branch: master commit 7cf75750e90f9bb5ad4c61c863330a5f395b80d2 Author: Oleh Krehel <ohwoeo...@gmail.com> Commit: Oleh Krehel <ohwoeo...@gmail.com>
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)))