Abstract windows and rely on subword

* avy-jump.el (avy-dowindows): New macro.
(avy--regex-candidates): Use `avy-dowindows'.
(avy-goto-subword-0): Rely on `subword-backward'.
(avy--line): Use `avy-dowindows'.

Fixes #4
This commit is contained in:
Oleh Krehel 2015-05-07 13:28:27 +02:00
parent e4f493ef83
commit 487d5ea201

View File

@ -59,6 +59,23 @@
"Face for whole window background during selection.") "Face for whole window background during selection.")
;;* Internals ;;* Internals
(defcustom avy-all-windows t
"When non-nil, loop though all windows for candidates."
:type 'boolean)
(defmacro avy-dowindows (flip &rest body)
"Depending on FLIP and `avy-all-windows' run BODY in each or selected window."
(declare (indent 1))
`(let ((avy-all-windows (if ,flip
(not avy-all-windows)
avy-all-windows)))
(dolist (wnd (if avy-all-windows
(window-list)
(list (selected-window))))
(with-selected-window wnd
(unless (memq major-mode '(image-mode doc-view-mode))
,@body)))))
(defun avy--goto (x) (defun avy--goto (x)
"Goto X. "Goto X.
X is (POS . WND) X is (POS . WND)
@ -109,20 +126,12 @@ POS is either a position or (BEG . END)."
(setq avy--overlays-back nil) (setq avy--overlays-back nil)
(avy--remove-leading-chars)) (avy--remove-leading-chars))
(defcustom avy-all-windows t
"When non-nil, loop though all windows for candidates."
:type 'boolean)
(defun avy--regex-candidates (regex &optional wnd beg end pred) (defun avy--regex-candidates (regex &optional wnd beg end pred)
"Return all elements that match REGEX in WND. "Return all elements that match REGEX in WND.
Each element of the list is ((BEG . END) . WND) Each element of the list is ((BEG . END) . WND)
When PRED is non-nil, it's a filter for matching point positions." When PRED is non-nil, it's a filter for matching point positions."
(let (candidates) (let (candidates)
(dolist (wnd (if avy-all-windows (avy-dowindows nil
(window-list)
(list (selected-window))))
(with-selected-window wnd
(unless (memq major-mode '(image-mode doc-view-mode))
(let ((we (or end (window-end (selected-window) t)))) (let ((we (or end (window-end (selected-window) t))))
(save-excursion (save-excursion
(goto-char (or beg (window-start))) (goto-char (or beg (window-start)))
@ -132,7 +141,7 @@ When PRED is non-nil, it's a filter for matching point positions."
(funcall pred)) (funcall pred))
(push (cons (cons (match-beginning 0) (push (cons (cons (match-beginning 0)
(match-end 0)) (match-end 0))
wnd) candidates))))))))) wnd) candidates)))))))
(nreverse candidates))) (nreverse candidates)))
(defvar avy--overlay-offset 0 (defvar avy--overlay-offset 0
@ -308,38 +317,33 @@ The window scope is determined by `avy-all-windows' (ARG negates it)."
str)))) str))))
(avy--generic-jump regex arg avy-goto-word-style))) (avy--generic-jump regex arg avy-goto-word-style)))
(declare-function subword-backward "subword")
;;;###autoload ;;;###autoload
(defun avy-goto-subword-0 (&optional arg) (defun avy-goto-subword-0 (&optional arg)
"Jump to a word or subword start. "Jump to a word or subword start.
The window scope is determined by `avy-all-windows' (ARG negates it)." The window scope is determined by `avy-all-windows' (ARG negates it)."
(interactive "P") (interactive "P")
(let* ((avy-all-windows (require 'subword)
(if arg (let ((avy-keys (number-sequence ?a ?z))
(not avy-all-windows)
avy-all-windows))
(avy-keys (number-sequence ?a ?z))
(case-fold-search nil) (case-fold-search nil)
(candidates (avy--regex-candidates candidates)
"\\(\\b\\sw\\)\\|\\(?:[^A-Z]\\([A-Z]\\)\\)"))) (avy-dowindows arg
(dolist (x candidates) (let ((ws (window-start)))
(when (> (- (cdar x) (caar x)) 1) (save-excursion
(cl-incf (caar x)))) (goto-char (window-end (selected-window) t))
(subword-backward)
(while (> (point) ws)
(push (cons (point) (selected-window)) candidates)
(subword-backward)))))
(avy--goto (avy--goto
(avy--process candidates (avy--style-fn avy-goto-word-style))))) (avy--process candidates (avy--style-fn avy-goto-word-style)))))
(defun avy--line (&optional arg) (defun avy--line (&optional arg)
"Select line in current window." "Select line in current window."
(let ((avy-background nil) (let ((avy-background nil)
(avy-all-windows
(if arg
(not avy-all-windows)
avy-all-windows))
candidates) candidates)
(dolist (wnd (if avy-all-windows (avy-dowindows arg
(window-list)
(list (selected-window))))
(with-selected-window wnd
(unless (memq major-mode '(image-mode doc-view-mode))
(let ((ws (window-start))) (let ((ws (window-start)))
(save-excursion (save-excursion
(save-restriction (save-restriction
@ -348,9 +352,8 @@ The window scope is determined by `avy-all-windows' (ARG negates it)."
(while (< (point) (point-max)) (while (< (point) (point-max))
(unless (get-char-property (unless (get-char-property
(max (1- (point)) ws) 'invisible) (max (1- (point)) ws) 'invisible)
(push (cons (point) (selected-window)) (push (cons (point) (selected-window)) candidates))
candidates)) (forward-line 1))))))
(forward-line 1))))))))
(avy--process (nreverse candidates) #'avy--overlay-pre))) (avy--process (nreverse candidates) #'avy--overlay-pre)))
;;;###autoload ;;;###autoload