thought_garden/AVY.org
2025-02-10 23:49:12 +05:30

4 KiB

AVY

AVY is a powerful Emacs library that allows you to jump to any visible character in a buffer with efficient tree searches.

The core idea that makes Avy a powerful tool is the filter - select - act paradigm.

Usage :

  1. call avy-goto-char-time - I have bound it to SPC a a
  2. filter by typing the characters of stings you want to go to
  3. A decision tree appears at all matching points in the frame
  4. Now before typing the decision select the action default (do nothing) - will go to position ? - display all possible actions, runs avy-show-dispatch-help
  5. act by entering your decision
(use-package avy
    :config
    (setq avy-timeout-seconds 0.3)

    (setq avy-keys '(?q ?e ?r ?y ?u ?o ?p
			?a ?s ?d ?f ?g ?h ?j
			?k ?l ?' ?x ?c ?v ?b
			?n ?, ?/))

    ;; overrides the function in avy.el, type ? before the decesion phase to call
    (defun avy-show-dispatch-help ()  
      (let* ((len (length "avy-action-"))
             (fw (frame-width))
             (raw-strings (mapcar
			   (lambda (x)
			     (format "%2s: %-19s"
                             (propertize
                              (char-to-string (car x))
                              'face 'aw-key-face)
                             (substring (symbol-name (cdr x)) len)))
			   avy-dispatch-alist))
             (max-len (1+ (apply #'max (mapcar #'length raw-strings))))
             (strings-len (length raw-strings))
             (per-row (floor fw max-len))
             display-strings)
	(cl-loop for string in raw-strings
		 for N from 1 to strings-len do
		 (push (concat string " ") display-strings)
		 (when (= (mod N per-row) 0) (push "\n" display-strings)))
	(message "%s" (apply #'concat (nreverse display-strings)))))
    

;; Kill text ----------------------------------------------------
(defun avy-action-kill-whole-line (pt)
  (save-excursion
    (goto-char pt)
    (kill-whole-line))
  (select-window
   (cdr
    (ring-ref avy-ring 0)))
  t)

(setf (alist-get ?k avy-dispatch-alist) 'avy-action-kill-stay
      (alist-get ?K avy-dispatch-alist) 'avy-action-kill-whole-line)


;; Copy text -----------------------------------------------------
(defun avy-action-copy-whole-line (pt)
  (save-excursion
    (goto-char pt)
    (cl-destructuring-bind (start . end)
        (bounds-of-thing-at-point 'line)
      (copy-region-as-kill start end)))
  (select-window
   (cdr
    (ring-ref avy-ring 0)))
  t)

(setf (alist-get ?w avy-dispatch-alist) 'avy-action-copy
      (alist-get ?W avy-dispatch-alist) 'avy-action-copy-whole-line)


;; Yank text -----------------------------------------------------
(defun avy-action-yank-whole-line (pt)
  (avy-action-copy-whole-line pt)
  (save-excursion (yank))
  t)

(setf (alist-get ?y avy-dispatch-alist) 'avy-action-yank
      (alist-get ?Y avy-dispatch-alist) 'avy-action-yank-whole-line)

;; Transpose/Move text --------------------------------------------
(defun avy-action-teleport-whole-line (pt)
  (avy-action-kill-whole-line pt)
  (save-excursion (yank)) t)

(setf (alist-get ?t avy-dispatch-alist) 'avy-action-teleport
      (alist-get ?T avy-dispatch-alist) 'avy-action-teleport-whole-line)

;; Mark text ------------------------------------------------------
(defun avy-action-mark-to-char (pt)
  (activate-mark)
  (goto-char pt))

(setf (alist-get ?  avy-dispatch-alist) 'avy-action-mark-to-char)


;; Flyspell words --------------------------------------------------
(defun avy-action-flyspell (pt)
  (save-excursion
    (goto-char pt)
    (when (require 'flyspell nil t)
      (flyspell-auto-correct-word)))
  (select-window
   (cdr (ring-ref avy-ring 0)))
  t)

;; Bind to semicolon (flyspell uses C-;)
(setf (alist-get ?\; avy-dispatch-alist) 'avy-action-flyspell)

)