Subject: Re: bug#25562: 25.1; isearch-forward-word first matches a non-word

From: Juri Linkov <[email-masked]>
Date: Tue, 31 Jan 2017 01:24:07 +0200

>>> I see, thanks for the explanation. That's still unsatisfactory to me. I
>>> think an ideal incremental word search would just start over from the
>>> current point each time a new character is typed (that's what most users
>>> would expect). Then any non-insertion command would make the user "commit"
>>> to the particular search and the incremental search proper would begin. Is
>>> that compatible with the current design of isearch?
>>
>> What you describe looks like isearch-barrier used for subsequent \| in regexps,
>> e.g. typing ‘C-M-s ^\<it\>’ and then ‘\|’ moves point back to the beginning
>> of the search.  But wouldn't this make the search too “jumpy”, especially
>> while typing long words?
>
> My use case of isearch-word is mainly short words, e.g. variable names
> such as f in f(x) in latex. I'd guess that's a pretty common pattern.
> Even for long words, I think an user would type a word quickly, and be
> confused that their first match is not really a match. That offsets the
> potential jumpiness (ie what happens when the user is typing the word)
> for me.

You can try yourself using the minimal patch below that demonstrates your idea.

But from what I see, it's not too good, using the recipe from your top post:

emacs -Q
M-<
M-s w
i

After typing the letter “i”, isearch fails, beeps, flashes the screen,
with a clear indication that something went wrong.  This is more confusing
for a user, because now a user has to stop and think about what is wrong.

Here is the patch to help seeing this in action:

diff --git a/lisp/isearch.el b/lisp/isearch.el
index 5c48c30..85b9365 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -1616,6 +1616,7 @@ (defun word-search-regexp (string &optional lax)
 
 Used in `word-search-forward', `word-search-backward',
 `word-search-forward-lax', `word-search-backward-lax'."
+  (setq lax nil)
   (cond
    ((equal string "") "")
    ((string-match-p "\\`\\W+\\'" string) "\\W+")
@@ -2465,6 +2466,11 @@ (defun isearch-process-search-char (char &optional count)
   ;; } and | are special in regexps when preceded by \.
   ;; Nothing special for + because it matches at least once.
   (cond
+   ((eq isearch-regexp-function t)
+    (goto-char isearch-barrier)
+    (setq isearch-other-end isearch-barrier
+          isearch-success t
+          isearch-error nil))
    ((memq char '(?* ??)) (isearch-fallback nil))
    ((eq   char ?\})      (isearch-fallback t t))
    ((eq   char ?|)       (isearch-fallback t nil t)))