GNU bug report logs - #10145
24.0.91; Word Isearch backward

Previous Next

Package: emacs;

Reported by: Dani Moncayo <dmoncayo <at> gmail.com>

Date: Sat, 26 Nov 2011 20:29:01 UTC

Severity: normal

Tags: patch

Found in version 24.0.91

Done: Juri Linkov <juri <at> jurta.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 10145 in the body.
You can then email your comments to 10145 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#10145; Package emacs. (Sat, 26 Nov 2011 20:29:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Dani Moncayo <dmoncayo <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sat, 26 Nov 2011 20:29:01 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Dani Moncayo <dmoncayo <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 24.0.91; Word Isearch backward
Date: Sat, 26 Nov 2011 21:26:58 +0100
Hi,

from "emacs -Q", type: `a a RET b b RET M-s w C-r a a SPC b b'.

At this point, the Isearch (word-type, backward) should succeed, but I
see a failing one.

In GNU Emacs 24.0.91.1 (i386-mingw-nt6.1.7601)
 of 2011-11-25 on DANI-PC
Windowing system distributor `Microsoft Corp.', version 6.1.7601
configured using `configure --with-gcc (4.6) --cflags -fno-omit-frame-pointer'

-- 
Dani Moncayo




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10145; Package emacs. (Tue, 29 Nov 2011 00:46:02 GMT) Full text and rfc822 format available.

Message #8 received at 10145 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: Dani Moncayo <dmoncayo <at> gmail.com>
Cc: 10145 <at> debbugs.gnu.org
Subject: Re: bug#10145: 24.0.91; Word Isearch backward
Date: Tue, 29 Nov 2011 02:33:06 +0200
> from "emacs -Q", type: `a a RET b b RET M-s w C-r a a SPC b b'.
>
> At this point, the Isearch (word-type, backward) should succeed, but I
> see a failing one.

Thanks, this is a bug.

The comment in `isearch-search-and-update' says:

    ;; In reverse search, adding stuff at
    ;; the end may cause zero or many more chars to be
    ;; matched, in the string following point.
    ;; Allow all those possibilities without moving point as
    ;; long as the match does not extend past search origin.

and it calls `looking-at' to implement this.
But it doesn't take into account word search.

