Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?

From: Juri Linkov <[email-masked]>
Date: Sun, 27 May 2012 12:43:37 +0300

>>> @@ -1425,7 +1445,11 @@ (defun word-search-backward (string &opt
>>> of words in STRING to a regexp used to search words without regard
>>> to punctuation."
>>> (interactive "sWord search backward: ")
>>> -  (re-search-backward (word-search-regexp string nil) bound noerror count))
>>> +  (re-search-backward
>>> +   (if (functionp isearch-word)
>>> +       (funcall isearch-word string nil)
>>> +     (word-search-regexp string nil))
>>> +   bound noerror count))
>> This doesn't sound right.
>
> I guess I was a bit terse here: what I meant is that changing the
> behavior depending on isearch-* variables is OK for a function named
> isearch-foo but not word-search-*ward.

Agreed.  This patch adds 4 new functions `isearch-word-search-*'.
Also it splits the standard default part of `isearch-search-fun'
into a separate function `isearch-search-fun-default' that can be
used to obtain the default search function in any special search
function that overrides `isearch-search-fun' like is is demonstrated
in the second patch for `minibuffer-history-isearch-search' below.
Additionally it enables the word search in the minibuffer with no effort
(the key clash with `M-s w' in the minibuffer is another issue).
I'll also go through other search functions and enable word/symbol search
in them as well.

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2012-05-17 00:03:49 +0000
+++ lisp/isearch.el	2012-05-27 09:43:07 +0000
@@ -1468,6 +1500,62 @@ (defun word-search-forward-lax (string &
   (interactive "sWord search: ")
   (re-search-forward (word-search-regexp string t) bound noerror count))
 
+;; General word-like regexp-based search.
+
+(defun isearch-word-search-backward (string &optional bound noerror count)
+  "Search backward from point for STRING, converted to regexp.
+Like `word-search-backward', but uses a function from the variable
+`isearch-word' to convert STRING to the regexp."
+  (re-search-backward
+   (if (functionp isearch-word)
+       (funcall isearch-word string nil)
+     (word-search-regexp string nil))
+   bound noerror count))
+
+(defun isearch-word-search-forward (string &optional bound noerror count)
+  "Search forward from point for STRING, converted to regexp.
+Like `word-search-forward', but uses a function from the variable
+`isearch-word' to convert STRING to the regexp."
+  (re-search-forward
+   (if (functionp isearch-word)
+       (funcall isearch-word string nil)
+     (word-search-regexp string nil))
+   bound noerror count))
+
+(defun isearch-word-search-backward-lax (string &optional bound noerror count)
+  "Search backward from point for STRING, converted to regexp.
+Like `word-search-backward-lax', but uses a function from the variable
+`isearch-word' to convert STRING to the regexp."
+  (re-search-backward
+   (if (functionp isearch-word)
+       (funcall isearch-word string t)
+     (word-search-regexp string t))
+   bound noerror count))
+
+(defun isearch-word-search-forward-lax (string &optional bound noerror count)
+  "Search forward from point for STRING, converted to regexp.
+Like `word-search-forward-lax', but uses a function from the variable
+`isearch-word' to convert STRING to the regexp."
+  (re-search-forward
+   (if (functionp isearch-word)
+       (funcall isearch-word string t)
+     (word-search-regexp string t))
+   bound noerror count))
+
+;; Symbol search
+
+(defun symbol-search-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 unless it ends in whitespace."
+  (concat
+   "\\_<"
+   (regexp-quote string)
+   (if (or (not lax) (string-match-p "\\W$" string)) "\\_>")))
+
+(put 'symbol-search-regexp 'isearch-message-prefix "symbol ")
+
 
 (defun isearch-query-replace (&optional delimited regexp-flag)
   "Start `query-replace' with string to replace from last search string.
@@ -2370,20 +2473,23 @@ (defun isearch-search-fun ()
 Can be changed via `isearch-search-fun-function' for special needs."
   (if isearch-search-fun-function
       (funcall isearch-search-fun-function)
-    (cond
-     (isearch-word
-      ;; 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
-	      (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)))
-     (isearch-regexp
-      (if isearch-forward 're-search-forward 're-search-backward))
-     (t
-      (if isearch-forward 'search-forward 'search-backward)))))
+    (isearch-search-fun-default)))
+
+(defun isearch-search-fun-default ()
+  (cond
+   (isearch-word
+    ;; 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
+	    (eq (length isearch-string)
+		(length (isearch-string-state (car isearch-cmds)))))
+	(if isearch-forward 'isearch-word-search-forward 'isearch-word-search-backward)
+      (if isearch-forward 'isearch-word-search-forward-lax 'isearch-word-search-backward-lax)))
+   (isearch-regexp
+    (if isearch-forward 're-search-forward 're-search-backward))
+   (t
+    (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/simple.el'
--- lisp/simple.el	2012-05-12 21:11:21 +0000
+++ lisp/simple.el	2012-05-27 09:43:19 +0000
@@ -1771,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
@@ -1822,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.