summary refs log tree commit diff stats
path: root/lisp/+avy.el
blob: b0837a335394416cfafc28d88d65459267a84167 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
;;; +avy.el -*- lexical-binding: t -*-

;;; Commentary:

;; https://karthinks.com/software/avy-can-do-anything/

;;; Code:

(require 'avy)

(defun avy-action-embark (pt)
  (unwind-protect
      (save-excursion
        (goto-char pt)
        (embark-act))
    (select-window
     (cdr (ring-ref avy-ring 0))))
  t)


;;; Remove `buffer-face-mode' when avy is active.

(defcustom +avy-buffer-face-functions '(avy-goto-char
                                        avy-goto-char-in-line
                                        avy-goto-char-2
                                        avy-goto-char-2-above
                                        avy-goto-char-2-below
                                        avy-goto-word-0
                                        avy-goto-whitespace-end
                                        avy-goto-word-0-above
                                        avy-goto-word-0-below
                                        avy-goto-whitespace-end-above
                                        avy-goto-whitespace-end-below
                                        avy-goto-word-1
                                        avy-goto-word-1-above
                                        avy-goto-word-1-below
                                        avy-goto-symbol-1
                                        avy-goto-symbol-1-above
                                        avy-goto-symbol-1-below
                                        avy-goto-subword-0
                                        avy-goto-subword-1
                                        avy-goto-word-or-subword-1
                                        avy-goto-line
                                        avy-goto-line-above
                                        avy-goto-line-below
                                        avy-goto-end-of-line
                                        avy-goto-char-timer)
  "Functions to disable `buffer-face-mode' during.")

(defvar-local +avy-buffer-face-mode-face nil
  "The state of `buffer-face-mode' before calling `avy-with'.")

;;; XXX: Doesn't switch back if avy errors out or quits
(defun +avy@un-buffer-face (win)
  "BEFORE advice on `avy-with' to disable `buffer-face-mode'."
  (with-current-buffer (window-buffer win)
    (when buffer-face-mode
      (setq +avy-buffer-face-mode-face buffer-face-mode-face)
      (buffer-face-mode -1))))

(defun +avy@re-buffer-face (win)
  "AFTER advice on `avy-with' to re-enable `buffer-face-mode'."
  (with-current-buffer (window-buffer win)
    (when +avy-buffer-face-mode-face
      (setq buffer-face-mode-face +avy-buffer-face-mode-face)
      (buffer-face-mode +1)))
  (let ((bounds (bounds-of-thing-at-point 'symbol)))
    (when (and (car bounds)
               (cdr bounds))
      (pulse-momentary-highlight-region (car bounds) (cdr bounds)))))

(defun +avy@buffer-face (fn &rest r)
  "AROUND advice for avy to dis/enable `buffer-face-mode'."
  (if avy-all-windows
      (walk-windows #'+avy@un-buffer-face nil (eq avy-all-windows 'all-frames)))
  (condition-case e
      (apply fn r)
    ((quit error) (message "Avy: %S" e) nil)
    (:sucess e))
  (if avy-all-windows
      (walk-windows #'+avy@re-buffer-face nil (eq avy-all-windows 'all-frames))))

(define-minor-mode +avy-buffer-face-mode
  "Turn off `buffer-face-mode' before doing Avy selections.
Restore the mode after the selection."
  :lighter ""
  :global t
  (setq +avy-buffer-face-mode-face nil)
  (cond
   (+avy-buffer-face-mode
    (dolist (fn +avy-buffer-face-functions)
      (advice-add fn :around #'+avy@buffer-face)))
   (t (dolist (fn +avy-buffer-face-functions)
        (advice-remove fn #'+avy@buffer-face)))))

(provide '+avy)
;;; avy.el ends here