branch: master
commit 7cf75750e90f9bb5ad4c61c863330a5f395b80d2
Author: Oleh Krehel <[email protected]>
Commit: Oleh Krehel <[email protected]>
swiper.el (swiper-toggle-face-matching): Add and bind to "C-c C-f"
* swiper.el (swiper-map): Bind `swiper-toggle-face-matching' to
"C-c C-f".
(swiper-invocation-face): New defvar.
(swiper--ivy): Set `swiper-invocation-face'.
(swiper-toggle-face-matching): Toggle `ivy-state-matcher' between
nil (the initial value) and 'swiper--face-matcher.
(swiper--face-matcher): New defun. In addition to filtering CANDIDATES
by having them match REGEXP, also ensure that every match has
`swiper-invocation-face'.
Example of usage:
1. Move point to a variable with e.g. `font-lock-keyword-face' and "C-s"
<input>.
2. Use "C-c C-f" to filter the candidates further by selecting only the
ones that have `font-lock-keyword-face'.
Note that "M-q" (`swiper-query-replace') is also affected by the filtering.
3. Use "C-c C-f" to toggle the filtering off.
Fixes #288
---
swiper.el | 33 +++++++++++++++++++++++++++++++++
1 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/swiper.el b/swiper.el
index d1bf5de..2fe3ef7 100644
--- a/swiper.el
+++ b/swiper.el
@@ -93,6 +93,7 @@
(define-key map (kbd "C-l") 'swiper-recenter-top-bottom)
(define-key map (kbd "C-'") 'swiper-avy)
(define-key map (kbd "C-7") 'swiper-mc)
+ (define-key map (kbd "C-c C-f") 'swiper-toggle-face-matching)
map)
"Keymap for swiper.")
@@ -319,11 +320,16 @@ there have line numbers. In the buffer, `ivy--regex'
should be used."
(defvar swiper-history nil
"History for `swiper'.")
+(defvar swiper-invocation-face nil
+ "The face at the point of invocation of `swiper'.")
+
(defun swiper--ivy (&optional initial-input)
"`isearch' with an overview using `ivy'.
When non-nil, INITIAL-INPUT is the initial search pattern."
(interactive)
(swiper--init)
+ (setq swiper-invocation-face
+ (plist-get (text-properties-at (point)) 'face))
(let ((candidates (swiper--candidates))
(preselect (buffer-substring-no-properties
(line-beginning-position)
@@ -346,6 +352,33 @@ When non-nil, INITIAL-INPUT is the initial search pattern."
(when (null ivy-exit)
(goto-char swiper--opoint)))))
+(defun swiper-toggle-face-matching ()
+ "Toggle matching only the candidates with `swiper-invocation-face'."
+ (interactive)
+ (setf (ivy-state-matcher ivy-last)
+ (if (ivy-state-matcher ivy-last)
+ nil
+ #'swiper--face-matcher))
+ (setq ivy--old-re nil))
+
+(defun swiper--face-matcher (regexp candidates)
+ "Return REGEXP-matching CANDIDATES.
+Matched candidates should have `swiper-invocation-face'."
+ (cl-remove-if-not
+ (lambda (x)
+ (and
+ (string-match regexp x)
+ (let ((s (match-string 0 x))
+ (i 0))
+ (while (and (< i (length s))
+ (text-property-any
+ i (1+ i)
+ 'face swiper-invocation-face
+ s))
+ (cl-incf i))
+ (eq i (length s)))))
+ candidates))
+
(defun swiper--ensure-visible ()
"Remove overlays hiding point."
(let ((overlays (overlays-at (point)))