The following patch fixes this bug by using `wordify'
now exposed to Lisp:

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2011-11-28 06:59:03 +0000
+++ lisp/isearch.el	2011-11-29 00:30:33 +0000
@@ -1648,8 +1643,10 @@ (defun isearch-search-and-update ()
 		   (if (and (eq case-fold-search t) search-upper-case)
 		       (setq case-fold-search
 			     (isearch-no-upper-case-p isearch-string isearch-regexp)))
-		   (looking-at (if isearch-regexp isearch-string
-				 (regexp-quote isearch-string))))
+		   (looking-at (cond
+				(isearch-regexp isearch-string)
+				(isearch-word (wordify isearch-string t))
+				(t (regexp-quote isearch-string)))))
 	       (error nil))
 	     (or isearch-yank-flag
 		 (<= (match-end 0)

=== modified file 'src/search.c'
--- src/search.c	2011-11-27 18:17:40 +0000
+++ src/search.c	2011-11-29 00:29:22 +0000
@@ -2078,13 +2078,12 @@ (at your option) any later version.
   XSETBUFFER (last_thing_searched, current_buffer);
 }
 
-/* Given STRING, a string of words separated by word delimiters,
-   compute a regexp that matches those exact words separated by
-   arbitrary punctuation.  If LAX is nonzero, the end of the string
-   need not match a word boundary unless it ends in whitespace.  */
-
-static Lisp_Object
-wordify (Lisp_Object string, int lax)
+DEFUN ("wordify", Fwordify, Swordify, 1, 2, 0,
+       doc: /* Given STRING, a string of words separated by word delimiters,
+compute a regexp that matches those exact words separated by
+arbitrary punctuation.  If LAX is non-nil, the end of the string
+need not match a word boundary unless it ends in whitespace.  */)
+  (Lisp_Object string, Lisp_Object lax)
 {
   register unsigned char *o;
   register EMACS_INT i, i_byte, len, punct_count = 0, word_count = 0;
@@ -2125,7 +2124,7 @@ (at your option) any later version.
     }
 
   adjust = - punct_count + 5 * (word_count - 1)
-    + ((lax && !whitespace_at_end) ? 2 : 4);
+    + ((!NILP (lax) && !whitespace_at_end) ? 2 : 4);
   if (STRING_MULTIBYTE (string))
     val = make_uninit_multibyte_string (len + adjust,
 					SBYTES (string)
@@ -2162,7 +2161,7 @@ (at your option) any later version.
       prev_c = c;
     }
 
-  if (!lax || whitespace_at_end)
+  if (NILP (lax) || whitespace_at_end)
     {
       *o++ = '\\';
       *o++ = 'b';
@@ -2220,7 +2219,7 @@ (at your option) any later version.
 Optional fourth argument is repeat count--search for successive occurrences.  */)
   (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
 {
-  return search_command (wordify (string, 0), bound, noerror, count, -1, 1, 0);
+  return search_command (Fwordify (string, Qnil), bound, noerror, count, -1, 1, 0);
 }
 
 DEFUN ("word-search-forward", Fword_search_forward, Sword_search_forward, 1, 4,
@@ -2234,7 +2233,7 @@ (at your option) any later version.
 Optional fourth argument is repeat count--search for successive occurrences.  */)
   (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
 {
-  return search_command (wordify (string, 0), bound, noerror, count, 1, 1, 0);
+  return search_command (Fwordify (string, Qnil), bound, noerror, count, 1, 1, 0);
 }
 
 DEFUN ("word-search-backward-lax", Fword_search_backward_lax, Sword_search_backward_lax, 1, 4,
@@ -2252,7 +2251,7 @@ (at your option) any later version.
 Optional fourth argument is repeat count--search for successive occurrences.  */)
   (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
 {
-  return search_command (wordify (string, 1), bound, noerror, count, -1, 1, 0);
+  return search_command (Fwordify (string, Qt), bound, noerror, count, -1, 1, 0);
 }
 
 DEFUN ("word-search-forward-lax", Fword_search_forward_lax, Sword_search_forward_lax, 1, 4,
@@ -2270,7 +2269,7 @@ (at your option) any later version.
 Optional fourth argument is repeat count--search for successive occurrences.  */)
   (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
 {
-  return search_command (wordify (string, 1), bound, noerror, count, 1, 1, 0);
+  return search_command (Fwordify (string, Qt), bound, noerror, count, 1, 1, 0);
 }
 
 DEFUN ("re-search-backward", Fre_search_backward, Sre_search_backward, 1, 4,
@@ -3229,6 +3228,7 @@ (at your option) any later version.
   defsubr (&Sposix_string_match);
   defsubr (&Ssearch_forward);
   defsubr (&Ssearch_backward);
+  defsubr (&Swordify);
   defsubr (&Sword_search_forward);
   defsubr (&Sword_search_backward);
   defsubr (&Sword_search_forward_lax);



Actually there are more places that require the Lisp call to `wordify'
like in `isearch-occur':

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2011-11-28 06:59:03 +0000
+++ lisp/isearch.el	2011-11-29 00:30:33 +0000
@@ -1447,12 +1447,7 @@ (defun isearch-occur (regexp &optional n
   (interactive
    (list
     (cond
-     (isearch-word (concat "\\b" (replace-regexp-in-string
-				  "\\W+" "\\W+"
-				  (replace-regexp-in-string
-				   "^\\W+\\|\\W+$" "" isearch-string)
-				  nil t)
-			   "\\b"))
+     (isearch-word (wordify isearch-string))
      (isearch-regexp isearch-string)
      (t (regexp-quote isearch-string)))
     (if current-prefix-arg (prefix-numeric-value current-prefix-arg))))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10145; Package emacs. (Tue, 29 Nov 2011 08:43:02 GMT) Full text and rfc822 format available.

Message #11 received at 10145 <at> debbugs.gnu.org (full text, mbox):

From: Andreas Schwab <schwab <at> linux-m68k.org>
To: Juri Linkov <juri <at> jurta.org>
Cc: 10145 <at> debbugs.gnu.org, Dani Moncayo <dmoncayo <at> gmail.com>
Subject: Re: bug#10145: 24.0.91; Word Isearch backward
Date: Tue, 29 Nov 2011 09:40:09 +0100
Juri Linkov <juri <at> jurta.org> writes:

> +       doc: /* Given STRING, a string of words separated by word delimiters,

The first line needs to be a complete sentence.

Andreas.

-- 
Andreas Schwab, schwab <at> linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10145; Package emacs. (Wed, 30 Nov 2011 09:58:02 GMT) Full text and rfc822 format available.

Message #14 received at 10145 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: Andreas Schwab <schwab <at> linux-m68k.org>
Cc: 10145 <at> debbugs.gnu.org, Dani Moncayo <dmoncayo <at> gmail.com>
Subject: Re: bug#10145: 24.0.91; Word Isearch backward
Date: Wed, 30 Nov 2011 11:46:38 +0200
>> +       doc: /* Given STRING, a string of words separated by word delimiters,
>
> The first line needs to be a complete sentence.

In the patch below the first line is a complete sentence,
and `wordify' is renamed to a better and more correct name
`word-regexp':

=== modified file 'src/search.c'
--- src/search.c	2011-11-27 18:17:40 +0000
+++ src/search.c	2011-11-30 09:41:35 +0000
@@ -2078,13 +2078,13 @@ (at your option) any later version.
   XSETBUFFER (last_thing_searched, current_buffer);
 }
 
-/* Given STRING, a string of words separated by word delimiters,
-   compute a regexp that matches those exact words separated by
-   arbitrary punctuation.  If LAX is nonzero, the end of the string
-   need not match a word boundary unless it ends in whitespace.  */
-
-static Lisp_Object
-wordify (Lisp_Object string, int lax)
+DEFUN ("word-regexp", Fword_regexp, Sword_regexp, 1, 2, 0,
+       doc: /* Return a regexp which matches words, ignoring punctuation.
+Given STRING, a string of words separated by word delimiters,
+compute a regexp that matches those exact words separated by
+arbitrary punctuation.  If LAX is non-nil, the end of the string
+need not match a word boundary unless it ends in whitespace.  */)
+  (Lisp_Object string, Lisp_Object lax)
 {
   register unsigned char *o;
   register EMACS_INT i, i_byte, len, punct_count = 0, word_count = 0;
@@ -2125,7 +2125,7 @@ (at your option) any later version.
     }
 
   adjust = - punct_count + 5 * (word_count - 1)
-    + ((lax && !whitespace_at_end) ? 2 : 4);
+    + ((!NILP (lax) && !whitespace_at_end) ? 2 : 4);
   if (STRING_MULTIBYTE (string))
     val = make_uninit_multibyte_string (len + adjust,
 					SBYTES (string)
@@ -2162,7 +2162,7 @@ (at your option) any later version.
       prev_c = c;
     }
 
-  if (!lax || whitespace_at_end)
+  if (NILP (lax) || whitespace_at_end)
     {
       *o++ = '\\';
       *o++ = 'b';
@@ -2220,7 +2220,7 @@ (at your option) any later version.
 Optional fourth argument is repeat count--search for successive occurrences.  */)
   (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
 {
-  return search_command (wordify (string, 0), bound, noerror, count, -1, 1, 0);
+  return search_command (Fword_regexp (string, Qnil), bound, noerror, count, -1, 1, 0);
 }
 
 DEFUN ("word-search-forward", Fword_search_forward, Sword_search_forward, 1, 4,
@@ -2234,7 +2234,7 @@ (at your option) any later version.
 Optional fourth argument is repeat count--search for successive occurrences.  */)
   (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
 {
-  return search_command (wordify (string, 0), bound, noerror, count, 1, 1, 0);
+  return search_command (Fword_regexp (string, Qnil), bound, noerror, count, 1, 1, 0);
 }
 
 DEFUN ("word-search-backward-lax", Fword_search_backward_lax, Sword_search_backward_lax, 1, 4,
@@ -2252,7 +2252,7 @@ (at your option) any later version.
 Optional fourth argument is repeat count--search for successive occurrences.  */)
   (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
 {
-  return search_command (wordify (string, 1), bound, noerror, count, -1, 1, 0);
+  return search_command (Fword_regexp (string, Qt), bound, noerror, count, -1, 1, 0);
 }
 
 DEFUN ("word-search-forward-lax", Fword_search_forward_lax, Sword_search_forward_lax, 1, 4,
@@ -2270,7 +2270,7 @@ (at your option) any later version.
 Optional fourth argument is repeat count--search for successive occurrences.  */)
   (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
 {
-  return search_command (wordify (string, 1), bound, noerror, count, 1, 1, 0);
+  return search_command (Fword_regexp (string, Qt), bound, noerror, count, 1, 1, 0);
 }
 
 DEFUN ("re-search-backward", Fre_search_backward, Sre_search_backward, 1, 4,
@@ -3229,6 +3229,7 @@ (at your option) any later version.
   defsubr (&Sposix_string_match);
   defsubr (&Ssearch_forward);
   defsubr (&Ssearch_backward);
+  defsubr (&Sword_regexp);
   defsubr (&Sword_search_forward);
   defsubr (&Sword_search_backward);
   defsubr (&Sword_search_forward_lax);

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2011-11-29 18:39:16 +0000
+++ lisp/isearch.el	2011-11-30 09:41:35 +0000
@@ -1438,12 +1447,7 @@ (defun isearch-occur (regexp &optional n
   (interactive
    (list
     (cond
-     (isearch-word (concat "\\b" (replace-regexp-in-string
-				  "\\W+" "\\W+"
-				  (replace-regexp-in-string
-				   "^\\W+\\|\\W+$" "" isearch-string)
-				  nil t)
-			   "\\b"))
+     (isearch-word (word-regexp isearch-string))
      (isearch-regexp isearch-string)
      (t (regexp-quote isearch-string)))
     (if current-prefix-arg (prefix-numeric-value current-prefix-arg))))
@@ -1642,8 +1646,10 @@ (defun isearch-search-and-update ()
 		   (if (and (eq case-fold-search t) search-upper-case)
 		       (setq case-fold-search
 			     (isearch-no-upper-case-p isearch-string isearch-regexp)))
-		   (looking-at (if isearch-regexp isearch-string
-				 (regexp-quote isearch-string))))
+		   (looking-at (cond
+				(isearch-regexp isearch-string)
+				(isearch-word (word-regexp isearch-string t))
+				(t (regexp-quote isearch-string)))))
 	       (error nil))
 	     (or isearch-yank-flag
 		 (<= (match-end 0)





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10145; Package emacs. (Wed, 30 Nov 2011 14:03:01 GMT) Full text and rfc822 format available.

Message #17 received at 10145 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
To: Juri Linkov <juri <at> jurta.org>
Cc: Andreas Schwab <schwab <at> linux-m68k.org>, 10145 <at> debbugs.gnu.org
Subject: Re: bug#10145: 24.0.91; Word Isearch backward
Date: Wed, 30 Nov 2011 09:02:05 -0500
> In the patch below the first line is a complete sentence,
> and `wordify' is renamed to a better and more correct name
> `word-regexp':

While `wordify' was OK as a local function in search.c, I think that
both `wordify' and `word-regexp' are too terse names for (global)
Elisp functions.  Maybe `search-words-regexp' would be appropriate.
Of course, I also see no reason why it should be implemented in C, so
moving it to Elisp would be welcome.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10145; Package emacs. (Wed, 30 Nov 2011 15:46:02 GMT) Full text and rfc822 format available.

Message #20 received at 10145 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
Cc: Andreas Schwab <schwab <at> linux-m68k.org>, 10145 <at> debbugs.gnu.org
Subject: Re: bug#10145: 24.0.91; Word Isearch backward
Date: Wed, 30 Nov 2011 17:32:45 +0200
>> In the patch below the first line is a complete sentence,
>> and `wordify' is renamed to a better and more correct name
>> `word-regexp':
>
> While `wordify' was OK as a local function in search.c, I think that
> both `wordify' and `word-regexp' are too terse names for (global)
> Elisp functions.  Maybe `search-words-regexp' would be appropriate.

I constructed that name based on the naming pattern of related functions
`word-search-forward' and `word-search-backward'.  A similar name
would be `word-search-regexp'.  However, it is used not only for search,
but for `looking-at' too, so we have to eliminate the `search' part
from the name.  Therefore `word-regexp'.

Another naming pattern would be `regexp-quote' that takes a string
and returns a regexp.  `quote' is a verb here, so using a verb
would produce a name like `regexp-wordify'.

