[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#11378: 24.1.50; Suggestion: Let M-i in isearch cycle `search-invisib
From: |
Juri Linkov |
Subject: |
bug#11378: 24.1.50; Suggestion: Let M-i in isearch cycle `search-invisible' |
Date: |
Tue, 29 May 2012 19:40:19 +0300 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.1.50 (x86_64-pc-linux-gnu) |
> It would be more useful to allow multiple filters by transforming
> `isearch-filter-predicate' from the variable defining a predicate to the
> hook-like list defining a set of predicates all of which should satisfy
> for the search hit.
This is implemented by the following patch that also simplifies
the filter usage in other packages and adds two useful filters for
comments/strings:
=== modified file 'lisp/isearch.el'
--- lisp/isearch.el 2012-05-29 09:46:06 +0000
+++ lisp/isearch.el 2012-05-29 16:35:09 +0000
@@ -179,12 +179,13 @@
"Function to save a function restoring the mode-specific Isearch state
to the search status stack.")
-(defvar isearch-filter-predicate 'isearch-filter-visible
- "Predicate that filters the search hits that would normally be available.
-Search hits that dissatisfy the predicate are skipped. The function
-has two arguments: the positions of start and end of text matched by
-the search. If this function returns nil, continue searching without
-stopping at this match.")
+(defvar isearch-filter-predicate '(isearch-filter-visible)
+ "Predicates that filter the search hits that would normally be available.
+Search hits that dissatisfy the list of predicates are skipped.
+Each function in this list has two arguments: the positions of
+start and end of text matched by the search.
+If `run-hook-with-args-until-failure' returns nil for all predicates,
+continue searching without stopping at this match.")
;; Search ring.
@@ -506,6 +516,9 @@ (defvar isearch-mode-map
(define-key map "\M-sw" 'isearch-toggle-word)
(define-key map "\M-s_" 'isearch-toggle-symbol)
+ (define-key map "\M-sfs" 'isearch-toggle-filter-strings)
+ (define-key map "\M-sfc" 'isearch-toggle-filter-comments)
+
(define-key map [?\M-%] 'isearch-query-replace)
(define-key map [?\C-\M-%] 'isearch-query-replace-regexp)
(define-key map "\M-so" 'isearch-occur)
@@ -665,6 +681,10 @@ (defun isearch-forward (&optional regexp
Type \\[isearch-toggle-regexp] to toggle regular-expression mode.
Type \\[isearch-toggle-word] to toggle word mode.
Type \\[isearch-toggle-symbol] to toggle symbol mode.
+
+Type \\[isearch-toggle-filter-strings] to toggle searching inside strings.
+Type \\[isearch-toggle-filter-comments] to toggle searching inside comments.
+
Type \\[isearch-edit-string] to edit the search string in the minibuffer.
Also supported is a search ring of the previous 16 search strings.
@@ -1036,6 +1056,9 @@ (defsubst isearch-case-fold-search-state
(defsubst isearch-pop-fun-state (frame)
"Return the function restoring the mode-specific Isearch state in FRAME."
(aref frame 11))
+(defsubst isearch-filter-predicate-state (frame)
+ "Return the filter predicates in FRAME."
+ (aref frame 12))
(defun isearch-top-state ()
(let ((cmd (car isearch-cmds)))
@@ -1048,7 +1071,8 @@ (defun isearch-top-state ()
isearch-error (isearch-error-state cmd)
isearch-wrapped (isearch-wrapped-state cmd)
isearch-barrier (isearch-barrier-state cmd)
- isearch-case-fold-search (isearch-case-fold-search-state cmd))
+ isearch-case-fold-search (isearch-case-fold-search-state cmd)
+ isearch-filter-predicate (isearch-filter-predicate-state cmd))
(if (functionp (isearch-pop-fun-state cmd))
(funcall (isearch-pop-fun-state cmd) cmd))
(goto-char (isearch-point-state cmd))))
@@ -1065,7 +1089,8 @@ (defun isearch-push-state ()
isearch-error isearch-wrapped isearch-barrier
isearch-case-fold-search
(if isearch-push-state-function
- (funcall isearch-push-state-function)))
+ (funcall isearch-push-state-function))
+ isearch-filter-predicate)
isearch-cmds)))
@@ -1411,6 +1436,40 @@ (defun isearch-toggle-case-fold ()
(sit-for 1)
(isearch-update))
+(defun isearch-toggle-filter-strings ()
+ "Toggle searching inside strings on or off."
+ (interactive)
+ (setq isearch-filter-predicate
+ (if (memq 'isearch-filter-strings isearch-filter-predicate)
+ (delq 'isearch-filter-strings isearch-filter-predicate)
+ (cons 'isearch-filter-strings isearch-filter-predicate)))
+ (setq isearch-success t isearch-adjusted t)
+ (isearch-update))
+
+(defun isearch-filter-strings (beg end)
+ "Test whether the current search hit is inside strings.
+Return non-nil if the text from BEG to END is inside strings."
+ (nth 3 (parse-partial-sexp (point-min) (point))))
+
+(put 'isearch-filter-strings 'isearch-message-prefix "string ")
+
+(defun isearch-toggle-filter-comments ()
+ "Toggle searching inside comments on or off."
+ (interactive)
+ (setq isearch-filter-predicate
+ (if (memq 'isearch-filter-comments isearch-filter-predicate)
+ (delq 'isearch-filter-comments isearch-filter-predicate)
+ (cons 'isearch-filter-comments isearch-filter-predicate)))
+ (setq isearch-success t isearch-adjusted t)
+ (isearch-update))
+
+(defun isearch-filter-comments (beg end)
+ "Test whether the current search hit is inside comments.
+Return non-nil if the text from BEG to END is inside comments."
+ (nth 4 (parse-partial-sexp (point-min) (point))))
+
+(put 'isearch-filter-comments 'isearch-message-prefix "comment ")
+
;; Word search
@@ -2373,6 +2439,11 @@ (defun isearch-message-prefix (&optional
(< (point) isearch-opoint)))
"over")
(if isearch-wrapped "wrapped ")
+ (mapconcat (lambda (s)
+ (and (symbolp s)
+ (get s 'isearch-message-prefix)))
+ isearch-filter-predicate
+ "")
(if isearch-word
(or (and (symbolp isearch-word)
(get isearch-word 'isearch-message-prefix))
@@ -2489,13 +2560,11 @@ (defun isearch-search ()
(setq isearch-case-fold-search
(isearch-no-upper-case-p isearch-string isearch-regexp)))
(condition-case lossage
- (let ((inhibit-point-motion-hooks
- (and (eq isearch-filter-predicate 'isearch-filter-visible)
- search-invisible))
+ (let ((inhibit-point-motion-hooks search-invisible)
(inhibit-quit nil)
(case-fold-search isearch-case-fold-search)
(search-spaces-regexp search-whitespace-regexp)
@@ -2509,8 +2578,9 @@ (defun isearch-search ()
(if (or (not isearch-success)
(bobp) (eobp)
(= (match-beginning 0) (match-end 0))
- (funcall isearch-filter-predicate
- (match-beginning 0) (match-end 0)))
+ (run-hook-with-args-until-failure
+ 'isearch-filter-predicate
+ (match-beginning 0) (match-end 0)))
(setq retry nil)))
(setq isearch-just-started nil)
(if isearch-success
@@ -2895,8 +3005,9 @@ (defun isearch-lazy-highlight-search ()
(if (or (not success)
(= (point) bound) ; like (bobp) (eobp) in `isearch-search'.
(= (match-beginning 0) (match-end 0))
- (funcall isearch-filter-predicate
- (match-beginning 0) (match-end 0)))
+ (run-hook-with-args-until-failure
+ 'isearch-filter-predicate
+ (match-beginning 0) (match-end 0)))
(setq retry nil)))
success)
(error nil)))
=== modified file 'lisp/dired-aux.el'
--- lisp/dired-aux.el 2012-04-17 01:52:00 +0000
+++ lisp/dired-aux.el 2012-05-29 16:35:30 +0000
@@ -2424,8 +2425,6 @@ (defcustom dired-isearch-filenames nil
:group 'dired
:version "23.1")
-(defvar dired-isearch-filter-predicate-orig nil)
-
(defun dired-isearch-filenames-toggle ()
"Toggle file names searching on or off.
When on, Isearch skips matches outside file names using the predicate
@@ -2433,9 +2432,9 @@ (defun dired-isearch-filenames-toggle ()
When off, it uses the original predicate."
(interactive)
(setq isearch-filter-predicate
- (if (eq isearch-filter-predicate 'dired-isearch-filter-filenames)
- dired-isearch-filter-predicate-orig
- 'dired-isearch-filter-filenames))
+ (if (memq 'dired-isearch-filter-filenames isearch-filter-predicate)
+ (delq 'dired-isearch-filter-filenames isearch-filter-predicate)
+ (cons 'dired-isearch-filter-filenames isearch-filter-predicate)))
(setq isearch-success t isearch-adjusted t)
(isearch-update))
@@ -2446,29 +2445,29 @@ (defun dired-isearch-filenames-setup ()
(when (or (eq dired-isearch-filenames t)
(and (eq dired-isearch-filenames 'dwim)
(get-text-property (point) 'dired-filename)))
- (setq isearch-message-prefix-add "filename ")
- (define-key isearch-mode-map "\M-sf" 'dired-isearch-filenames-toggle)
- (setq dired-isearch-filter-predicate-orig
- (default-value 'isearch-filter-predicate))
- (setq-default isearch-filter-predicate 'dired-isearch-filter-filenames)
+ (define-key isearch-mode-map "\M-sff" 'dired-isearch-filenames-toggle)
+ (setq isearch-filter-predicate
+ (cons 'dired-isearch-filter-filenames isearch-filter-predicate))
(add-hook 'isearch-mode-end-hook 'dired-isearch-filenames-end nil t)))
(defun dired-isearch-filenames-end ()
"Clean up the Dired file name search after terminating isearch."
(setq isearch-message-prefix-add nil)
- (define-key isearch-mode-map "\M-sf" nil)
- (setq-default isearch-filter-predicate dired-isearch-filter-predicate-orig)
+ (define-key isearch-mode-map "\M-sff" nil)
+ (setq isearch-filter-predicate
+ (delq 'dired-isearch-filter-filenames isearch-filter-predicate))
(remove-hook 'isearch-mode-end-hook 'dired-isearch-filenames-end t))
(defun dired-isearch-filter-filenames (beg end)
- "Test whether the current search hit is a visible file name.
+ "Test whether the current search hit is a file name.
Return non-nil if the text from BEG to END is part of a file
-name (has the text property `dired-filename') and is visible."
- (and (isearch-filter-visible beg end)
- (if dired-isearch-filenames
- (text-property-not-all (min beg end) (max beg end)
- 'dired-filename nil)
- t)))
+name (has the text property `dired-filename')."
+ (if dired-isearch-filenames
+ (text-property-not-all (min beg end) (max beg end)
+ 'dired-filename nil)
+ t))
+
+(put 'dired-isearch-filter-filenames 'isearch-message-prefix "filename ")
;;;###autoload
(defun dired-isearch-filenames ()
=== modified file 'lisp/info.el'
--- lisp/info.el 2012-05-29 09:09:38 +0000
+++ lisp/info.el 2012-05-29 16:39:00 +0000
@@ -1772,7 +1775,8 @@ (defun Info-search (regexp &optional bou
(point-max)))
(while (and (not give-up)
(or (null found)
- (not (funcall isearch-filter-predicate beg-found
found))))
+ (not (run-hook-with-args-until-failure
+ 'isearch-filter-predicate beg-found found))))
(let ((search-spaces-regexp
(if (or (not isearch-mode) isearch-regexp)
Info-search-whitespace-regexp)))
@@ -1854,7 +1858,8 @@ (defun Info-search (regexp &optional bou
(setq give-up nil found nil)
(while (and (not give-up)
(or (null found)
- (not (funcall isearch-filter-predicate
beg-found found))))
+ (not (run-hook-with-args-until-failure
+ 'isearch-filter-predicate beg-found
found))))
(let ((search-spaces-regexp
(if (or (not isearch-mode) isearch-regexp)
Info-search-whitespace-regexp)))
@@ -4049,7 +4054,7 @@ (define-derived-mode Info-mode nil "Info
(set (make-local-variable 'isearch-push-state-function)
'Info-isearch-push-state)
(set (make-local-variable 'isearch-filter-predicate)
- 'Info-isearch-filter)
+ '(Info-isearch-filter))
(set (make-local-variable 'search-whitespace-regexp)
Info-search-whitespace-regexp)
(set (make-local-variable 'revert-buffer-function)
=== modified file 'lisp/wdired.el'
--- lisp/wdired.el 2012-01-19 07:21:25 +0000
+++ lisp/wdired.el 2012-05-29 16:35:52 +0000
@@ -216,8 +216,7 @@ (defun wdired-change-to-wdired-mode ()
(buffer-substring (point-min) (point-max)))
(set (make-local-variable 'wdired-old-point) (point))
(set (make-local-variable 'query-replace-skip-read-only) t)
- (set (make-local-variable 'isearch-filter-predicate)
- 'wdired-isearch-filter-read-only)
+ (add-hook 'isearch-filter-predicate 'wdired-isearch-filter-read-only nil t)
(use-local-map wdired-mode-map)
(force-mode-line-update)
(setq buffer-read-only nil)
@@ -245,9 +244,8 @@ (defun wdired-change-to-wdired-mode ()
(defun wdired-isearch-filter-read-only (beg end)
"Skip matches that have a read-only property."
- (and (isearch-filter-visible beg end)
- (not (text-property-not-all (min beg end) (max beg end)
- 'read-only nil))))
+ (not (text-property-not-all (min beg end) (max beg end)
+ 'read-only nil)))
;; Protect the buffer so only the filenames can be changed, and put
;; properties so filenames (old and new) can be easily found.