chiark / gitweb /
Support for Magnar Sveen's awesome `multiple-cursors' package.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 13 Jul 2013 15:34:40 +0000 (16:34 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 15 Mar 2014 14:34:13 +0000 (14:34 +0000)
To use it:

git clone https://github.com/magnars/multiple-cursors.el/ \
~/lib/emacs/multiple-cursors/

dot/emacs
el/dot-emacs.el
el/mdw-multiple-cursors.el [new file with mode: 0644]
setup

index 83a8bd0d833233258289358517375fcb785f6eae..4705e7edf78360a9b2a74b5a3b6d1638f99c056f 100644 (file)
--- a/dot/emacs
+++ b/dot/emacs
 (trap (show-paren-mode t))
 (or window-system (menu-bar-mode -1))
 
+;; Multiple cursors.
+
+(setq load-path (nconc load-path (list "~/lib/emacs/multiple-cursors/")))
+(global-set-key [?\C-c ?r] 'mdw-multiple-cursors-keymap)
+(autoload 'mdw-multiple-cursors-keymap "mdw-multiple-cursors.el"
+  "A keymap for Magnar Sveen's awesome multiple-cursors." nil 'keymap)
+
 ;; Temporary directory handling.
 
 (defun mdw-check-dir-exists (dir)
index e8751ff0d2cdee6c0729777090878d2c4f4cb772..f21af7f06790f2007f59d5b2ecde7adc11f66b91 100644 (file)
@@ -865,6 +865,9 @@ (mdw-define-face region
   (((type tty) (class color)) :background "blue")
   (((type tty) (class mono)) :inverse-video t)
   (t :background "grey30"))
+(mdw-define-face mc/cursor-face
+  (((type tty) (class mono)) :inverse-video t)
+  (t :background "red"))
 (mdw-define-face minibuffer-prompt
   (t :weight bold))
 (mdw-define-face mode-line
diff --git a/el/mdw-multiple-cursors.el b/el/mdw-multiple-cursors.el
new file mode 100644 (file)
index 0000000..8107d48
--- /dev/null
@@ -0,0 +1,156 @@
+;;; -*-emacs-lisp-*-
+;;;
+;;; Key bindings for Magnar Sveen's `multiple-cursors' package
+;;;
+;;; (c) 2014 Mark Wooding
+;;;
+
+;;;----- Licensing notice ---------------------------------------------------
+;;;
+;;; This program is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; This program is distributed in the hope that it will be useful,
+;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software Foundation,
+;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+;; Loading and setup:
+;;
+;; (global-set-key [...] 'mdw-multiple-values-keymap)
+;; (autoload 'mdw-multiple-cursors-keymap "mdw-multiple-cursors.el"
+;;   "A keymap for Magnar Sveen's awesome multiple-cursors." nil 'keymap)
+
+;;;--------------------------------------------------------------------------
+;;; Some machinery for omitting key prefixes.
+
+(defvar mdw-omit-prefix-enable-repeat t
+  "*If true, allow invoking sequences of commands without repeating prefixes.
+This is both a user twiddle (which you can turn on and off depending on
+whether you like the feature) and a state variable used by the
+implementation.")
+
+(defun mdw-omit-prefix-repeat (keys tag)
+  "Maybe invoke other commands with the same prefix.
+The KEYS which invoked the current command, usually as collected via
+`this-single-command-keys'.  If the next keystroke refers to a command
+whose name has a `mdw-omit-prefix-repeat' property with value TAG then run
+that command and repeat.
+
+Call this at the end of your command function if you want to allow prefix
+omission.  Honours the `mdw-omit-prefix-enable-repeat' variable."
+  (when mdw-omit-prefix-enable-repeat
+    (let ((n (1- (length keys))) cmd done
+         (mdw-omit-prefix-enable-repeat nil))
+      (while (not done)
+       (setq done t)
+       (aset keys n (read-event))
+       (let* ((cmd (key-binding keys t))
+              (cmdtag (get cmd 'mdw-omit-prefix-repeat)))
+         (clear-this-command-keys t)
+         (when (eq cmdtag tag)
+           (setq done nil)
+           (call-interactively cmd))))
+      (when last-input-event
+       (setq unread-command-events (list last-input-event))))))
+
+(defmacro mdw-omit-prefix-wrapper (name func args tag &rest things)
+  "Generate a prefix-omission wrapper function around a command.
+The wrapper will be called NAME; it will invoke FUNC, passing it ARGS;
+commands in the same keymap whose `mdw-omit-prefix-enable-repeat'
+property has the value TAG can be invoked without repeating the
+prefix.  The THINGS are items (such as documentation or `interactive'
+forms) to appear at the start of the wrapper function."
+  `(progn
+     (defun ,name ,args
+       ,@things
+       (let ((keys (this-single-command-keys)))
+        (,func ,@args)
+        (mdw-omit-prefix-repeat keys ',tag)))
+     (put ',name 'mdw-omit-prefix-repeat ',tag)
+     ',name))
+
+;;;--------------------------------------------------------------------------
+;;; The multiple-cursors key bindings.
+
+(eval-when (load eval)
+  (require 'multiple-cursors))
+
+(defvar mdw-multiple-cursors-keymap (make-sparse-keymap)
+  "Keymap for `multiple-cursors'.")
+(fset 'mdw-multiple-cursors-keymap mdw-multiple-cursors-keymap)
+
+(defmacro mdw-make-multiple-cursors-repeat-wrappers (&rest specs)
+  "Set up wrappers around the `multiple-cursors' functions.
+Each of the SPECS has the form
+
+       (FUNC ARGS INTERACT BIND)
+
+where:
+
+  * FUNC is the existing function which is to be wrapped;
+
+  * ARGS are the arguments to be collected by the wrapper function,
+    and passed to FUNC;
+
+  * INTERACT is an `interactive' string, or `nil' (if there are no
+    interactive arguments to be collected); and
+
+  * BIND is the key binding to set in `mdw-multiple-cursors-keymap'."
+
+  `(progn
+     ,@(apply #'append
+             (mapcar (lambda (spec)
+                       (let* ((func (car spec))
+                              (args (cadr spec))
+                              (interact (car (cddr spec)))
+                              (bind (cadr (cddr spec)))
+                              (wrapper (intern
+                                        (concat "mdw-"
+                                                (symbol-name func)))))
+                         `((mdw-omit-prefix-wrapper
+                            ,wrapper ,func ,args
+                            multiple-cursors
+                            (interactive ,@(and interact
+                                                (list interact))))
+                           (define-key mdw-multiple-cursors-keymap
+                                       ,bind ',wrapper)
+                           (pushnew ',wrapper mc/cmds-to-run-once))))
+                     specs))
+     '(,@(mapcar #'car specs))))
+
+;; Set up commands which want omit-prefix wrappers.
+(mdw-make-multiple-cursors-repeat-wrappers
+  (mc/mark-next-like-this (arg) "p" "\C-s")
+  (mc/mark-previous-like-this (arg) "p" "\C-r")
+  (mc/mark-next-word-like-this (arg) "p" "\M-f")
+  (mc/mark-previous-word-like-this (arg) "p" "\M-b")
+  (mc/mark-next-symbol-like-this (arg) "p" "\C-\M-f")
+  (mc/mark-previous-symbol-like-this (arg) "p" "\C-\M-b")
+  (mc/skip-to-next-like-this () nil "\M-s")
+  (mc/skip-to-previous-like-this () nil "\M-r")
+  (mc/unmark-next-like-this () nil "\C-\M-s")
+  (mc/unmark-previous-like-this () nil "\C-\M-r")
+  (mc/cycle-forward () nil "\M-n")
+  (mc/cycle-backward () nil "\M-p")
+  (mc/mark-all-like-this-dwim (arg) "p" "a"))
+
+;; Set up other commands.
+(let ((map mdw-multiple-cursors-keymap))
+  (define-key map "/" 'mc/mark-sgml-tag-pair)
+  (define-key map "\M-a" 'mc/mark-all-dwim)
+  (define-key map "e" 'mc/edit-lines)
+  (define-key map "\C-e" 'mc/edit-ends-of-lines)
+  (define-key map "\C-a" 'mc/edit-beginnings-of-lines)
+  (define-key map "\C-@" 'set-rectangular-region-anchor)
+  (define-key map [?\C- ] 'set-rectangular-region-anchor))
+
+;;;----- That's all, folks --------------------------------------------------
+
+(provide 'mdw-multiple-cursors)
diff --git a/setup b/setup
index c15f062981677132d7333ccc39de478a34f30df5..542297623a192e3eceeaac37c137928afab7e3ab 100755 (executable)
--- a/setup
+++ b/setup
@@ -297,6 +297,7 @@ emacspkg="
   ew-hols
   mdw-gnus-patch
   git git-blame vc-git stgit
+  mdw-multiple-cursors
   quilt"
 for elib in $emacspkg; do
   $echon "  $elib:$echoc"