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.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 11381 in the body.
You can then email your comments to 11381 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#11381; Package emacs. (Sun, 29 Apr 2012 23:00:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Andy Grover <andy <at> groveronline.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sun, 29 Apr 2012 23:00:02 GMT) Full text and rfc822 format available.

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

From: Andy Grover <andy <at> groveronline.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 23.3; isearch-search-and-update issue?
Date: Sun, 29 Apr 2012 15:31:48 -0700
Hi I'm trying to use the following macro as defined on the emacs wiki:

http://emacswiki.org/emacs/SearchAtPoint#toc10

(defun my-isearch-word-at-point ()
  (interactive)
  (call-interactively 'isearch-forward-regexp))

(defun my-isearch-yank-word-hook ()
  (when (equal this-command 'my-isearch-word-at-point)
    (let ((string (concat "\\_<"
                          (buffer-substring-no-properties
                           (progn (skip-syntax-backward "w_") (point))
                           (progn (skip-syntax-forward "w_") (point)))
                          "\\_>")))
      (if (and isearch-case-fold-search
               (eq 'not-yanks search-upper-case))
          (setq string (downcase string)))
      (setq isearch-string string
            isearch-message
            (concat isearch-message
                    (mapconcat 'isearch-text-char-description
                               string ""))
            isearch-yank-flag t)
      (isearch-search-and-update))))

(add-hook 'isearch-mode-hook 'my-isearch-yank-word-hook)

(global-set-key "\M-8" 'my-isearch-word-at-point)

However, it's saying "wrong type argument: arrayp nil" sometimes.

Am I doing something wrong or is this a bug?

Thanks -- Andy


In GNU Emacs 23.3.1 (x86_64-redhat-linux-gnu, GTK+ Version 2.24.8)
 of 2012-01-13 on x86-04.phx2.fedoraproject.org
Windowing system distributor `Fedora Project', version 11.0.11104000
configured using `configure  '--build=x86_64-redhat-linux-gnu'
'--host=x86_64-redhat-linux-gnu' '--program-prefix='
'--disable-dependency-tracking' '--prefix=/usr' '--exec-prefix=/usr'
'--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc'
'--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib64'
'--libexecdir=/usr/libexec' '--localstatedir=/var'
'--sharedstatedir=/var/lib' '--mandir=/usr/share/man'
'--infodir=/usr/share/info' '--with-dbus' '--with-gif' '--with-jpeg'
'--with-png' '--with-rsvg' '--with-tiff' '--with-xft' '--with-xpm'
'--with-x-toolkit=gtk' 'build_alias=x86_64-redhat-linux-gnu'
'host_alias=x86_64-redhat-linux-gnu' 'CFLAGS=-DMAIL_USE_LOCKF -O2 -g
-pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
--param=ssp-buffer-size=4  -m64 -mtune=generic' 'LDFLAGS=-Wl,-z,relro ''

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: en_US.utf8
  value of $XMODIFIERS: @im=none
  locale-coding-system: utf-8-unix
  default enable-multibyte-characters: t

Major mode: Emacs-Lisp

Minor modes in effect:
  which-function-mode: t
  show-paren-mode: t
  desktop-save-mode: t
  cua-mode: t
  tooltip-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  size-indication-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent input:
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> M-e
M-e M-q M-e M-e <down> <down> <down> <down> <down>
<down> <left> <left> <left> <left> <left> <left> <left>
<left> <left> <left> ; ; C-x C-s M-e M-e M-e C-s i
s e a r c h - y a n k - f l a g C-s C-s C-s C-s C-s
C-s <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <down> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
C-s C-s C-s C-s C-s C-s C-s <up> <up> <up> <down-mouse-1>
<mouse-1> <down> <down> <down> M-x f i l <tab> l <tab>
c <tab> <return> C-h C-h C-h C-g C-g C-h v f i l l
<tab> c o l <tab> <return> C-x 1 M-e M-e M-e <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> M-e M-q <down> <down> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <backspace> <backspace> <down> <backspace>
<backspace> <backspace> <backspace> <backspace> <backspace>
<backspace> <down> C-x C-e <up> <right> <right> <right>
<right> <right> <right> <right> <right> <right> <right>
<right> <right> <right> M-8 M-8 M-8 M-8 M-8 <help-echo>
<help-echo> <help-echo> <help-echo> <help-echo> <help-echo>
<help-echo> <menu-bar> <help-menu> <send-emacs-bug
-report>

Recent messages:
Saving file /home/agrover/git/conffiles/.emacs.d/init.el...
Wrote /home/agrover/git/conffiles/.emacs.d/init.el
Mark saved where search started [2 times]
Making completion list...
Quit
Type C-x 1 to delete the help window.
my-isearch-yank-word-hook
isearch-search-and-update: Wrong type argument: arrayp, nil
Mark saved where search started
isearch-search-and-update: Wrong type argument: arrayp, nil [3 times]
isearch-search-and-update: Wrong type argument: arrayp, nil

Load-path shadows:
None found.

Features:
(shadow sort mail-extr message ecomplete rfc822 mml mml-sec
password-cache mm-decode mm-bodies mm-encode mailcap mail-parse rfc2231
rfc2047 rfc2045 qp ietf-drums mailabbrev nnheader gnus-util netrc
time-date mm-util mail-prsvr gmm-utils wid-edit mailheader canlock sha1
hex-util hashcash mail-utils emacsbug pp jka-compr find-func help-mode
view help-fns newcomment multi-isearch hideshow which-func imenu cc-mode
cc-fonts easymenu cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars
cc-defs regexp-opt hi-lock vc-git midnight swbuff ido saveplace paren
desktop cua-base cus-start cus-load tooltip ediff-hook vc-hooks
lisp-float-type mwheel x-win x-dnd font-setting tool-bar dnd fontset
image fringe lisp-mode register page menu-bar rfn-eshadow timer select
scroll-bar mldrag mouse jit-lock font-lock syntax facemenu font-core
frame cham georgian utf-8-lang misc-lang vietnamese tibetan thai
tai-viet lao korean japanese hebrew greek romanian slovak czech european
ethiopic indian cyrillic chinese case-table epa-hook jka-cmpr-hook help
simple abbrev loaddefs button minibuffer faces cus-face files
text-properties overlay md5 base64 format env code-pages mule custom
widget hashtable-print-readable backquote make-network-process dbusbind
system-font-setting font-render-setting gtk x-toolkit x multi-tty emacs)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Mon, 30 Apr 2012 00:37:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> jurta.org>
To: Andy Grover <andy <at> groveronline.com>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Mon, 30 Apr 2012 03:27:01 +0300
> However, it's saying "wrong type argument: arrayp nil" sometimes.
>
> Am I doing something wrong or is this a bug?

Well, I recommend you to call `my-isearch-yank-word-hook'
from `my-isearch-word-at-point' (after `isearch-forward-regexp')
instead of adding it to the hook `isearch-mode-hook'.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Tue, 01 May 2012 09:24:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> jurta.org>
To: Andy Grover <andy <at> groveronline.com>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Tue, 01 May 2012 12:03:41 +0300
> Hi I'm trying to use the following macro as defined on the emacs wiki:
>
> http://emacswiki.org/emacs/SearchAtPoint#toc10

Looking at how this page presents 12 ways to invent the wheel,
the question arises: why not help people with some basic functionality
in isearch.el that could be used to build commands that will
work reliably and without such problems as reported by this bug report.

ISTM, what people are trying to achieve can be divided into the
three wishes:

1. Start Isearch with an initial search string, such as the
   word/symbol at point.

   One way would be to add a new argument to all commands
   that start Isearch.  But the drawback is that there are
   too many such commands (isearch-forward, isearch-backward,
   isearch-forward-regexp etc.)

   A better method is to add a global variable
   e.g. `isearch-string-initial' that will allow the user
   to define the initial search string.

2. Yank a thing at point to the search string
   (mostly a symbol/identifier).

   This means adding more yanking commands to accompany the existing
   `isearch-yank-word', `isearch-yank-word-or-char', etc.

3. Add a new search type for symbol/identifier, similar to word search.

   First we could try to reuse the existing `isearch-word'.
   Currently `word-search-regexp' converts the search string
   to a regular expression with \b at word boundaries.
   For a symbol/identifier it could add \_< and \_>
   at symbol boundaries.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Tue, 01 May 2012 13:10:01 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 11381 <at> debbugs.gnu.org, Andy Grover <andy <at> groveronline.com>
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Tue, 01 May 2012 09:08:20 -0400
> Looking at how this page presents 12 ways to invent the wheel,
> the question arises: why not help people with some basic functionality
> in isearch.el that could be used to build commands that will
> work reliably and without such problems as reported by this bug report.

Sounds like a good idea.  To solve nb 3 (i.e. searching for a symbol),
all that's needed is to set isearch-search-fun-function, so the
mechanism is there.

The problem is that it's clunky to use because you can't just let-bind
that variable around the call to isearch-forward.  So one thing we
(c|sh)ould provide is a general way to "run isearch with the following
vars temporarily bound to these values".
Maybe simply a new function that runs isearch in a recursive-edit would
be all that's needed (so you can let-bind the vars around the call to
that function).


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Tue, 01 May 2012 15:24:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 11381 <at> debbugs.gnu.org, Andy Grover <andy <at> groveronline.com>
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Tue, 01 May 2012 18:17:02 +0300
> Sounds like a good idea.  To solve nb 3 (i.e. searching for a symbol),
> all that's needed is to set isearch-search-fun-function, so the
> mechanism is there.

`isearch-word' binds the search function to `word-search-forward'
and `word-search-backward', so perhaps new functions
`symbol-search-forward' and `symbol-search-backward'
will be necessary too.

> The problem is that it's clunky to use because you can't just let-bind
> that variable around the call to isearch-forward.  So one thing we
> (c|sh)ould provide is a general way to "run isearch with the following
> vars temporarily bound to these values".
> Maybe simply a new function that runs isearch in a recursive-edit would
> be all that's needed (so you can let-bind the vars around the call to
> that function).

Another variant to try is to set these variables in a function
added to `isearch-mode-hook'.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Tue, 15 May 2012 21:40:01 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> jurta.org>
To: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Wed, 16 May 2012 00:35:30 +0300
> `isearch-word' binds the search function to `word-search-forward'
> and `word-search-backward', so perhaps new functions
> `symbol-search-forward' and `symbol-search-backward'
> will be necessary too.

Before trying to implement `symbol-search-forward',
word-search-{for,back}ward{-lax,} need to be moved to Elisp as
Stefan asked to do for 24.2 in bug#10145.

Below is a complete patch that moves them to Elisp:

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2012-02-23 00:36:49 +0000
+++ lisp/isearch.el	2012-05-15 21:27:45 +0000
@@ -1381,6 +1393,94 @@ (defun isearch-toggle-case-fold ()
   (sit-for 1)
   (isearch-update))
 
+
+;; Word search
+
+(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', `word-search-backward',
+`word-search-forward-lax', `word-search-backward-lax'."
+  (if (string-match-p "^\\W*$" string)
+      ""
+    (concat
+     "\\b"
+     (mapconcat 'identity (split-string string "\\W+" t) "\\W+")
+     (if (or (not lax) (string-match-p "\\W$" string)) "\\b"))))
+
+(defun word-search-backward (string &optional bound noerror count)
+  "Search backward from point for STRING, ignoring differences in punctuation.
+Set point to the beginning of the occurrence found, and return point.
+An optional second argument bounds the search; it is a buffer position.
+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.
+
+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."
+  (interactive "sWord search backward: ")
+  (re-search-backward (word-search-regexp string nil) bound noerror count))
+
+(defun word-search-forward (string &optional bound noerror count)
+  "Search forward from point for STRING, ignoring differences in punctuation.
+Set point to the end of the occurrence found, and return point.
+An optional second argument bounds the search; it is a buffer position.
+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.
+
+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."
+  (interactive "sWord search: ")
+  (re-search-forward (word-search-regexp string nil) bound noerror count))
+
+(defun word-search-backward-lax (string &optional bound noerror count)
+  "Search backward from point for STRING, ignoring differences in punctuation.
+Set point to the beginning of the occurrence found, and return point.
+
+Unlike `word-search-backward', the end of STRING need not match a word
+boundary, unless STRING ends in whitespace.
+
+An optional second argument bounds the search; it is a buffer position.
+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.
+
+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."
+  (interactive "sWord search backward: ")
+  (re-search-backward (word-search-regexp string t) bound noerror count))
+
+(defun word-search-forward-lax (string &optional bound noerror count)
+  "Search forward from point for STRING, ignoring differences in punctuation.
+Set point to the end of the occurrence found, and return point.
+
+Unlike `word-search-forward', the end of STRING need not match a word
+boundary, unless STRING ends in whitespace.
+
+An optional second argument bounds the search; it is a buffer position.
+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.
+
+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."
+  (interactive "sWord search: ")
+  (re-search-forward (word-search-regexp string t) bound noerror count))
+
+
 (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

=== modified file 'src/search.c'
--- src/search.c	2012-03-27 06:46:42 +0000
+++ src/search.c	2012-05-15 21:27:00 +0000
@@ -2078,102 +2078,6 @@ (at your option) any later version.
   XSETBUFFER (last_thing_searched, current_buffer);
 }
 
-DEFUN ("word-search-regexp", Fword_search_regexp, Sword_search_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.
-
-Used in `word-search-forward', `word-search-backward',
-`word-search-forward-lax', `word-search-backward-lax'.  */)
-  (Lisp_Object string, Lisp_Object 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)
-    + ((!NILP (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 (NILP (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.
@@ -2216,86 +2120,6 @@ (at your option) any later version.
   return search_command (string, bound, noerror, count, 1, 0, 0);
 }
 
-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.
-Set point to the beginning of the occurrence found, and return point.
-An optional second argument bounds the search; it is a buffer position.
-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.
-
-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 (Fword_search_regexp (string, Qnil), bound, noerror, count, -1, 1, 0);
-}
-
-DEFUN ("word-search-forward", Fword_search_forward, Sword_search_forward, 1, 4,
-       "sWord search: ",
-       doc: /* Search forward from point for STRING, ignoring differences in punctuation.
-Set point to the end of the occurrence found, and return point.
-An optional second argument bounds the search; it is a buffer position.
-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.
-
-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 (Fword_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,
-       "sWord search backward: ",
-       doc: /* Search backward from point for STRING, ignoring differences in punctuation.
-Set point to the beginning of the occurrence found, and return point.
-
-Unlike `word-search-backward', the end of STRING need not match a word
-boundary, unless STRING ends in whitespace.
-
-An optional second argument bounds the search; it is a buffer position.
-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.
-
-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 (Fword_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,
-       "sWord search: ",
-       doc: /* Search forward from point for STRING, ignoring differences in punctuation.
-Set point to the end of the occurrence found, and return point.
-
-Unlike `word-search-forward', the end of STRING need not match a word
-boundary, unless STRING ends in whitespace.
-
-An optional second argument bounds the search; it is a buffer position.
-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.
-
-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 (Fword_search_regexp (string, Qt), bound, noerror, count, 1, 1, 0);
-}
-
 DEFUN ("re-search-backward", Fre_search_backward, Sre_search_backward, 1, 4,
        "sRE search backward: ",
        doc: /* Search backward from point for match for regular expression REGEXP.
@@ -3252,11 +3076,6 @@ (at your option) any later version.
   defsubr (&Sposix_string_match);
   defsubr (&Ssearch_forward);
   defsubr (&Ssearch_backward);
-  defsubr (&Sword_search_regexp);
-  defsubr (&Sword_search_forward);
-  defsubr (&Sword_search_backward);
-  defsubr (&Sword_search_forward_lax);
-  defsubr (&Sword_search_backward_lax);
   defsubr (&Sre_search_forward);
   defsubr (&Sre_search_backward);
   defsubr (&Sposix_search_forward);





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Wed, 16 May 2012 02:37:01 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Tue, 15 May 2012 22:35:48 -0400
> Before trying to implement `symbol-search-forward',
> word-search-{for,back}ward{-lax,} need to be moved to Elisp as
> Stefan asked to do for 24.2 in bug#10145.

> Below is a complete patch that moves them to Elisp:

Feel free to install it on the trunk, thanks,


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Thu, 17 May 2012 00:12:01 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Thu, 17 May 2012 03:08:33 +0300
>> Below is a complete patch that moves them to Elisp:
>
> Feel free to install it on the trunk, thanks,

Installed.

Regarding the addition of symbol search functions, I hesitate to define
7 more functions for every search type.  If now add
symbol-search-forward, symbol-search-backward,
symbol-search-forward-lax, symbol-search-backward-lax,
and two functions to activate the symbol search
isearch-forward-symbol, isearch-backward-symbol,
then later someone might ask to add a subword search type
with subword-search-forward, subword-search-backward,
subword-search-forward-lax, subword-search-backward-lax,
isearch-forward-subword, isearch-backward-subword,
and so on.  This will grow isearch.el unnecessarily.

When trying to achieve simplicity, all what is needed to define
for every regexp-based search type is just:

1. Define a string-to-regexp conversion function
   (like `word-search-regexp').

2. Define a key sequence to activate this search type.

This is a minimal set of requirements to define a new regexp-based
search type.

I believe a set of search filters for bug#11378
could be defined in the same simple way:

1. Define a filter predicate function
   (like `isearch-filter-visible').

2. Define a key sequence to activate this search filter.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Sun, 20 May 2012 00:33:01 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Sun, 20 May 2012 03:15:33 +0300
> Regarding the addition of symbol search functions, I hesitate to
> define 7 more functions for every search type.  If now add
> symbol-search-forward, symbol-search-backward,
> symbol-search-forward-lax, symbol-search-backward-lax,
> and two functions to activate the symbol search
> isearch-forward-symbol, isearch-backward-symbol,
> then later someone might ask to add a subword search type
> with subword-search-forward, subword-search-backward,
> subword-search-forward-lax, subword-search-backward-lax,
> isearch-forward-subword, isearch-backward-subword,
> and so on.  This will grow isearch.el unnecessarily.
>
> When trying to achieve simplicity, all what is needed to define
> for every regexp-based search type is just:
>
> 1. Define a string-to-regexp conversion function
>    (like `word-search-regexp').
>
> 2. Define a key sequence to activate this search type.
>
> This is a minimal set of requirements to define a new regexp-based
> search type.

There are more limitations that affect the design of this feature:
it would be desirable to reuse the existing search type variable
`isearch-word' because it's used in too many places like:
recording the search status in the `isearch-cmds' stack, lazy-highlighting,
external custom search functions.  And also the aim is to to reuse
4 existing functions word-search-{for,back}ward{-lax,} because they are
used in `isearch-search-fun' and some other packages that override the
default search function.

So the minimal set of changes would be like in the following patch.
It also allows adding more regexp-based search types with less changes
due to `funcall'.

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2012-05-15 21:30:58 +0000
+++ lisp/isearch.el	2012-05-20 00:14:00 +0000
@@ -512,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)
@@ -626,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.
 
@@ -732,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) 'symbol-search-regexp))
+
 (defun isearch-backward (&optional regexp-p no-recursive-edit)
   "\
 Do incremental search backward.
@@ -1379,6 +1392,13 @@ (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 'symbol-search-regexp) 'symbol-search-regexp))
+  (setq isearch-success t isearch-adjusted t)
+  (isearch-update))
+
 (defun isearch-toggle-case-fold ()
   "Toggle case folding in searching on or off."
   (interactive)
@@ -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))
 
 (defun word-search-forward (string &optional bound noerror count)
   "Search forward from point for STRING, ignoring differences in punctuation.
@@ -1440,7 +1464,11 @@ (defun word-search-forward (string &opti
 of words in STRING to a regexp used to search words without regard
 to punctuation."
   (interactive "sWord search: ")
-  (re-search-forward (word-search-regexp string nil) bound noerror count))
+  (re-search-forward
+   (if (functionp isearch-word)
+       (funcall isearch-word string nil)
+     (word-search-regexp string nil))
+   bound noerror count))
 
 (defun word-search-backward-lax (string &optional bound noerror count)
   "Search backward from point for STRING, ignoring differences in punctuation.
@@ -1459,7 +1487,11 @@ (defun word-search-backward-lax (string
 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 t) bound noerror count))
+  (re-search-backward
+   (if (functionp isearch-word)
+       (funcall isearch-word string t)
+     (word-search-regexp string t))
+   bound noerror count))
 
 (defun word-search-forward-lax (string &optional bound noerror count)
   "Search forward from point for STRING, ignoring differences in punctuation.
@@ -1478,7 +1510,23 @@ (defun word-search-forward-lax (string &
 of words in STRING to a regexp used to search words without regard
 to punctuation."
   (interactive "sWord search: ")
-  (re-search-forward (word-search-regexp string t) bound noerror count))
+  (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)) "\\_>")))
 
 
 (defun isearch-query-replace (&optional delimited regexp-flag)
@@ -1546,6 +1594,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)))))
@@ -1763,6 +1813,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)))))
@@ -2348,7 +2400,9 @@ (defun isearch-message-prefix (&optional
 			      (< (point) isearch-opoint)))
 		       "over")
 		   (if isearch-wrapped "wrapped ")
-		   (if isearch-word "word " "")
+		   (if (eq isearch-word 'symbol-search-regexp)
+		       "symbol "
+		     (if isearch-word "word " ""))
 		   (if isearch-regexp "regexp " "")
 		   (if multi-isearch-next-buffer-current-function "multi " "")
 		   (or isearch-message-prefix-add "")





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Mon, 21 May 2012 01:37:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Sun, 20 May 2012 21:36:11 -0400
> @@ -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.
 
> +		   (if (eq isearch-word 'symbol-search-regexp)
> +		       "symbol "

Comparing two functions for equality is a bad idea.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Mon, 21 May 2012 02:25:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Sun, 20 May 2012 22:23:31 -0400
>> @@ -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.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Sun, 27 May 2012 09:57:01 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Sun, 27 May 2012 12:35:20 +0300
>> +		   (if (eq isearch-word 'symbol-search-regexp)
>> +		       "symbol "
>
> Comparing two functions for equality is a bad idea.

Comparing two functions can be avoided by using properties
on function symbols like in the patch below.

The same solution of using symbol properties could be used also
for isearch filters to replace

	     (and (eq isearch-filter-predicate 'isearch-filter-visible)
		  search-invisible))

with

	     (and (symbolp isearch-filter-predicate)
                  (get isearch-filter-predicate 'visible)
		  search-invisible))
and
(put 'isearch-filter-visible 'visible t)

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2012-05-17 00:03:49 +0000
+++ lisp/isearch.el	2012-05-27 09:34:07 +0000
@@ -1468,6 +1500,20 @@ (defun word-search-forward-lax (string &
   (interactive "sWord search: ")
   (re-search-forward (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.
@@ -2329,7 +2428,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 "")




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Sun, 27 May 2012 09:57:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
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.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Mon, 28 May 2012 04:25:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Mon, 28 May 2012 00:23:10 -0400
> Comparing two functions can be avoided by using properties
> on function symbols like in the patch below.

It's not perfect, but yes, it's much better.

> The same solution of using symbol properties could be used also
> for isearch filters to replace
> 	     (and (eq isearch-filter-predicate 'isearch-filter-visible)
> 		  search-invisible))
> with
> 	     (and (symbolp isearch-filter-predicate)
>                   (get isearch-filter-predicate 'visible)
> 		  search-invisible))

Yes, that might also help allowing isearch-filter-predicate to take
a list of functions.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Mon, 28 May 2012 04:50:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Mon, 28 May 2012 00:48:19 -0400
>>>>> "Juri" == Juri Linkov <juri <at> jurta.org> writes:

>>>> @@ -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-*'.

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-").

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

> 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 we inline your defs, this turns into:

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

which can be simplified to

        (lambda (string &optional bound noerror count)
          (if isearch-forward
              (re-search-forward
               (if (functionp isearch-word)
                   (funcall isearch-word string nil)
                 (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)))

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))


-- Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Mon, 28 May 2012 09:11:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: 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





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Mon, 28 May 2012 14:10:04 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Mon, 28 May 2012 10:08:15 -0400
>> 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.

Thanks, see comments below.

>>> 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))

For the internal cases, the above should be replaced by a call to
isearch-search-fun-default.  Obviously, if there are external such
cases, we'll indeed need to additionally keep:

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

[...]
> === 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)

BTW, could you add isearch-toggle-case-fold to the M-s prefix, while
you're at it?

>  (defun Info-isearch-search ()

I think we can share even more code here with isearch.el.

But in any case, the patch looks good now, thank you,


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Mon, 28 May 2012 15:49:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: juri <at> jurta.org, 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Mon, 28 May 2012 18:44:47 +0300
> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
> Date: Mon, 28 May 2012 00:23:10 -0400
> Cc: 11381 <at> debbugs.gnu.org
> 
> > Comparing two functions can be avoided by using properties
> > on function symbols like in the patch below.
> 
> It's not perfect, but yes, it's much better.

Actually, I very much dislike this "feature" of putting properties on
function symbols, or at least the way we use it.  The problem is
documentation: there's no good place visible to users where to
document the possible values of these properties and their meanings,
so they are only documented in the code.  This makes maintenance much
harder and error-prone than it needs to be.

Look at delsel.el, for one such example.  The various uses of the
related properties, scattered through half a dozen other Lisp
packages, are completely obfuscated, and the only place you can really
understand what these properties mean is by looking at the code in
delsel.el that handles them, because even the commentary in delsel.el
leaves a lot of place for improvement.

I say, either we start documenting these properties in the doc strings
and in the manual, or we should deprecate and discourage the practice
of using them.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Mon, 28 May 2012 17:37:01 GMT) Full text and rfc822 format available.

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

From: "Drew Adams" <drew.adams <at> oracle.com>
To: "'Eli Zaretskii'" <eliz <at> gnu.org>,
	"'Stefan Monnier'" <monnier <at> iro.umontreal.ca>
Cc: 11381 <at> debbugs.gnu.org, emacs-devel <at> gnu.org
Subject: use and doc of function symbol properties [was: bug#11381: 23.3;
	isearch-search-and-update issue?]
Date: Mon, 28 May 2012 10:34:34 -0700
The question you (Eli) raise is not specific to isearch or to delsel.  The
proper place to discuss it is emacs-devel - especially if you propose to change
things.  So I'm ccing emacs-devel - but bug #11381 should be dropped from the cc
list from now on.

> Actually, I very much dislike this "feature" of putting properties on
> function symbols, or at least the way we use it.  The problem is
> documentation:

We agree that that is the problem.  It is not something else.

> there's no good place visible to users where to
> document the possible values of these properties and their meanings,
> so they are only documented in the code.

Yes.  Documentation could be improved.

But the use of symbol properties, including for function symbols, is nothing
special.  It is similar to using attributes or methods with objects in OOP.
What's sometimes missing perhaps is better documentation/discoverability.

Emacs Lisp symbols are rudimentary objects, and, yes, there is not a lot of
built-in support for discovering or navigating them - how particular properties
are used in various contexts etc.

> This makes maintenance much harder and error-prone than
> it needs to be.

If Emacs maintainers substitute basic Emacs keys/commands here and there then
they need to be aware of `delete-selection-mode' - yes.  The same is true for
other modes that users might use - whether visual lines or whatever.  Changing
one thing can affect another.

The consequence for delsel if that advice is ignored is to risk making it a
no-op in some cases: you can neuter `delete-selection-mode' if you do not pay
attention when you replace commands with new ones (e.g. in some mode).


Wrt the user, and visibility of this information:

In some cases, the user (yes, user) is an Elisp programmer, and s?he would
sometimes need to consult the code anyway, depending on what s?he wants to do.

A user of delsel can be someone who never changes such a property on any
function symbol (most users), or it can be someone who does.  For the latter, it
would probably not be necessary to consult the delsel code if the documentation
included some information that is currently only in the delsel.el Commentary.

[This is not unique to delsel.el, BTW - there are other libraries for which a
programming user must consult the Commentary in order to understand - even when
it might not be necessary to read the code itself.  IOW, there are other cases
where some of the Commentary info might fruitfully be added to the doc.

Library thingatpt.el comes to mind - e.g., the doc strings where we say "See the
file `thingatpt.el' for documentation on how to define a symbol as a valid
THING."  That's almost as long as the info in the Commentary.]

Typically, someone minimally familiar with using delsel as a programmer can
easily answer a question from a user about what's happening or how to change the
behavior.  This info could be added to the `delete-selection-mode' doc string.
The doc could include info about programming/customizing the behavior.  That
info is not a big deal IMO, either to present or to understand.

Some libraries have whole Info manuals that delve into such
programming/customization aspects.  Library delsel.el is very simple, so that
info could just be added to the doc string for the mode.  The entire Commentary
text that explains it is only a few lines long (labeled "Interface"), and that
is all that is needed, I think.

> Look at delsel.el, for one such example.  The various uses of the
> related properties, scattered through half a dozen other Lisp
> packages, are completely obfuscated, and the only place you can really
> understand what these properties mean is by looking at the code in
> delsel.el that handles them, because even the commentary in delsel.el
> leaves a lot of place for improvement.

Not sure I agree, though it is hard to disagree that the application of
properties to function symbols is scattered.  It is of course the case that the
place to look for understanding delete-selection mode is function
`delete-selection-mode'.  And it is true that today that means looking also at
the delsel.el Commentary.  Moving that info to the doc string would help.

Can you be more specific about what is missing from the Commentary in delsel.el?
It seems to me that how delsel works and how to customize the behavior is pretty
well explained there, if a bit succinctly.  What else would you like to see
documented in this regard?

> I say, either we start documenting these properties in the doc strings
> and in the manual, or we should deprecate and discourage the practice
> of using them.

OK for the former.  I disagree with the latter.  Let's not throw out the baby
with the bathwater.

I really don't think this is a big deal.  I've seen a few user questions about
delsel behavior in help-gnu-emacs over the years, and IIRC all of them had an
obvious explanation to someone familiar with the behavior of delsel (which is
quite simple).  Putting the info about that behavior into the doc string would
be helpful - and sufficient, I think.

But of course that won't stop a few "end" users from having the occasional
question because some library they picked up effectively customizes delsel
behavior without saying so.

A typical question comes from someone who already uses delsel (and who is used
to using it), who then picks up a library that changes some key bindings,
effectively replacing some commands that are handled by delsel with some
commands that are not.

This case is not a big deal.  Such a user can tell right away that something has
changed the delsel behavior, and a quick question to help-gnu-emacs - or a quick
check of the new doc string - would likely turn on the light.

But a user who has never used delsel before, and who already uses some library
that substitutes keys/commands so that delsel becomes a no-op for them, will
perhaps not understand why delsel does not seem to behave as advertised.  IOW,
trying to understand the expected vanilla behavior of delsel (having never used
it), and trying to understand a modified behavior at the same time, might be
more difficult.

But even that user, if s?he consults the new doc string, would have a good
chance of understanding the situation.

Attaching properties to Lisp function symbols in order to affect behavior is as
old as Lisp symbols themselves.  Please do not try to discourage this practice.
But it is fine to try to improve the documentation or discoverability.

[Belongs in a separate thread, at another time, but if `delete-selection-mode'
were the default (yes) then: (a) users new to Emacs would find behavior much
closer to what they are used to, and (b) Emacs developers (including 3rd-party)
would be more conscious of delsel, so would likely DTRT wrt it more often.]

(Just one opinion.)





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Mon, 28 May 2012 19:37:01 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: juri <at> jurta.org, 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Mon, 28 May 2012 15:34:35 -0400
>> > Comparing two functions can be avoided by using properties
>> > on function symbols like in the patch below.
>> It's not perfect, but yes, it's much better.
> Actually, I very much dislike this "feature" of putting properties on
> function symbols, or at least the way we use it.

Agreed, hence the "not perfect".

> I say, either we start documenting these properties in the doc strings
> and in the manual, or we should deprecate and discourage the practice
> of using them.

For delsel, I think the answer is to not use properties (which is why
I insisted we use another mechanism for the shift-select and
delete-active-region thingies).

For the case at hand, it's more difficult to fold the functionality
directly into the function (that would make us turn those functions
into object-like functions, along the lines of what we do for
completion tables).

And, I agree that the docstring of isearch-search-fun-function should
then clearly document what the `isearch-message-prefix' means.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Tue, 29 May 2012 00:37:01 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Tue, 29 May 2012 03:27:10 +0300
> And, I agree that the docstring of isearch-search-fun-function should
> then clearly document what the `isearch-message-prefix' means.

The problem is to find the right docstring to document the property.

The docstring of `isearch-search-fun-function' is about a function that
returns a search function.  But the property `isearch-message-prefix' is
put on a function that converts a string into a regexp.

So it could be documented in the docstring of `isearch-message-prefix',
but this function has no docstring (and neither `isearch-message').




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Tue, 29 May 2012 01:28:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Mon, 28 May 2012 21:26:03 -0400
>> And, I agree that the docstring of isearch-search-fun-function should
>> then clearly document what the `isearch-message-prefix' means.

> The problem is to find the right docstring to document the property.

Sorry, I mistyped.  It should be in the docstring of isearch-word, of
course, since that's the variable that will hold the function that needs
the property.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Tue, 29 May 2012 10:01:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Tue, 29 May 2012 12:49:11 +0300
> BTW, could you add isearch-toggle-case-fold to the M-s prefix, while
> you're at it?

Added.

> But in any case, the patch looks good now, thank you,

Installed, with the docstring added to `isearch-word'.

Later I'll post a patch to start Isearch with an initial search string.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#11381; Package emacs. (Tue, 29 May 2012 13:37:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 11381 <at> debbugs.gnu.org
Subject: Re: bug#11381: 23.3; isearch-search-and-update issue?
Date: Tue, 29 May 2012 09:34:57 -0400
> Installed, with the docstring added to `isearch-word'.

Thanks, Juri,


        Stefan




bug closed, send any further explanations to 11381 <at> debbugs.gnu.org and Andy Grover <andy <at> groveronline.com> Request was from Chong Yidong <cyd <at> gnu.org> to control <at> debbugs.gnu.org. (Mon, 29 Oct 2012 23:32:01 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 27 Nov 2012 12:24:03 GMT) Full text and rfc822 format available.

This bug report was last modified 11 years and 151 days ago.

Previous Next


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