about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.emacs.d/lisp/init-navigation.el74
1 files changed, 59 insertions, 15 deletions
diff --git a/.emacs.d/lisp/init-navigation.el b/.emacs.d/lisp/init-navigation.el
index 082a64d..bfee93c 100644
--- a/.emacs.d/lisp/init-navigation.el
+++ b/.emacs.d/lisp/init-navigation.el
@@ -2,6 +2,65 @@
 ;;; Commentary:
 ;;; Code:
 
+(defvar-local goto-char--last-char nil)
+(use-package emacs
+  :config
+  (defun goto-char-forward (arg char)
+    "Move forward to char in line.
+If a C-u prefix argument is given, it is not restricted to the current line.
+If a numeric prefix argument N is given, move forward N instances of char."
+    (interactive "P\ncGo to char: ")
+    (setq goto-char--last-char char)
+    (goto-char--move-forward arg))
+
+  (defun goto-char-forward-repeat-last (arg)
+    "Move forward in line to char last used in a goto-char command.
+If a C-u prefix argument is given, it is not restricted to the current line.
+If a numeric prefix argument N is given, move forward N instances of the last used char."
+    (interactive "P")
+    (goto-char--move-forward arg))
+
+  (defun goto-char-backward (arg char)
+    "Move forward to char in line.
+If a C-u prefix argument is given, it is not restricted to the current line.
+If a numeric prefix argument N is given, move back N instances of char."
+    (interactive "P\ncGo to char (backward):")
+    (setq goto-char--last-char char)
+    (goto-char--move-backward arg))
+
+  (defun goto-char-backward-repeat-last (arg)
+    "Move backward in line to char last qused in a goto-char command.
+If a C-u prefix argument is given, it is not restricted to the current line.
+If a numeric prefix argument N is given, move back N instances of the last used char."
+    (interactive "P")
+    (goto-char--move-backward arg))
+
+  (defun goto-char--move-forward (arg)
+    (when goto-char--last-char
+      (let ((count (if (consp arg)
+                       2 ;; C-u -> 2 (i.e. first match on any line)
+                       (if (equal (char-after) goto-char--last-char)
+                           (1+ (or arg 1)) ;; skip over the char after the cursor, if needed
+                         arg)))
+            (end-position (unless (consp arg)
+                            (line-end-position))))
+        (when (search-forward (string goto-char--last-char) end-position t count)
+          (backward-char)))))
+
+  (defun goto-char--move-backward (arg)
+    (when goto-char--last-char
+      (let ((count (unless (consp arg)
+                     arg))
+            (start-position (unless (consp arg)
+                              (line-beginning-position))))
+        (search-backward (string goto-char--last-char) start-position t count))))
+
+  :bind
+  ("C-'" . goto-char-forward)
+  ("C-;" . goto-char-backward)
+  ("C-@" . goto-char-forward-repeat-last)
+  ("C-:" . goto-char-backward-repeat-last))
+
 (use-package smartscan
   :config
   (global-smartscan-mode t)
@@ -40,21 +99,6 @@
   ("C-c Z" . my/affe-find-symbol-at-point)
   ("C-~" . my/affe-grep-symbol-at-point))
 
-;; TODO - which of these are useful?
-(use-package avy
-  :custom
-  (avy-background t)
-  (avy-style 'pre)
-  :bind
-  ("C-:" . avy-goto-char)
-  ("C-'" . avy-goto-char-2)
-  ("C-;" . avy-goto-char-in-line)
-  ("C-c C-v" . avy-goto-char-in-line)
-  ("C-c v" . avy-goto-word-or-subword-1)
-  ("M-g w" . avy-goto-word-1)
-  ("M-g M-w" . avy-goto-word-0)
-  ("M-g M-f" . avy-goto-line))
-
 (use-package rg
   :bind
   ("C-c C-M-r" . rg-menu)