Yet another naming pattern is `number-to-string'.  Using that
we get the name `words-to-regexp'.

> Of course, I also see no reason why it should be implemented in C, so
> moving it to Elisp would be welcome.

I'll provide an Elisp version once the function name is agreed upon.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10145; Package emacs. (Wed, 30 Nov 2011 19:12:02 GMT) Full text and rfc822 format available.

Message #23 received at 10145 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
To: Juri Linkov <juri <at> jurta.org>
Cc: Andreas Schwab <schwab <at> linux-m68k.org>, 10145 <at> debbugs.gnu.org
Subject: Re: bug#10145: 24.0.91; Word Isearch backward
Date: Wed, 30 Nov 2011 14:11:18 -0500
> `word-search-forward' and `word-search-backward'.  A similar name
> would be `word-search-regexp'.  However, it is used not only for search,
> but for `looking-at' too, so we have to eliminate the `search' part
> from the name.  Therefore `word-regexp'.

`word-search-regexp' is good, thank you.

> I'll provide an Elisp version once the function name is agreed upon.

Thanks.  Of course, that would/will have to wait for 24.2.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10145; Package emacs. (Thu, 01 Dec 2011 07:33:01 GMT) Full text and rfc822 format available.

Message #26 received at 10145 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
Cc: 10145 <at> debbugs.gnu.org
Subject: Re: bug#10145: 24.0.91; Word Isearch backward
Date: Thu, 01 Dec 2011 09:27:14 +0200
> `word-search-regexp' is good, thank you.
>
>> I'll provide an Elisp version once the function name is agreed upon.
>
> Thanks.  Of course, that would/will have to wait for 24.2.

This is intended to fix a bug reported by Dani for 24.1.

Below is a complete patch.  Please decide what to do.

The Elisp version passes all regression tests and its output
is identical to the output of the C version:

(word-search-regexp "")        ""
(word-search-regexp " ")       ""
(word-search-regexp "w")       "\\bw\\b"
(word-search-regexp " w")      "\\bw\\b"
(word-search-regexp "w ")      "\\bw\\b"
(word-search-regexp " w ")     "\\bw\\b"
(word-search-regexp "w w")     "\\bw\\W\\W*w\\b"
(word-search-regexp " w w")    "\\bw\\W\\W*w\\b"
(word-search-regexp "w w ")    "\\bw\\W\\W*w\\b"
(word-search-regexp " w w ")   "\\bw\\W\\W*w\\b"
(word-search-regexp "" t)      ""
(word-search-regexp " " t)     ""
(word-search-regexp "w" t)     "\\bw"
(word-search-regexp " w" t)    "\\bw"
(word-search-regexp "w " t)    "\\bw\\b"
(word-search-regexp " w " t)   "\\bw\\b"
(word-search-regexp "w w" t)   "\\bw\\W\\W*w"
(word-search-regexp " w w" t)  "\\bw\\W\\W*w"
(word-search-regexp "w w " t)  "\\bw\\W\\W*w\\b"
(word-search-regexp " w w " t) "\\bw\\W\\W*w\\b"

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2011-11-29 18:39:16 +0000
+++ lisp/isearch.el	2011-12-01 07:27:07 +0000
@@ -1380,6 +1389,20 @@ (defun isearch-toggle-case-fold ()
   (sit-for 1)
   (isearch-update))
 
+(defun word-search-regexp (string &optional lax)
+  "Return a regexp which matches words, ignoring punctuation.
+Given STRING, a string of words separated by word delimiters,
+compute a regexp that matches those exact words separated by
+arbitrary punctuation.  If LAX is non-nil, the end of the string
+need not match a word boundary unless it ends in whitespace.
+Used in `word-search-forward' and `word-search-backward'."
+  (if (string-match-p "^\\W*$" string)
+      ""
+    (concat
+     "\\b"
+     (mapconcat 'identity (split-string string "\\W\\W*" t) "\\W\\W*")
+     (if (or (not lax) (string-match-p "\\W$" string)) "\\b"))))
+
 (defun isearch-query-replace (&optional delimited regexp-flag)
   "Start `query-replace' with string to replace from last search string.
 The arg DELIMITED (prefix arg if interactive), if non-nil, means replace
@@ -1642,8 +1660,10 @@ (defun isearch-search-and-update ()
 		   (if (and (eq case-fold-search t) search-upper-case)
 		       (setq case-fold-search
 			     (isearch-no-upper-case-p isearch-string isearch-regexp)))
-		   (looking-at (if isearch-regexp isearch-string
-				 (regexp-quote isearch-string))))
+		   (looking-at (cond
+				(isearch-regexp isearch-string)
+				(isearch-word (word-search-regexp isearch-string t))
+				(t (regexp-quote isearch-string)))))
 	       (error nil))
 	     (or isearch-yank-flag
 		 (<= (match-end 0)

=== modified file 'src/search.c'
--- src/search.c	2011-11-27 18:17:40 +0000
+++ src/search.c	2011-12-01 07:27:07 +0000
@@ -2078,99 +2077,6 @@ (at your option) any later version.
   XSETBUFFER (last_thing_searched, current_buffer);
 }
 
-/* Given STRING, a string of words separated by word delimiters,
-   compute a regexp that matches those exact words separated by
-   arbitrary punctuation.  If LAX is nonzero, the end of the string
-   need not match a word boundary unless it ends in whitespace.  */
-
-static Lisp_Object
-wordify (Lisp_Object string, int lax)
-{
-  register unsigned char *o;
-  register EMACS_INT i, i_byte, len, punct_count = 0, word_count = 0;
-  Lisp_Object val;
-  int prev_c = 0;
-  EMACS_INT adjust;
-  int whitespace_at_end;
-
-  CHECK_STRING (string);
-  len = SCHARS (string);
-
-  for (i = 0, i_byte = 0; i < len; )
-    {
-      int c;
-
-      FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE (c, string, i, i_byte);
-
-      if (SYNTAX (c) != Sword)
-	{
-	  punct_count++;
-	  if (SYNTAX (prev_c) == Sword)
-	    word_count++;
-	}
-
-      prev_c = c;
-    }
-
-  if (SYNTAX (prev_c) == Sword)
-    {
-      word_count++;
-      whitespace_at_end = 0;
-    }
-  else
-    {
-      whitespace_at_end = 1;
-      if (!word_count)
-	return empty_unibyte_string;
-    }
-
-  adjust = - punct_count + 5 * (word_count - 1)
-    + ((lax && !whitespace_at_end) ? 2 : 4);
-  if (STRING_MULTIBYTE (string))
-    val = make_uninit_multibyte_string (len + adjust,
-					SBYTES (string)
-					+ adjust);
-  else
-    val = make_uninit_string (len + adjust);
-
-  o = SDATA (val);
-  *o++ = '\\';
-  *o++ = 'b';
-  prev_c = 0;
-
-  for (i = 0, i_byte = 0; i < len; )
-    {
-      int c;
-      EMACS_INT i_byte_orig = i_byte;
-
-      FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE (c, string, i, i_byte);
-
-      if (SYNTAX (c) == Sword)
-	{
-	  memcpy (o, SDATA (string) + i_byte_orig, i_byte - i_byte_orig);
-	  o += i_byte - i_byte_orig;
-	}
-      else if (SYNTAX (prev_c) == Sword && --word_count)
-	{
-	  *o++ = '\\';
-	  *o++ = 'W';
-	  *o++ = '\\';
-	  *o++ = 'W';
-	  *o++ = '*';
-	}
-
-      prev_c = c;
-    }
-
-  if (!lax || whitespace_at_end)
-    {
-      *o++ = '\\';
-      *o++ = 'b';
-    }
-
-  return val;
-}
-
 DEFUN ("search-backward", Fsearch_backward, Ssearch_backward, 1, 4,
        "MSearch backward: ",
        doc: /* Search backward from point for STRING.
@@ -2209,6 +2115,9 @@ (at your option) any later version.
   return search_command (string, bound, noerror, count, 1, 0, 0);
 }
 
+/* Function that returns a regexp which matches words, ignoring punctuation.  */
+static Lisp_Object Qword_search_regexp;
+
 DEFUN ("word-search-backward", Fword_search_backward, Sword_search_backward, 1, 4,
        "sWord search backward: ",
        doc: /* Search backward from point for STRING, ignoring differences in punctuation.
@@ -2217,10 +2126,15 @@ (at your option) any later version.
 The match found must not extend before that position.
 Optional third argument, if t, means if fail just return nil (no error).
   If not nil and not t, move to limit of search and return nil.
-Optional fourth argument is repeat count--search for successive occurrences.  */)
+Optional fourth argument is repeat count--search for successive occurrences.
+
+Relies on the function `word-search-regexp' to convert a sequence
+of words in STRING to a regexp used to search words without regard
+to punctuation.  */)
   (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
 {
-  return search_command (wordify (string, 0), bound, noerror, count, -1, 1, 0);
+  return search_command (call2 (Qword_search_regexp, string, Qnil),
+			 bound, noerror, count, -1, 1, 0);
 }
 
 DEFUN ("word-search-forward", Fword_search_forward, Sword_search_forward, 1, 4,
@@ -2231,10 +2145,15 @@ (at your option) any later version.
 The match found must not extend after that position.
 Optional third argument, if t, means if fail just return nil (no error).
   If not nil and not t, move to limit of search and return nil.
-Optional fourth argument is repeat count--search for successive occurrences.  */)
+Optional fourth argument is repeat count--search for successive occurrences.
+
+Relies on the function `word-search-regexp' to convert a sequence
+of words in STRING to a regexp used to search words without regard
+to punctuation.  */)
   (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
 {
-  return search_command (wordify (string, 0), bound, noerror, count, 1, 1, 0);
+  return search_command (call2 (Qword_search_regexp, string, Qnil),
+			 bound, noerror, count, 1, 1, 0);
 }
 
 DEFUN ("word-search-backward-lax", Fword_search_backward_lax, Sword_search_backward_lax, 1, 4,
@@ -2249,10 +2168,15 @@ (at your option) any later version.
 The match found must not extend before that position.
 Optional third argument, if t, means if fail just return nil (no error).
   If not nil and not t, move to limit of search and return nil.
-Optional fourth argument is repeat count--search for successive occurrences.  */)
+Optional fourth argument is repeat count--search for successive occurrences.
+
+Relies on the function `word-search-regexp' to convert a sequence
+of words in STRING to a regexp used to search words without regard
+to punctuation.  */)
   (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
 {
-  return search_command (wordify (string, 1), bound, noerror, count, -1, 1, 0);
+  return search_command (call2 (Qword_search_regexp, string, Qt),
+			 bound, noerror, count, -1, 1, 0);
 }
 
 DEFUN ("word-search-forward-lax", Fword_search_forward_lax, Sword_search_forward_lax, 1, 4,
@@ -2267,10 +2191,15 @@ (at your option) any later version.
 The match found must not extend after that position.
 Optional third argument, if t, means if fail just return nil (no error).
   If not nil and not t, move to limit of search and return nil.
-Optional fourth argument is repeat count--search for successive occurrences.  */)
+Optional fourth argument is repeat count--search for successive occurrences.
+
+Relies on the function `word-search-regexp' to convert a sequence
+of words in STRING to a regexp used to search words without regard
+to punctuation.  */)
   (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
 {
-  return search_command (wordify (string, 1), bound, noerror, count, 1, 1, 0);
+  return search_command (call2 (Qword_search_regexp, string, Qt),
+			 bound, noerror, count, 1, 1, 0);
 }
 
 DEFUN ("re-search-backward", Fre_search_backward, Sre_search_backward, 1, 4,
@@ -3243,4 +3172,5 @@ (at your option) any later version.
   defsubr (&Smatch_data);
   defsubr (&Sset_match_data);
   defsubr (&Sregexp_quote);
+  DEFSYM (Qword_search_regexp, "word-search-regexp");
 }





Added tag(s) patch. Request was from Juri Linkov <juri <at> jurta.org> to control <at> debbugs.gnu.org. (Thu, 01 Dec 2011 07:36:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10145; Package emacs. (Thu, 01 Dec 2011 16:01:01 GMT) Full text and rfc822 format available.

Message #31 received at 10145 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 10145 <at> debbugs.gnu.org
Subject: Re: bug#10145: 24.0.91; Word Isearch backward
Date: Thu, 01 Dec 2011 11:00:20 -0500
>> `word-search-regexp' is good, thank you.
>>> I'll provide an Elisp version once the function name is agreed upon.
>> Thanks.  Of course, that would/will have to wait for 24.2.
> This is intended to fix a bug reported by Dani for 24.1.

Yes, of course the fix needs to be installed now, only the move to Elisp
needs to wait for 24.2.


        Stefan


PS: BTW, I'd assume that word-search-{for,back}ward{-lax,} would want to
move to Elisp.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10145; Package emacs. (Fri, 02 Dec 2011 10:25:01 GMT) Full text and rfc822 format available.

Message #34 received at 10145 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 10145 <at> debbugs.gnu.org
Subject: Re: bug#10145: 24.0.91; Word Isearch backward
Date: Fri, 02 Dec 2011 12:22:11 +0200
> Yes, of course the fix needs to be installed now, only the move to Elisp
> needs to wait for 24.2.

Installed without reimplementing in Lisp.

> PS: BTW, I'd assume that word-search-{for,back}ward{-lax,} would want to
> move to Elisp.

I'll try to do that.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10145; Package emacs. (Fri, 02 Dec 2011 10:50:02 GMT) Full text and rfc822 format available.

Message #37 received at 10145 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> jurta.org>
Cc: monnier <at> iro.umontreal.ca, 10145 <at> debbugs.gnu.org
Subject: Re: bug#10145: 24.0.91; Word Isearch backward
Date: Fri, 02 Dec 2011 12:48:06 +0200
> From: Juri Linkov <juri <at> jurta.org>
> Date: Fri, 02 Dec 2011 12:22:11 +0200
> Cc: 10145 <at> debbugs.gnu.org
> 
> > PS: BTW, I'd assume that word-search-{for,back}ward{-lax,} would want to
> > move to Elisp.
> 
> I'll try to do that.

Thanks, but I very much hope such changes will wait for 24.2.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10145; Package emacs. (Fri, 02 Dec 2011 14:39:02 GMT) Full text and rfc822 format available.

Message #40 received at 10145 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
To: Juri Linkov <juri <at> jurta.org>
Cc: 10145 <at> debbugs.gnu.org
Subject: Re: bug#10145: 24.0.91; Word Isearch backward
Date: Fri, 02 Dec 2011 09:38:10 -0500
>> Yes, of course the fix needs to be installed now, only the move to Elisp
>> needs to wait for 24.2.
> Installed without reimplementing in Lisp.

Thank you, so we can close this bug, right?


        Stefan




Reply sent to Juri Linkov <juri <at> jurta.org>:
You have taken responsibility. (Fri, 02 Dec 2011 17:20:03 GMT) Full text and rfc822 format available.

Notification sent to Dani Moncayo <dmoncayo <at> gmail.com>:
bug acknowledged by developer. (Fri, 02 Dec 2011 17:20:04 GMT) Full text and rfc822 format available.

Message #45 received at 10145-done <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
Cc: 10145-done <at> debbugs.gnu.org
Subject: Re: bug#10145: 24.0.91; Word Isearch backward
Date: Fri, 02 Dec 2011 19:11:29 +0200
>>> Yes, of course the fix needs to be installed now, only the move to Elisp
>>> needs to wait for 24.2.
>> Installed without reimplementing in Lisp.
>
> Thank you, so we can close this bug, right?

Right, I'll try not to forget installing the move to Elisp
after feature freeze is over (the `pending' branch currently
looks like abandoned - not updated for a long time).




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 31 Dec 2011 12:24:02 GMT) Full text and rfc822 format available.

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

Previous Next


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