bug-gnu-emacs
[Top][All Lists]
Advanced

[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.






reply via email to

[Prev in Thread] Current Thread [Next in Thread]