GNU bug report logs - #11381
23.3; isearch-search-and-update issue?

Previous Next

Package: emacs;

Reported by: Andy Grover <andy <at> groveronline.com>

Date: Sun, 29 Apr 2012 23:00:02 UTC

Severity: wishlist

Found in version 23.3

Done: Chong Yidong <cyd <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 11381 <at> debbugs.gnu.org
Subject: bug#11381: 23.3; isearch-search-and-update issue?
Date: Mon, 28 May 2012 11:55:20 +0300
> Do we really need those 4?  I think we can just get away with
> symbol-search-regexp (whose name also needs to start with "isearch-").

In the next patch these functions are removed and symbol-search-regexp
is renamed to isearch-symbol-regexp.

>> Also it splits the standard default part of `isearch-search-fun'
>
> You could actually set isearch-search-fun-function's default to
> isearch-search-fun-default so we can just unconditionally call
> isearch-search-fun-function's.

It still needs protection against such cases as currently existing in
several places in internal and probably also in external packages:

    (let ((isearch-search-fun-function nil))
      (isearch-search-fun))

So it requires a call like:

    (funcall (or isearch-search-fun-function 'isearch-search-fun-default))

> and then
>
>         (lambda (string &optional bound noerror count)
>           (funcall
>            (if isearch-forward #'re-search-forward #'re-search-backward)
>            (if (functionp isearch-word)
>                (funcall isearch-word string nil)
>              (word-search-regexp string nil))
>            bound noerror count))

This is used in a complete patch that implements the symbol search
and fixes the word search (everything is in one patch below
but it will be installed in separate commits):

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2012-05-17 00:03:49 +0000
+++ lisp/isearch.el	2012-05-28 08:38:31 +0000
@@ -503,6 +512,7 @@ (defvar isearch-mode-map
 
     (define-key map "\M-sr" 'isearch-toggle-regexp)
     (define-key map "\M-sw" 'isearch-toggle-word)
+    (define-key map "\M-s_" 'isearch-toggle-symbol)
 
     (define-key map [?\M-%] 'isearch-query-replace)
     (define-key map [?\C-\M-%] 'isearch-query-replace-regexp)
@@ -614,6 +627,7 @@ (define-key esc-map "\C-s" 'isearch-forw
 (define-key global-map "\C-r" 'isearch-backward)
 (define-key esc-map "\C-r" 'isearch-backward-regexp)
 (define-key search-map "w" 'isearch-forward-word)
+(define-key search-map "_" 'isearch-forward-symbol)
 
 ;; Entry points to isearch-mode.
 
@@ -653,6 +667,7 @@ (defun isearch-forward (&optional regexp
 Type \\[isearch-toggle-case-fold] to toggle search case-sensitivity.
 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-edit-string] to edit the search string in the minibuffer.
 
 Also supported is a search ring of the previous 16 search strings.
@@ -720,6 +735,16 @@ (defun isearch-forward-word (&optional n
   (interactive "P\np")
   (isearch-mode t nil nil (not no-recursive-edit) (null not-word)))
 
+(defun isearch-forward-symbol (&optional not-symbol no-recursive-edit)
+  "\
+Do incremental search forward for a symbol.
+The prefix argument is currently unused.
+Like ordinary incremental search except that your input is treated
+as a symbol surrounded by symbol boundary constructs \\_< and \\_>.
+See the command `isearch-forward' for more information."
+  (interactive "P\np")
+  (isearch-mode t nil nil (not no-recursive-edit) 'isearch-symbol-regexp))
+
 (defun isearch-backward (&optional regexp-p no-recursive-edit)
   "\
 Do incremental search backward.
@@ -747,14 +772,14 @@ (defun isearch-backward-regexp (&optiona
 ;;  "List of commands for which isearch-mode does not recursive-edit.")
 
 
-(defun isearch-mode (forward &optional regexp op-fun recursive-edit word-p)
+(defun isearch-mode (forward &optional regexp op-fun recursive-edit word)
   "Start Isearch minor mode.
 It is called by the function `isearch-forward' and other related functions."
 
   ;; Initialize global vars.
   (setq isearch-forward forward
 	isearch-regexp regexp
-	isearch-word word-p
+	isearch-word word
 	isearch-op-fun op-fun
 	isearch-last-case-fold-search isearch-case-fold-search
 	isearch-case-fold-search case-fold-search
@@ -1367,6 +1392,14 @@ (defun isearch-toggle-word ()
   (setq isearch-success t isearch-adjusted t)
   (isearch-update))
 
+(defun isearch-toggle-symbol ()
+  "Toggle symbol searching on or off."
+  (interactive)
+  (setq isearch-word (unless (eq isearch-word 'isearch-symbol-regexp)
+		       'isearch-symbol-regexp))
+  (setq isearch-success t isearch-adjusted t)
+  (isearch-update))
+
 (defun isearch-toggle-case-fold ()
   "Toggle case folding in searching on or off."
   (interactive)
@@ -1468,6 +1501,20 @@ (defun word-search-forward-lax (string &
   (interactive "sWord search: ")
   (re-search-forward (word-search-regexp string t) bound noerror count))
 
+;; Symbol search
+
+(defun isearch-symbol-regexp (string &optional lax)
+  "Return a regexp which matches STRING as a symbol.
+Creates a regexp where STRING is surrounded by symbol delimiters \\_< and \\_>.
+If LAX is non-nil, the end of the string need not match a symbol boundary."
+  (concat "\\_<" (regexp-quote string) (unless lax "\\_>")))
+
+(put 'isearch-symbol-regexp 'isearch-message-prefix "symbol ")
+
 
 (defun isearch-query-replace (&optional delimited regexp-flag)
   "Start `query-replace' with string to replace from last search string.
@@ -1534,6 +1581,8 @@ (defun isearch-occur (regexp &optional n
   (interactive
    (let* ((perform-collect (consp current-prefix-arg))
 	  (regexp (cond
+		   ((functionp isearch-word)
+		    (funcall isearch-word isearch-string))
 		   (isearch-word (word-search-regexp isearch-string))
 		   (isearch-regexp isearch-string)
 		   (t (regexp-quote isearch-string)))))
@@ -1749,6 +1800,8 @@ (defun isearch-search-and-update ()
 		       (setq case-fold-search
 			     (isearch-no-upper-case-p isearch-string isearch-regexp)))
 		   (looking-at (cond
+				((functionp isearch-word)
+				 (funcall isearch-word isearch-string t))
 				(isearch-word (word-search-regexp isearch-string t))
 				(isearch-regexp isearch-string)
 				(t (regexp-quote isearch-string)))))
@@ -2329,7 +2387,11 @@ (defun isearch-message-prefix (&optional
 			      (< (point) isearch-opoint)))
 		       "over")
 		   (if isearch-wrapped "wrapped ")
-		   (if isearch-word "word " "")
+		   (if isearch-word
+		       (or (and (symbolp isearch-word)
+				(get isearch-word 'isearch-message-prefix))
+			   "word ")
+		     "")
 		   (if isearch-regexp "regexp " "")
 		   (if multi-isearch-next-buffer-current-function "multi " "")
 		   (or isearch-message-prefix-add "")
@@ -2356,8 +2418,8 @@ (defun isearch-message-suffix (&optional
 
 ;; Searching
 
-(defvar isearch-search-fun-function nil
-  "Overrides the default `isearch-search-fun' behavior.
+(defvar isearch-search-fun-function 'isearch-search-fun-default
+  "Non-default value overrides the behavior of `isearch-search-fun-default'.
 This variable's value should be a function, which will be called
 with no arguments, and should return a function that takes three
 arguments: STRING, BOUND, and NOERROR.
@@ -2368,22 +2430,29 @@ (defvar isearch-search-fun-function nil
 (defun isearch-search-fun ()
   "Return the function to use for the search.
 Can be changed via `isearch-search-fun-function' for special needs."
-  (if isearch-search-fun-function
-      (funcall isearch-search-fun-function)
+  (funcall (or isearch-search-fun-function 'isearch-search-fun-default)))
+
+(defun isearch-search-fun-default ()
+  "Return default functions to use for the search."
     (cond
      (isearch-word
+    (lambda (string &optional bound noerror count)
       ;; Use lax versions to not fail at the end of the word while
       ;; the user adds and removes characters in the search string
       ;; (or when using nonincremental word isearch)
-      (if (or isearch-nonincremental
+      (let ((lax (not (or isearch-nonincremental
 	      (eq (length isearch-string)
-		  (length (isearch-string-state (car isearch-cmds)))))
-	  (if isearch-forward 'word-search-forward 'word-search-backward)
-	(if isearch-forward 'word-search-forward-lax 'word-search-backward-lax)))
+			      (length (isearch-string-state (car isearch-cmds))))))))
+	(funcall
+	 (if isearch-forward #'re-search-forward #'re-search-backward)
+	 (if (functionp isearch-word)
+	     (funcall isearch-word string lax)
+	   (word-search-regexp string lax))
+	 bound noerror count))))
      (isearch-regexp
       (if isearch-forward 're-search-forward 're-search-backward))
      (t
-      (if isearch-forward 'search-forward 'search-backward)))))
+    (if isearch-forward 'search-forward 'search-backward))))
 
 (defun isearch-search-string (string bound noerror)
   "Search for the first occurrence of STRING or its translation.

=== modified file 'lisp/comint.el'
--- lisp/comint.el	2012-05-15 16:58:35 +0000
+++ lisp/comint.el	2012-05-28 08:50:41 +0000
@@ -1463,18 +1463,10 @@ (defun comint-goto-input (pos)
 
 (defun comint-history-isearch-search ()
   "Return the proper search function, for Isearch in input history."
-  (cond
-   (isearch-word
-    (if isearch-forward 'word-search-forward 'word-search-backward))
-   (t
     (lambda (string bound noerror)
       (let ((search-fun
 	     ;; Use standard functions to search within comint text
-             (cond
-              (isearch-regexp
-               (if isearch-forward 're-search-forward 're-search-backward))
-              (t
-               (if isearch-forward 'search-forward 'search-backward))))
+	   (isearch-search-fun-default))
 	    found)
 	;; Avoid lazy-highlighting matches in the comint prompt and in the
 	;; output when searching forward.  Lazy-highlight calls this lambda
@@ -1523,7 +1515,7 @@ (defun comint-history-isearch-search ()
 		 ;; Return point of the new search result
 		 (point))
 	     ;; Return nil on the error "no next/preceding item"
-	     (error nil)))))))))
+	   (error nil)))))))
 
 (defun comint-history-isearch-message (&optional c-q-hack ellipsis)
   "Display the input history search prompt.
@@ -1556,14 +1548,13 @@ (defun comint-history-isearch-wrap ()
   "Wrap the input history search when search fails.
 Move point to the first history element for a forward search,
 or to the last history element for a backward search."
-  (unless isearch-word
     ;; When `comint-history-isearch-search' fails on reaching the
     ;; beginning/end of the history, wrap the search to the first/last
     ;; input history element.
     (if isearch-forward
 	(comint-goto-input (1- (ring-length comint-input-ring)))
       (comint-goto-input nil))
-    (setq isearch-success t))
+  (setq isearch-success t)
   (goto-char (if isearch-forward (comint-line-beginning-position) (point-max))))
 
 (defun comint-history-isearch-push-state ()

=== modified file 'lisp/info.el'
--- lisp/info.el	2012-05-22 03:31:34 +0000
+++ lisp/info.el	2012-05-28 08:27:29 +0000
@@ -1913,26 +1916,23 @@ (defun Info-search-backward (regexp &opt
 (defun Info-isearch-search ()
   (if Info-isearch-search
       (lambda (string &optional bound noerror count)
-	(if isearch-word
-	    (Info-search (concat "\\b" (replace-regexp-in-string
-					"\\W+" "\\W+"
-					(replace-regexp-in-string
-					 "^\\W+\\|\\W+$" "" string)
-					nil t)
+	(Info-search
+	 (cond
+	  (isearch-word
 				 ;; Lax version of word search
-				 (if (or isearch-nonincremental
+	   (let ((lax (not (or isearch-nonincremental
 					 (eq (length string)
 					     (length (isearch-string-state
-						      (car isearch-cmds)))))
-				     "\\b"))
+					    (car isearch-cmds))))))))
+	     (if (functionp isearch-word)
+		 (funcall isearch-word string lax)
+	       (word-search-regexp string lax))))
+	  (isearch-regexp string)
+	  (t (regexp-quote string)))
 			 bound noerror count
 			 (unless isearch-forward 'backward))
-	  (Info-search (if isearch-regexp string (regexp-quote string))
-		       bound noerror count
-		       (unless isearch-forward 'backward)))
 	(point))
-    (let ((isearch-search-fun-function nil))
-      (isearch-search-fun))))
+    (isearch-search-fun-default)))
 
 (defun Info-isearch-wrap ()
   (if Info-isearch-search

=== modified file 'lisp/misearch.el'
--- lisp/misearch.el	2012-01-19 07:21:25 +0000
+++ lisp/misearch.el	2012-05-28 08:43:16 +0000
@@ -130,13 +130,7 @@ (defun multi-isearch-search-fun ()
   (lambda (string bound noerror)
     (let ((search-fun
 	   ;; Use standard functions to search within one buffer
-	   (cond
-	    (isearch-word
-	     (if isearch-forward 'word-search-forward 'word-search-backward))
-	    (isearch-regexp
-	     (if isearch-forward 're-search-forward 're-search-backward))
-	    (t
-	     (if isearch-forward 'search-forward 'search-backward))))
+	   (isearch-search-fun-default))
 	  found buffer)
       (or
        ;; 1. First try searching in the initial buffer

=== modified file 'lisp/simple.el'
--- lisp/simple.el	2012-05-04 23:16:47 +0000
+++ lisp/simple.el	2012-05-28 08:29:25 +0000
@@ -1699,18 +1771,10 @@ (defun minibuffer-history-isearch-end ()
 
 (defun minibuffer-history-isearch-search ()
   "Return the proper search function, for isearch in minibuffer history."
-  (cond
-   (isearch-word
-    (if isearch-forward 'word-search-forward 'word-search-backward))
-   (t
     (lambda (string bound noerror)
       (let ((search-fun
 	     ;; Use standard functions to search within minibuffer text
-             (cond
-              (isearch-regexp
-               (if isearch-forward 're-search-forward 're-search-backward))
-              (t
-               (if isearch-forward 'search-forward 'search-backward))))
+	   (isearch-search-fun-default))
 	    found)
 	;; Avoid lazy-highlighting matches in the minibuffer prompt when
 	;; searching forward.  Lazy-highlight calls this lambda with the
@@ -1750,7 +1814,7 @@ (defun minibuffer-history-isearch-search
 		 ;; Return point of the new search result
 		 (point))
 	     ;; Return nil when next(prev)-history-element fails
-	     (error nil)))))))))
+	   (error nil)))))))
 
 (defun minibuffer-history-isearch-message (&optional c-q-hack ellipsis)
   "Display the minibuffer history search prompt.
@@ -1781,14 +1845,13 @@ (defun minibuffer-history-isearch-wrap (
   "Wrap the minibuffer history search when search fails.
 Move point to the first history element for a forward search,
 or to the last history element for a backward search."
-  (unless isearch-word
     ;; When `minibuffer-history-isearch-search' fails on reaching the
     ;; beginning/end of the history, wrap the search to the first/last
     ;; minibuffer history element.
     (if isearch-forward
 	(goto-history-element (length (symbol-value minibuffer-history-variable)))
       (goto-history-element 0))
-    (setq isearch-success t))
+  (setq isearch-success t)
   (goto-char (if isearch-forward (minibuffer-prompt-end) (point-max))))
 
 (defun minibuffer-history-isearch-push-state ()

=== modified file 'lisp/textmodes/reftex-global.el'
--- lisp/textmodes/reftex-global.el	2012-01-19 07:21:25 +0000
+++ lisp/textmodes/reftex-global.el	2012-05-28 08:49:52 +0000
@@ -350,9 +350,8 @@ (defun reftex-ensure-write-access (files
 ;; variable `multi-isearch-next-buffer-function'.
 
 (defun reftex-isearch-wrap-function ()
-  (if (not isearch-word)
       (switch-to-buffer
-       (funcall isearch-next-buffer-function (current-buffer) t)))
+   (funcall isearch-next-buffer-function (current-buffer) t))
   (goto-char (if isearch-forward (point-min) (point-max))))
 
 (defun reftex-isearch-push-state-function ()
@@ -364,14 +363,7 @@ (defun reftex-isearch-pop-state-function
 
 (defun reftex-isearch-isearch-search (string bound noerror)
   (let ((nxt-buff nil)
-	(search-fun
-	 (cond
-	  (isearch-word
-	   (if isearch-forward 'word-search-forward 'word-search-backward))
-	  (isearch-regexp
-	   (if isearch-forward 're-search-forward 're-search-backward))
-	  (t
-	   (if isearch-forward 'search-forward 'search-backward)))))
+	(search-fun (isearch-search-fun-default)))
     (or
      (funcall search-fun string bound noerror)
      (unless bound





This bug report was last modified 12 years and 205 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.