about summary refs log tree commit diff
path: root/tools
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2019-12-15T17·09+0000
committerVincent Ambo <tazjin@google.com>2019-12-15T17·13+0000
commit00c9060c2f0ec581db8841aa34fd92c0e9953693 (patch)
tree17bb2998297f9f6c359abe16a610fc30fc2bd1bd /tools
parent895deabb3aee036dbe3a96fa5caea46bfeef2012 (diff)
feat(emacs.d): Introduce custom mc/mark-dwim cursor marker r/155
Adds a "do what I mean" multiple-cursor selection with the logic that
I find most useful:

* If there is no active region, mark the next line (or lines, based on
  prefix argument)
* If there is an active region that spans multiple lines, call
  `mc/edit-lines`
* If there is an active region on a single line, trigger a custom
  selection hydra with functionality equivalent to
  `mc/mark-more-like-this-extended` but a slightly improved user
  experience

Hopefully this will make it easier to get into the habit of actually
using multiple-cursors without calling the mc commands via M-x
Diffstat (limited to 'tools')
-rw-r--r--tools/emacs/config/bindings.el1
-rw-r--r--tools/emacs/config/functions.el27
2 files changed, 28 insertions, 0 deletions
diff --git a/tools/emacs/config/bindings.el b/tools/emacs/config/bindings.el
index 626bdcea8e..502750aa9d 100644
--- a/tools/emacs/config/bindings.el
+++ b/tools/emacs/config/bindings.el
@@ -24,6 +24,7 @@
 ;; Miscellaneous editing commands
 (global-set-key (kbd "C-c w") 'whitespace-cleanup)
 (global-set-key (kbd "C-c a") 'align-regexp)
+(global-set-key (kbd "C-c m") 'mc/mark-dwim)
 
 ;; Browse URLs (very useful for Gitlab's SSH output!)
 (global-set-key (kbd "C-c b p") 'browse-url-at-point)
diff --git a/tools/emacs/config/functions.el b/tools/emacs/config/functions.el
index a6cc07e889..e50950a8ef 100644
--- a/tools/emacs/config/functions.el
+++ b/tools/emacs/config/functions.el
@@ -182,6 +182,33 @@ Including indent-buffer, which should not be called automatically on save."
   (inferior-erlang
    (format "nix-shell --command erl %s" (cdr (project-current)))))
 
+(defhydra mc/mark-more-hydra (:color pink)
+  ("<up>" mmlte--up "Mark previous like this")
+  ("<down>" mc/mmlte--down "Mark next like this")
+  ("<left>" mc/mmlte--left (if (eq mc/mark-more-like-this-extended-direction 'up)
+                               "Skip past the cursor furthest up"
+                             "Remove the cursor furthest down"))
+  ("<right>" mc/mmlte--right (if (eq mc/mark-more-like-this-extended-direction 'up)
+                                 "Remove the cursor furthest up"
+                               "Skip past the cursor furthest down"))
+  ("f" nil "Finish selecting"))
+
+;; Mute the message that mc/mmlte wants to print on its own
+(advice-add 'mc/mmlte--message :around (lambda (&rest args) (ignore)))
+
+(defun mc/mark-dwim (arg)
+  "Select multiple things, but do what I mean."
+
+  (interactive "p")
+  (if (not (region-active-p)) (mc/mark-next-lines arg)
+    (if (< 1 (count-lines (region-beginning)
+                          (region-end)))
+        (mc/edit-lines arg)
+      ;; The following is almost identical to `mc/mark-more-like-this-extended',
+      ;; but uses a hydra (`mc/mark-more-hydra') instead of a transient key map.
+      (mc/mmlte--down)
+      (mc/mark-more-hydra/body))))
+
 (defun memespace-region ()
   "Make a meme out of it."