GNU bug report logs - #32990
26.1.50; isearch-forward + t-m-m/mark-active doc

Previous Next

Package: emacs;

Reported by: charles <at> aurox.ch

Date: Mon, 8 Oct 2018 18:12:02 UTC

Severity: normal

Found in version 26.1.50

Fixed in version 26.2

Done: Noam Postavsky <npostavs <at> gmail.com>

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 32990 in the body.
You can then email your comments to 32990 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#32990; Package emacs. (Mon, 08 Oct 2018 18:12:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to charles <at> aurox.ch:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 08 Oct 2018 18:12:02 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: bug-gnu-emacs <at> gnu.org
Subject: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Mon, 08 Oct 2018 19:58:15 +0200
Another small change for emacs-26:

diff --git a/lisp/isearch.el b/lisp/isearch.el
index 3725779..7833a7b 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -719,6 +719,10 @@ isearch-forward
 If you try to exit with the search string still empty, it invokes
  nonincremental search.
 
+Exiting pushes the mark where point was before the search
+started, unless `transient-mark-mode' is on and the mark is
+active.
+
 Type \\[isearch-toggle-case-fold] to toggle search case-sensitivity.
 Type \\[isearch-toggle-invisible] to toggle search in invisible text.
 Type \\[isearch-toggle-regexp] to toggle regular-expression mode.


This behavior is already documented in the manual node "Basic
Isearch".




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Mon, 08 Oct 2018 20:09:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: charles <at> aurox.ch
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Mon, 08 Oct 2018 23:07:59 +0300
> Date: Mon, 08 Oct 2018 19:58:15 +0200
> From: charles <at> aurox.ch (Charles A. Roelli)
> 
> Another small change for emacs-26:
> 
> diff --git a/lisp/isearch.el b/lisp/isearch.el
> index 3725779..7833a7b 100644
> --- a/lisp/isearch.el
> +++ b/lisp/isearch.el
> @@ -719,6 +719,10 @@ isearch-forward
>  If you try to exit with the search string still empty, it invokes
>   nonincremental search.
>  
> +Exiting pushes the mark where point was before the search
> +started, unless `transient-mark-mode' is on and the mark is
> +active.
> +

Are you sure this is important to say there?  The doc string of that
function is already way beyond annoyingly long.

I'd actually encourage the opposite trend: make the doc string
shorter, and tell users to read the manual for more details.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Tue, 09 Oct 2018 18:11:01 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Tue, 09 Oct 2018 20:14:34 +0200
> Date: Mon, 08 Oct 2018 23:07:59 +0300
> From: Eli Zaretskii <eliz <at> gnu.org>
> CC: 32990 <at> debbugs.gnu.org
> 
> Are you sure this is important to say there?  The doc string of that
> function is already way beyond annoyingly long.

It is important, but see below.

> I'd actually encourage the opposite trend: make the doc string
> shorter, and tell users to read the manual for more details.

Ok, that would be better than duplicating all the details in both the
function documentation and the manual.  I will prepare a patch.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Tue, 09 Oct 2018 18:22:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: charles <at> aurox.ch
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Tue, 09 Oct 2018 21:21:02 +0300
> Date: Tue, 09 Oct 2018 20:14:34 +0200
> From: charles <at> aurox.ch (Charles A. Roelli)
> CC: 32990 <at> debbugs.gnu.org
> 
> > I'd actually encourage the opposite trend: make the doc string
> > shorter, and tell users to read the manual for more details.
> 
> Ok, that would be better than duplicating all the details in both the
> function documentation and the manual.  I will prepare a patch.

Thanks!




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sun, 14 Oct 2018 19:50:02 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sun, 14 Oct 2018 21:53:31 +0200
> Date: Tue, 09 Oct 2018 21:21:02 +0300
> From: Eli Zaretskii <eliz <at> gnu.org>
>
> > Ok, that would be better than duplicating all the details in both the
> > function documentation and the manual.  I will prepare a patch.
> 
> Thanks!

This line of isearch-forward's current docstring points to several
issues which make me uncomfortable changing or deleting it yet:

  Type DEL to cancel last input item from end of search string.

(DEL is the binding for "isearch-delete-char").

"Last input" is defined by the documentation of "isearch-delete-char"
as "the last character or the last isearch command that added or
deleted characters from the search string, moved point, toggled regexp
mode or case-sensitivity, etc.".

This definition of "last input" is not in the manual, and DEL is never
advertised to be capable of canceling regexp mode or case-sensitivity
toggling.  DEL is only advertised as being capable of "canceling the
last character of the search string" (in node "Basic Isearch") and
"canceling some C-s characters" (in node "Repeat Isearch").

For example, from emacs -Q, M-< C-s buffer M-r DEL deletes the "r" off
the search string, instead of "canceling the last input item", which I
understand should be the "M-r" regexp mode toggling.

To make matters more complicated, DEL /sometimes/ does cancel the
"last input" of a search: for example, if you have some text on your
kill ring, C-s C-y DEL undoes the yanking of the string into the
search.  (This is surprisingly sophisticated to me, and, I think,
something to document better.)

All of this makes it sound as if "isearch-delete-char" is badly named:
it is a wrapper around "isearch-pop-state", and seems to be a sort of
general (but incomplete) "undo" command for ISEARCH.  Maybe we should
name it differently and even provide a more intuitive binding for it
(on the master branch).  Its name also clashes with
"isearch-del-char".

Thus, some first steps for the emacs-26 branch could be to:

  . correct the definition of "last input item" as mentioned in the
    documentation of "isearch-delete-char"

  . name, index and fully explain "isearch-delete-char" in the Emacs
    manual

  . mention in more places how and when to use "isearch-delete-char"

If anybody can explain more about "isearch-delete-char", please do!




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Mon, 15 Oct 2018 15:03:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: charles <at> aurox.ch
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Mon, 15 Oct 2018 18:02:16 +0300
> Date: Sun, 14 Oct 2018 21:53:31 +0200
> From: charles <at> aurox.ch (Charles A. Roelli)
> CC: 32990 <at> debbugs.gnu.org
> 
> Thus, some first steps for the emacs-26 branch could be to:
> 
>   . correct the definition of "last input item" as mentioned in the
>     documentation of "isearch-delete-char"
> 
>   . name, index and fully explain "isearch-delete-char" in the Emacs
>     manual
> 
>   . mention in more places how and when to use "isearch-delete-char"

Sounds like a good plan to me, thanks.

I wouldn't rename isearch-delete-char; instead, I'd explain that what
it does is a kind of "undo", as you describe.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Tue, 16 Oct 2018 18:53:02 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Tue, 16 Oct 2018 20:57:13 +0200
> Date: Mon, 15 Oct 2018 18:02:16 +0300
> From: Eli Zaretskii <eliz <at> gnu.org>
>
> Sounds like a good plan to me, thanks.
> 
> I wouldn't rename isearch-delete-char; instead, I'd explain that what
> it does is a kind of "undo", as you describe.

Ok, how about the following?



diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index 053603e..58a7658 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -99,10 +99,18 @@ Basic Isearch
 that customize this highlighting.  The current search string is also
 displayed in the echo area.
 
-  If you make a mistake typing the search string, type @key{DEL}.
-Each @key{DEL} cancels the last character of the search string.
-@xref{Error in Isearch}, for more about dealing with unsuccessful
-search.
+@cindex isearch input item
+@cindex input item, isearch
+@findex isearch-delete-char
+@kindex DEL @r{(Incremental search)}
+  If you make a mistake typing the search string, type @key{DEL}
+(@code{isearch-delete-char}).  Each @key{DEL} cancels the last input
+item entered during the search.  Emacs records a new @dfn{input item}
+whenever you type a command that changes the search string, the
+position of point, the success or failure of the search, the direction
+of the search, the position of the other end of the current search
+result, or the ``wrappedness'' of the search.  @xref{Error in
+Isearch}, for more about dealing with unsuccessful search.
 
 @cindex exit incremental search
 @cindex incremental search, exiting
@@ -283,14 +291,15 @@ Error in Isearch
 @code{isearch-fail}.
 
   At this point, there are several things you can do.  If your string
-was mistyped, you can use @key{DEL} to erase some of it and correct
-it, or you can type @kbd{M-e} and edit it.  If you like the place you
-have found, you can type @key{RET} to remain there.  Or you can type
-@kbd{C-g}, which removes from the search string the characters that
-could not be found (the @samp{T} in @samp{FOOT}), leaving those that
-were found (the @samp{FOO} in @samp{FOOT}).  A second @kbd{C-g} at
-that point cancels the search entirely, returning point to where it
-was when the search started.
+was mistyped, use @key{DEL} to cancel a previous input item
+(@pxref{Basic Isearch}), @kbd{C-M-w} to erase one character at a time,
+or @kbd{M-e} to edit it.  If you like the place you have found, you
+can type @key{RET} to remain there.  Or you can type @kbd{C-g}, which
+removes from the search string the characters that could not be found
+(the @samp{T} in @samp{FOOT}), leaving those that were found (the
+@samp{FOO} in @samp{FOOT}).  A second @kbd{C-g} at that point cancels
+the search entirely, returning point to where it was when the search
+started.
 
 @cindex quitting (in search)
 @kindex C-g @r{(Incremental search)}
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 31571e1..40b0799 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -1956,11 +1956,14 @@ isearch-highlight-regexp
 
 
 (defun isearch-delete-char ()
-  "Discard last input item and move point back.
-Last input means the last character or the last isearch command
-that added or deleted characters from the search string,
-moved point, toggled regexp mode or case-sensitivity, etc.
-If no previous match was done, just beep."
+  "Undo last input item during a search.
+
+An input item is a command that pushes a new state of isearch (as
+recorded by the `isearch--state' structure) to `isearch-cmds'.
+Info node `Basic Isearch' explains when Emacs pushes a new
+isearch state.
+
+If no input items have been entered yet, just beep."
   (interactive)
   (if (null (cdr isearch-cmds))
       (ding)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sat, 20 Oct 2018 10:01:02 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: charles <at> aurox.ch
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sat, 20 Oct 2018 12:59:48 +0300
> Date: Tue, 16 Oct 2018 20:57:13 +0200
> From: charles <at> aurox.ch (Charles A. Roelli)
> CC: 32990 <at> debbugs.gnu.org
> 
> Ok, how about the following?

LGTM, with 2 comments:

>  (defun isearch-delete-char ()
> -  "Discard last input item and move point back.
> -Last input means the last character or the last isearch command
> -that added or deleted characters from the search string,
> -moved point, toggled regexp mode or case-sensitivity, etc.
> -If no previous match was done, just beep."
> +  "Undo last input item during a search.
> +
> +An input item is a command that pushes a new state of isearch (as

I think you meant to say that "An input item is the result of a
command that pushes a new state ...".  Right?

> +Info node `Basic Isearch' explains when Emacs pushes a new
> +isearch state.

It is better to use `(emacs)Basic Search' as a link to the manual;
that's what we do elsewhere.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Thu, 25 Oct 2018 19:06:01 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Thu, 25 Oct 2018 21:11:02 +0200
> Date: Sat, 20 Oct 2018 12:59:48 +0300
> From: Eli Zaretskii <eliz <at> gnu.org>

> > +An input item is a command that pushes a new state of isearch (as
> 
> I think you meant to say that "An input item is the result of a
> command that pushes a new state ...".  Right?

Yes.

> > +Info node `Basic Isearch' explains when Emacs pushes a new
> > +isearch state.
> 
> It is better to use `(emacs)Basic Search' as a link to the manual;
> that's what we do elsewhere.

Thanks, I've done this and pushed to emacs-26.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sun, 28 Oct 2018 10:02:02 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: eliz <at> gnu.org
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sun, 28 Oct 2018 11:06:46 +0100
The following patch improves indexing of the isearch commands and
bindings mentioned in the current docstring of isearch-forward, and
adds an explanation in the manual for one missing command
(isearch-query-replace-regexp).  This should be one of the last
changes before we can comfortably shorten isearch-forward's docstring.


----
* doc/emacs/search.texi (Basic Isearch): Index isearch-exit,
isearch-abort, isearch-cancel, isearch-repeat-forward,
isearch-repeat-backward and their bindings.
(Repeat Isearch): Index isearch-ring-advance,
isearch-ring-retreat and isearch-edit-string.
(Special Isearch): Index isearch-quote-char,
isearch-char-by-name and their bindings.  Index
isearch-query-replace and isearch-query-replace-regexp, and
the latter's binding.  Explain what
isearch-query-replace-regexp does.  Index isearch-complete.
(Word Search): Index isearch-toggle-word and its binding.
----
diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index 58a7658..9170dc2 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -114,24 +114,30 @@ Basic Isearch
 
 @cindex exit incremental search
 @cindex incremental search, exiting
+@findex isearch-exit
+@kindex RET @r{(Incremental search)}
   When you are satisfied with the place you have reached, type
-@key{RET}.  This stops searching, leaving the cursor where the search
-brought it.  Also, any command not specially meaningful in searches
-stops the searching and is then executed.  Thus, typing @kbd{C-a}
-exits the search and then moves to the beginning of the line; typing
-one of the arrow keys exits the search and performs the respective
-movement command; etc.  @key{RET} is necessary only if the next
-command you want to type is a printing character, @key{DEL},
-@key{RET}, or another character that is special within searches
-(@kbd{C-q}, @kbd{C-w}, @kbd{C-r}, @kbd{C-s}, @kbd{C-y}, @kbd{M-y},
-@kbd{M-r}, @kbd{M-c}, @kbd{M-e}, and some others described below).
-You can fine-tune the commands that exit the search; see @ref{Not
-Exiting Isearch}.
+@key{RET} (@code{isearch-exit}).  This stops searching, leaving the
+cursor where the search brought it.  Also, any command not specially
+meaningful in searches stops the searching and is then executed.
+Thus, typing @kbd{C-a} exits the search and then moves to the
+beginning of the line; typing one of the arrow keys exits the search
+and performs the respective movement command; etc.  @key{RET} is
+necessary only if the next command you want to type is a printing
+character, @key{DEL}, @key{RET}, or another character that is special
+within searches (@kbd{C-q}, @kbd{C-w}, @kbd{C-r}, @kbd{C-s},
+@kbd{C-y}, @kbd{M-y}, @kbd{M-r}, @kbd{M-c}, @kbd{M-e}, and some others
+described below).  You can fine-tune the commands that exit the
+search; see @ref{Not Exiting Isearch}.
 
   As a special exception, entering @key{RET} when the search string is
 empty launches nonincremental search (@pxref{Nonincremental Search}).
 (This can be customized; see @ref{Search Customizations}.)
 
+@findex isearch-abort
+@findex isearch-cancel
+@kindex C-g C-g @r{(Incremental Search)}
+@kindex ESC ESC ESC @r{(Incremental Search)}
   To abandon the search and return to the place where you started,
 type @kbd{@key{ESC} @key{ESC} @key{ESC}} (@code{isearch-cancel}) or
 @kbd{C-g C-g} (@code{isearch-abort}).
@@ -154,13 +160,18 @@ Basic Isearch
 @node Repeat Isearch
 @subsection Repeating Incremental Search
 
+@kindex C-s @r{(Incremental Search)}
+@kindex C-r @r{(Incremental Search)}
+@findex isearch-repeat-forward
+@findex isearch-repeat-backward
   Suppose you search forward for @samp{FOO} and find a match, but not
 the one you expected to find: the @samp{FOO} you were aiming for
-occurs later in the buffer.  In this event, type another @kbd{C-s} to
-move to the next occurrence of the search string.  You can repeat this
-any number of times.  If you overshoot, you can cancel some @kbd{C-s}
-characters with @key{DEL}.  Similarly, each @kbd{C-r} in a backward
-incremental search repeats the backward search.
+occurs later in the buffer.  In this event, type another @kbd{C-s}
+(@code{isearch-repeat-forward}) to move to the next occurrence of the
+search string.  You can repeat this any number of times.  If you
+overshoot, you can cancel some @kbd{C-s} characters with @key{DEL}.
+Similarly, each @kbd{C-r} (@code{isearch-repeat-backward}) in a
+backward incremental search repeats the backward search.
 
 @cindex lazy search highlighting
   If you pause for a little while during incremental search, Emacs
@@ -200,12 +211,15 @@ Repeat Isearch
 you have already seen.
 
 @cindex search ring
+@findex isearch-ring-advance
+@findex isearch-ring-retreat
 @kindex M-n @r{(Incremental search)}
 @kindex M-p @r{(Incremental search)}
 @vindex search-ring-max
   To reuse earlier search strings, use the @dfn{search ring}.  The
-commands @kbd{M-p} and @kbd{M-n} move through the ring to pick a
-search string to reuse.  These commands leave the selected search ring
+commands @kbd{M-p} (@code{isearch-ring-retreat}) and @kbd{M-n}
+(@code{isearch-ring-advance}) move through the ring to pick a search
+string to reuse.  These commands leave the selected search ring
 element in the minibuffer, where you can edit it.  Type
 @kbd{C-s}/@kbd{C-r} or @key{RET} to accept the string and start
 searching for it.  The number of most recently used search strings
@@ -214,14 +228,16 @@ Repeat Isearch
 
 @cindex incremental search, edit search string
 @cindex interactively edit search string
+@findex isearch-edit-string
 @kindex M-e @r{(Incremental search)}
 @kindex mouse-1 @r{in the minibuffer (Incremental Search)}
   To edit the current search string in the minibuffer without
-replacing it with items from the search ring, type @kbd{M-e} or click
-@kbd{mouse-1} in the minibuffer.  Type @key{RET}, @kbd{C-s} or
-@kbd{C-r} to finish editing the string and search for it.  Type
-@kbd{C-f} or @kbd{@key{RIGHT}} to add to the search string characters
-following point from the buffer from which you started the search.
+replacing it with items from the search ring, type @kbd{M-e}
+(@code{isearch-edit-string}) or click @kbd{mouse-1} in the minibuffer.
+Type @key{RET}, @kbd{C-s} or @kbd{C-r} to finish editing the string
+and search for it.  Type @kbd{C-f} or @kbd{@key{RIGHT}} to add to the
+search string characters following point from the buffer from which
+you started the search.
 
 @node Isearch Yank
 @subsection Isearch Yanking
@@ -357,17 +373,22 @@ Special Isearch
 
 @itemize @bullet
 @item
-Type @kbd{C-q}, followed by a non-graphic character or a sequence of
-octal digits.  This adds a character to the search string, similar to
-inserting into a buffer using @kbd{C-q} (@pxref{Inserting Text}).  For
-example, @kbd{C-q C-s} during incremental search adds the
-@samp{control-S} character to the search string.
+@findex isearch-quote-char
+@kindex C-q @r{(Incremental Search)}
+Type @kbd{C-q} (@code{isearch-quote-char}), followed by a non-graphic
+character or a sequence of octal digits.  This adds a character to the
+search string, similar to inserting into a buffer using @kbd{C-q}
+(@pxref{Inserting Text}).  For example, @kbd{C-q C-s} during
+incremental search adds the @samp{control-S} character to the search
+string.
 
 @item
-Type @kbd{C-x 8 @key{RET}}, followed by a Unicode name or code-point
-in hex.  This adds the specified character into the search string,
-similar to the usual @code{insert-char} command (@pxref{Inserting
-Text}).
+@findex isearch-char-by-name
+@kindex C-x 8 RET @r{(Incremental Search)}
+Type @kbd{C-x 8 @key{RET}} (@code{isearch-char-by-name}), followed by
+a Unicode name or code-point in hex.  This adds the specified
+character into the search string, similar to the usual
+@code{insert-char} command (@pxref{Inserting Text}).
 
 @item
 @kindex C-^ @r{(Incremental Search)}
@@ -400,12 +421,20 @@ Special Isearch
 @code{isearch-occur}, which runs @code{occur} with the current search
 string.  @xref{Other Repeating Search, occur}.
 
+@findex isearch-query-replace
+@findex isearch-query-replace-regexp
 @kindex M-% @r{(Incremental search)}
-  Typing @kbd{M-%} in incremental search invokes @code{query-replace}
-or @code{query-replace-regexp} (depending on search mode) with the
-current search string used as the string to replace.  A negative
-prefix argument means to replace backward.  @xref{Query Replace}.
-
+@kindex C-M-% @r{(Incremental search)}
+  Typing @kbd{M-%} (@code{isearch-query-replace}) in incremental
+search invokes @code{query-replace} or @code{query-replace-regexp}
+(depending on search mode) with the current search string used as the
+string to replace.  A negative prefix argument means to replace
+backward.  @xref{Query Replace}.  Typing @kbd{C-M-%}
+(@code{isearch-query-replace-regexp}) invokes
+@code{query-replace-regexp} with the current search string used as the
+regexp to replace.
+
+@findex isearch-complete
 @kindex M-TAB @r{(Incremental search)}
   Typing @kbd{M-@key{TAB}} in incremental search invokes
 @code{isearch-complete}, which attempts to complete the search string
@@ -599,15 +628,18 @@ Word Search
 Search the Web for the text in region.
 @end table
 
-@kindex M-s w
 @findex isearch-forward-word
+@findex isearch-toggle-word
+@kindex M-s w
+@kindex M-s w @r{(Incremental Search)}
   To begin a forward incremental word search, type @kbd{M-s w}.  If
 incremental search is not already active, this runs the command
 @code{isearch-forward-word}.  If incremental search is already active
-(whether a forward or backward search), @kbd{M-s w} switches to a word
-search while keeping the direction of the search and the current
-search string unchanged.  You can toggle word search back off by
-typing @kbd{M-s w} again.
+(whether a forward or backward search), @kbd{M-s w} runs the command
+@code{isearch-toggle-word}, which switches to a word search while
+keeping the direction of the search and the current search string
+unchanged.  You can toggle word search back off by typing @kbd{M-s w}
+again.
 
 @findex word-search-forward
 @findex word-search-backward




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sun, 28 Oct 2018 15:54:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: charles <at> aurox.ch
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sun, 28 Oct 2018 17:53:19 +0200
> Date: Sun, 28 Oct 2018 11:06:46 +0100
> From: charles <at> aurox.ch (Charles A. Roelli)
> CC: 32990 <at> debbugs.gnu.org
> 
> The following patch improves indexing of the isearch commands and
> bindings mentioned in the current docstring of isearch-forward, and
> adds an explanation in the manual for one missing command
> (isearch-query-replace-regexp).  This should be one of the last
> changes before we can comfortably shorten isearch-forward's docstring.

Thanks, I have a couple of minor comments:

> +search string.  You can repeat this any number of times.  If you
> +overshoot, you can cancel some @kbd{C-s} characters with @key{DEL}.
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I would say "cancel some @kbd{C-s} commands", not "characters".
"Cancel characters" sounds awkward and slightly confusing.

> +@kindex M-s w
> +@kindex M-s w @r{(Incremental Search)}

It is not useful to have several index entries starting with the same
string and pointing to the same place, or very close places.  In this
case, I think just the first one will do.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sun, 28 Oct 2018 17:10:01 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sun, 28 Oct 2018 18:09:19 +0100
> Date: Sun, 28 Oct 2018 17:53:19 +0200
> From: Eli Zaretskii <eliz <at> gnu.org>
>
> Thanks, I have a couple of minor comments:
> 
> > +search string.  You can repeat this any number of times.  If you
> > +overshoot, you can cancel some @kbd{C-s} characters with @key{DEL}.
>                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> I would say "cancel some @kbd{C-s} commands", not "characters".
> "Cancel characters" sounds awkward and slightly confusing.
> 
> > +@kindex M-s w
> > +@kindex M-s w @r{(Incremental Search)}
> 
> It is not useful to have several index entries starting with the same
> string and pointing to the same place, or very close places.  In this
> case, I think just the first one will do.

Thanks for reviewing, I pushed the change with these amendments.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sat, 10 Nov 2018 13:57:02 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: eliz <at> gnu.org
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sat, 10 Nov 2018 14:57:43 +0100
Now that we have all of the important isearch commands and bindings
indexed, we should be able to shorten isearch-forward's docstring.
The question is, how much?  Here's one attempt that may cut out too
much:

  "Do incremental search forward for a string as you type.
\\<isearch-mode-map>
\\[isearch-repeat-forward] moves forward to the next search hit.
\\[isearch-repeat-backward] moves backward to the previous search hit.
\\[isearch-abort] aborts the search and returns point to its former position.
\\[isearch-exit] exits the search and leaves point where it is.

Many other non-printing keys have special bindings while searching;
Info node `(emacs)Incremental Search' and its descendants describes
them.

If REGEXP-P is non-nil (or interactively, when called with a
prefix argument), do an incremental regular expression search
instead.

If NO-RECURSIVE-EDIT is non-nil (as it is interactively), do not
enter a recursive edit.  If nil, enter a recursive edit and
exit the recursive edit when the search is done."

It covers the absolute basics, but leaves everything else to the
manual.  I'm not sure all users will like that, since the current
docstring covers almost all of the keybindings.

I remember reading somewhere a suggestion for adding a toolbar (and
(or) a dedicated menu) for use during isearch-mode, to help the
discoverability of these myriad keybindings.  That could be a good
alternative to listing verbosely every binding in the docstring.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sat, 10 Nov 2018 14:06:02 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: charles <at> aurox.ch
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sat, 10 Nov 2018 16:05:05 +0200
> Date: Sat, 10 Nov 2018 14:57:43 +0100
> From: charles <at> aurox.ch (Charles A. Roelli)
> CC: 32990 <at> debbugs.gnu.org
> 
> Now that we have all of the important isearch commands and bindings
> indexed, we should be able to shorten isearch-forward's docstring.
> The question is, how much?  Here's one attempt that may cut out too
> much:
> 
>   "Do incremental search forward for a string as you type.
> \\<isearch-mode-map>
> \\[isearch-repeat-forward] moves forward to the next search hit.
> \\[isearch-repeat-backward] moves backward to the previous search hit.
> \\[isearch-abort] aborts the search and returns point to its former position.
> \\[isearch-exit] exits the search and leaves point where it is.
> 
> Many other non-printing keys have special bindings while searching;
> Info node `(emacs)Incremental Search' and its descendants describes
> them.
> 
> If REGEXP-P is non-nil (or interactively, when called with a
> prefix argument), do an incremental regular expression search
> instead.
> 
> If NO-RECURSIVE-EDIT is non-nil (as it is interactively), do not
> enter a recursive edit.  If nil, enter a recursive edit and
> exit the recursive edit when the search is done."

I think we should at least describe in the doc string what is
described in "Basic Isearch", which would mean adding
isearch-delete-char.  Other than that, I'm okay with this text.

> I remember reading somewhere a suggestion for adding a toolbar (and
> (or) a dedicated menu) for use during isearch-mode, to help the
> discoverability of these myriad keybindings.  That could be a good
> alternative to listing verbosely every binding in the docstring.

I agree, but we should make sure clicking the menu won't exit Isearch.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sat, 10 Nov 2018 21:59:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: charles <at> aurox.ch (Charles A. Roelli)
Cc: eliz <at> gnu.org, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sat, 10 Nov 2018 22:34:35 +0200
> Now that we have all of the important isearch commands and bindings
> indexed, we should be able to shorten isearch-forward's docstring.

We could move all the current long text from isearch-forward's
docstring to isearch-describe-mode.  Maybe better to move it
to isearch-describe-mode's docstring and then instead of current

  (describe-function 'isearch-forward)

in isearch-describe-mode call

  (describe-function 'isearch-describe-mode)

Then we could add a link to isearch-describe-mode from docstring
of isearch-forward and other isearch commands with an explanation
"For more information, see isearch-describe-mode ..."




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Thu, 15 Nov 2018 19:56:02 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Thu, 15 Nov 2018 20:57:12 +0100
> Date: Sat, 10 Nov 2018 16:05:05 +0200
> From: Eli Zaretskii <eliz <at> gnu.org>
>
> I think we should at least describe in the doc string what is
> described in "Basic Isearch", which would mean adding
> isearch-delete-char.  Other than that, I'm okay with this text.

Ok, I will add that in too.

> > I remember reading somewhere a suggestion for adding a toolbar (and
> > (or) a dedicated menu) for use during isearch-mode, to help the
> > discoverability of these myriad keybindings.  That could be a good
> > alternative to listing verbosely every binding in the docstring.
> 
> I agree, but we should make sure clicking the menu won't exit Isearch.
> 
> Thanks.

There's a first draft of a menu- and tool-bar for Isearch at the end
of this message (on branch master).  Clicking the menu items and icons
should work okay with the mouse, but I haven't yet found a way to show
the menu with either "tmm-menubar" or TTY menus, since activating
these functions will normally exit Isearch.




diff --git a/lisp/isearch.el b/lisp/isearch.el
index 035ff69..1f8a611 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -489,6 +489,142 @@ 'isearch-mode-help
 
 ;; Define isearch-mode keymap.
 
+(defvar isearch-menu-bar-map
+  (let ((map (make-sparse-keymap "Isearch")))
+    (define-key map [isearch-complete]
+      '(menu-item "Complete current search string" isearch-complete
+                  :help "Complete current search string over search history"))
+    (define-key map [isearch-complete-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-query-replace-regexp]
+      '(menu-item "Replace search string as regexp" isearch-query-replace-regexp
+                  :help "Replace matches for current search string as regexp"))
+    (define-key map [isearch-query-replace]
+      '(menu-item "Replace search string" isearch-query-replace
+                  :help "Replace matches for current search string"))
+    (define-key map [isearch-occur]
+      '(menu-item "Show all matches for search string" isearch-occur
+                  :help "Show all matches for current search string"))
+    (define-key map [isearch-highlight-regexp]
+      '(menu-item "Highlight all matches for search string"
+                  isearch-highlight-regexp
+                  :help "Highlight all matches for current search string"))
+    (define-key map [isearch-search-replace-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-toggle-specified-input-method]
+      '(menu-item "Turn on specific input method"
+                  isearch-toggle-specified-input-method
+                  :help "Turn on specific input method for search"))
+    (define-key map [isearch-toggle-input-method]
+      '(menu-item "Toggle input method" isearch-toggle-input-method
+                  :help "Toggle input method for search"))
+    (define-key map [isearch-input-method-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-char-by-name]
+      '(menu-item "Search for char by name" isearch-char-by-name
+                  :help "Search for character by name"))
+    (define-key map [isearch-quote-char]
+      '(menu-item "Search for literal char" isearch-quote-char
+                  :help "Search for literal char"))
+    (define-key map [isearch-special-char-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-toggle-word]
+      '(menu-item "Word matching" isearch-toggle-word
+                  :help "Word matching"
+                  :button (:toggle
+                           . (eq isearch-regexp-function 'word-search-regexp))))
+    (define-key map [isearch-toggle-symbol]
+      '(menu-item "Symbol matching" isearch-toggle-symbol
+                  :help "Symbol matching"
+                  :button (:toggle
+                           . (eq isearch-regexp-function
+                                 'isearch-symbol-regexp))))
+    (define-key map [isearch-toggle-regexp]
+      '(menu-item "Regexp matching" isearch-toggle-regexp
+                  :help "Regexp matching"
+                  :button (:toggle . isearch-regexp)))
+    (define-key map [isearch-toggle-invisible]
+      '(menu-item "Invisible text matching" isearch-toggle-invisible
+                  :help "Invisible text matching"
+                  :button (:toggle . isearch-invisible)))
+    (define-key map [isearch-toggle-char-fold]
+      '(menu-item "Character folding matching" isearch-toggle-char-fold
+                  :help "Character folding matching"
+                  :button (:toggle
+                           . (eq isearch-regexp-function
+                                 'char-fold-to-regexp))))
+    (define-key map [isearch-toggle-case-fold]
+      '(menu-item "Case folding matching" isearch-toggle-case-fold
+                  :help "Case folding matching"
+                  :button (:toggle . isearch-case-fold-search)))
+    (define-key map [isearch-toggle-lax-whitespace]
+      '(menu-item "Lax whitespace matching" isearch-toggle-lax-whitespace
+                  :help "Lax whitespace matching"
+                  :button (:toggle . isearch-lax-whitespace)))
+    (define-key map [isearch-toggle-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-del-char]
+      '(menu-item "Delete last character from search string" isearch-del-char
+                  :help "Delete last character from search string"))
+    (define-key map [isearch-yank-pop]
+      '(menu-item "Yank previous kill on search string" isearch-yank-pop
+                  :help "Replace yanked previous kill on search string"))
+    (define-key map [isearch-yank-kill]
+      '(menu-item "Yank current kill on search string" isearch-yank-kill
+                  :help "Append current kill to search string"))
+    (define-key map [isearch-yank-line]
+      '(menu-item "Yank rest of line on search string" isearch-yank-line
+                  :help "Yank the rest of the current line on search string"))
+    (define-key map [isearch-yank-symbol-or-char]
+      '(menu-item "Yank symbol/char on search string"
+                  isearch-yank-symbol-or-char
+                  :help "Yank next symbol or char on search string"))
+    (define-key map [isearch-yank-word-or-char]
+      '(menu-item "Yank word/char on search string"
+                  isearch-yank-word-or-char
+                  :help "Yank next word or char on search string"))
+    (define-key map [isearch-yank-char]
+      '(menu-item "Yank char on search string" isearch-yank-char
+                  :help "Yank char at point on search string"))
+    (define-key map [isearch-yank-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-edit-string]
+      '(menu-item "Edit current search string" isearch-edit-string
+                  :help "Edit current search string"))
+    (define-key map [isearch-ring-retreat]
+      '(menu-item "Edit previous search string" isearch-ring-retreat
+                  :help "Edit previous search string in Isearch history"))
+    (define-key map [isearch-ring-advance]
+      '(menu-item "Edit next search string" isearch-ring-advance
+                  :help "Edit next search string in Isearch history"))
+    (define-key map [isearch-delete-char]
+      '(menu-item "Cancel last input item" isearch-delete-char
+                  :help "Cancel the last Isearch command"))
+    (define-key map [isearch-repeat-backward]
+      '(menu-item "Repeat search backward" isearch-repeat-backward
+                  :help "Repeat current search backward"))
+    (define-key map [isearch-repeat-forward]
+      '(menu-item "Repeat search forward" isearch-repeat-forward
+                  :help "Repeat current search forward"))
+    (define-key map [isearch-nonincremental]
+      '(menu-item "Nonincremental search" isearch-exit
+                  :help "Start nonincremental search"
+                  :visible (string-equal isearch-string "")))
+    (define-key map [isearch-exit]
+      '(menu-item "Finish search" isearch-exit
+                  :help "Finish search leaving point where it is"
+                  :visible (not (string-equal isearch-string ""))))
+    (define-key map [isearch-abort]
+      '(menu-item "Remove characters not found" isearch-abort
+                  :help "Quit current search"
+                  :visible (not isearch-success)))
+    (define-key map [isearch-cancel]
+      `(menu-item "Cancel search" isearch-cancel
+                  :help "Cancel current search and return to starting point"
+                  :filter ,(lambda (binding)
+                             (if isearch-success 'isearch-abort binding))))
+    map))
+
 (defvar isearch-mode-map
   (let ((i 0)
 	(map (make-keymap)))
@@ -595,9 +731,58 @@ isearch-mode-map
     ;; characters to the search string.  See iso-transl.el.
     (define-key map "\C-x8\r" 'isearch-char-by-name)
 
+    (define-key map [menu-bar search-menu]
+      (list 'menu-item "Isearch" isearch-menu-bar-map))
+
     map)
   "Keymap for `isearch-mode'.")
 
+(defvar isearch-tool-bar-old-map nil
+  "Variable holding the old local value of `tool-bar-map', if any.")
+
+(defun isearch-tool-bar-image (image-name)
+  "Return an image specification for IMAGE-NAME."
+  (eval (tool-bar--image-expression image-name)))
+
+(defvar isearch-tool-bar-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [isearch-describe-mode]
+      (list 'menu-item "Help" 'isearch-describe-mode
+            :help "Get help for Isearch"
+            :image '(isearch-tool-bar-image "help")))
+    (define-key map [isearch-occur]
+      (list 'menu-item "Show hits" 'isearch-occur
+            :help "Show each search hit"
+            :image '(isearch-tool-bar-image "index")))
+    (define-key map [isearch-query-replace]
+      (list 'menu-item "Replace" 'isearch-query-replace
+            :help "Replace search string"
+            :image '(isearch-tool-bar-image "search-replace")))
+    (define-key map [isearch-delete-char]
+      (list 'menu-item "Undo" 'isearch-delete-char
+            :help "Undo last input item"
+            :image '(isearch-tool-bar-image "undo")))
+    (define-key map [isearch-exit]
+      (list 'menu-item "Finish" 'isearch-exit
+            :help "Finish search leaving point where it is"
+            :image '(isearch-tool-bar-image "exit")
+            :visible '(not (string-equal isearch-string ""))))
+    (define-key map [isearch-cancel]
+      (list 'menu-item "Abort" 'isearch-cancel
+            :help "Abort search"
+            :image '(isearch-tool-bar-image "close")
+            :filter (lambda (binding)
+                      (if isearch-success 'isearch-abort binding))))
+    (define-key map [isearch-repeat-forward]
+      (list 'menu-item "Repeat forward" 'isearch-repeat-forward
+            :help "Repeat search forward"
+            :image '(isearch-tool-bar-image "right-arrow")))
+    (define-key map [isearch-repeat-backward]
+      (list 'menu-item "Repeat backward" 'isearch-repeat-backward
+            :help "Repeat search backward"
+            :image '(isearch-tool-bar-image "left-arrow")))
+    map))
+
 (defvar minibuffer-local-isearch-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map minibuffer-local-map)
@@ -733,6 +918,12 @@ isearch--saved-overriding-local-map
     (nconc minor-mode-alist
 	   (list '(isearch-mode isearch-mode))))
 
+;; We add an entry for `isearch-mode' to `minor-mode-map-alist' so
+;; that `isearch-menu-bar-map' can show on the menu bar.
+(or (assq 'isearch-mode minor-mode-map-alist)
+    (nconc minor-mode-map-alist
+           (list (cons 'isearch-mode isearch-mode-map))))
+
 (defvar-local isearch-mode nil) ;; Name of the minor mode, if non-nil.
 
 (define-key global-map "\C-s" 'isearch-forward)
@@ -978,6 +1169,10 @@ isearch-mode
 	isearch-original-minibuffer-message-timeout minibuffer-message-timeout
 	minibuffer-message-timeout nil)
 
+  (if (local-variable-p 'tool-bar-map)
+      (setq isearch-tool-bar-old-map tool-bar-map))
+  (setq-local tool-bar-map isearch-tool-bar-map)
+
   ;; We must bypass input method while reading key.  When a user type
   ;; printable character, appropriate input method is turned on in
   ;; minibuffer to read multibyte characters.
@@ -1144,6 +1339,12 @@ isearch-done
       (setq input-method-function isearch-input-method-function)
     (kill-local-variable 'input-method-function))
 
+  (if isearch-tool-bar-old-map
+      (progn
+        (setq-local tool-bar-map isearch-tool-bar-old-map)
+        (setq isearch-tool-bar-old-map nil))
+    (kill-local-variable 'tool-bar-map))
+
   (force-mode-line-update)
 
   ;; If we ended in the middle of some intangible text,
@@ -2486,7 +2687,10 @@ isearch-pre-command-hook
      ;; `set-transient-map' thingy like `universal-argument--mode'.
      ((not (eq overriding-terminal-local-map isearch--saved-overriding-local-map)))
      ;; Don't exit Isearch for isearch key bindings.
-     ((commandp (lookup-key isearch-mode-map key nil)))
+     ((or (commandp (lookup-key isearch-mode-map key nil))
+          (commandp
+           (lookup-key
+            `(keymap (tool-bar menu-item nil ,isearch-tool-bar-map)) key))))
      ;; Optionally edit the search string instead of exiting.
      ((eq search-exit-option 'edit)
       (setq this-command 'isearch-edit-string))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Thu, 15 Nov 2018 20:08:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: charles <at> aurox.ch
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Thu, 15 Nov 2018 22:07:44 +0200
> Date: Thu, 15 Nov 2018 20:57:12 +0100
> From: charles <at> aurox.ch (Charles A. Roelli)
> CC: 32990 <at> debbugs.gnu.org
> 
> > I agree, but we should make sure clicking the menu won't exit Isearch.
> > 
> > Thanks.
> 
> There's a first draft of a menu- and tool-bar for Isearch at the end
> of this message (on branch master).

Thanks, I will try that later.

> Clicking the menu items and icons should work okay with the mouse,
> but I haven't yet found a way to show the menu with either
> "tmm-menubar" or TTY menus, since activating these functions will
> normally exit Isearch.

Does it work to give the respective commands a non-nil isearch-scroll
property?  I think at least the TTY menus should work even when the
TTY has no mouse.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Thu, 15 Nov 2018 22:17:01 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: charles <at> aurox.ch (Charles A. Roelli)
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Fri, 16 Nov 2018 00:15:02 +0200
> There's a first draft of a menu- and tool-bar for Isearch at the end
> of this message (on branch master).

Thanks, this was needed for a long time.  I tried it, and it looks great!

> Clicking the menu items and icons should work okay with the mouse, but
> I haven't yet found a way to show the menu with either "tmm-menubar"
> or TTY menus, since activating these functions will normally
> exit Isearch.

Eli is right.  (put 'tmm-menubar 'isearch-scroll t) did the trick.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Fri, 16 Nov 2018 08:55:02 GMT) Full text and rfc822 format available.

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

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>, "Charles A. Roelli" <charles <at> aurox.ch>
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Fri, 16 Nov 2018 09:53:43 +0100
> Eli is right.  (put 'tmm-menubar 'isearch-scroll t) did the trick.

While you're there: Is there anything we could do about Bug#8213?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Fri, 16 Nov 2018 16:01:02 GMT) Full text and rfc822 format available.

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

From: Drew Adams <drew.adams <at> oracle.com>
To: martin rudalics <rudalics <at> gmx.at>, Juri Linkov <juri <at> linkov.net>, "Charles
 A. Roelli" <charles <at> aurox.ch>
Cc: 32990 <at> debbugs.gnu.org
Subject: RE: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Fri, 16 Nov 2018 08:00:01 -0800 (PST)
>  > Eli is right.  (put 'tmm-menubar 'isearch-scroll t) did the trick.
> 
> While you're there: Is there anything we could do about Bug#8213?

Sorry for jumping in here in ignorance, but when
I follow the recipe for bug #8213 with Emacs 26
I can move the window divider with no problem.
That does exit Isearch, but that doesn't seem to
be what the bug report was about - it says that
you cannot move the divider.

I'm on Windows 10, though, not Windows 7 as in
the bug report.  And maybe I'm missing something.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Fri, 16 Nov 2018 20:21:01 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: Juri Linkov <juri <at> linkov.net>
Cc: eliz <at> gnu.org, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Fri, 16 Nov 2018 21:22:23 +0100
> From: Juri Linkov <juri <at> linkov.net>
> Date: Fri, 16 Nov 2018 00:15:02 +0200
>
> Thanks, this was needed for a long time.  I tried it, and it looks great!

Thanks for testing it.

> > Clicking the menu items and icons should work okay with the mouse, but
> > I haven't yet found a way to show the menu with either "tmm-menubar"
> > or TTY menus, since activating these functions will normally
> > exit Isearch.
> 
> Eli is right.  (put 'tmm-menubar 'isearch-scroll t) did the trick.

To see the positive effect of that statement, is setting
`isearch-allow-scroll' to t required?

For me, the following recipe still has issues, even with that line
added to the patch:

emacs -Q
M-x set-variable isearch-allow-scroll t
C-r M-` i

The "Isearch" menu should now be shown in the *Completions* window,
but instead Isearch actually searches for the character "i" in the
minibuffer.  If we can inhibit that then we should be fine.  (It looks
like Isearch is not happy about commands switching the current buffer
behind its back.)

As for the TTY menus, adding "(put 'menu-bar-open 'isearch-scroll t)"
and enabling `isearch-allow-scroll' allows use of the new menu during
Isearch from a TTY.  Thanks Eli!




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sat, 17 Nov 2018 09:30:02 GMT) Full text and rfc822 format available.

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

From: martin rudalics <rudalics <at> gmx.at>
To: Drew Adams <drew.adams <at> oracle.com>, Juri Linkov <juri <at> linkov.net>, 
 "Charles A. Roelli" <charles <at> aurox.ch>
Cc: 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sat, 17 Nov 2018 10:29:32 +0100
> Sorry for jumping in here in ignorance, but when
> I follow the recipe for bug #8213 with Emacs 26
> I can move the window divider with no problem.

Thanks for checking.  Apparently that bug was fixed in some version of
Emacs 24 and is hopefully marked as done now.

> That does exit Isearch, but that doesn't seem to
> be what the bug report was about - it says that
> you cannot move the divider.

Right.  It would be nice to be able to resize windows during Isearch
without causing the latter to exit.  That would, however, amount to a
feature request and the bug report did not ask for it.

> I'm on Windows 10, though, not Windows 7 as in
> the bug report.  And maybe I'm missing something.

Hopefully not.

Thanks again, martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sat, 17 Nov 2018 21:34:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: charles <at> aurox.ch (Charles A. Roelli)
Cc: eliz <at> gnu.org, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sat, 17 Nov 2018 23:01:40 +0200
> To see the positive effect of that statement, is setting
> `isearch-allow-scroll' to t required?

This is required as long as it's not the default.

> For me, the following recipe still has issues, even with that line
> added to the patch:
>
> emacs -Q
> M-x set-variable isearch-allow-scroll t
> C-r M-` i
>
> The "Isearch" menu should now be shown in the *Completions* window,
> but instead Isearch actually searches for the character "i" in the
> minibuffer.  If we can inhibit that then we should be fine.  (It looks
> like Isearch is not happy about commands switching the current buffer
> behind its back.)

I tried:

C-r M-` down i

and it works fine, i.e. typing an arrow key after M-`
somehow suspends the isearch mode, and you can continue
typing letters in tmm-menu.

But maybe we should suspend isearch explicitly with something like

(defun isearch-tmm ()
  (interactive)
  (with-isearch-suspended (tmm-menubar)))

(define-key isearch-mode-map "\M-`" 'isearch-tmm)

PS: I noticed that tmm menus are reversed, so you have to type `up'
key for a previous tmm-menu item, not `down' like in other menus.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sat, 17 Nov 2018 21:34:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: charles <at> aurox.ch (Charles A. Roelli)
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sat, 17 Nov 2018 23:07:58 +0200
> There's a first draft of a menu- and tool-bar for Isearch at the end
> of this message (on branch master).  Clicking the menu items and icons
> should work okay with the mouse, but I haven't yet found a way to show
> the menu with either "tmm-menubar" or TTY menus, since activating
> these functions will normally exit Isearch.

What do you think about adding also some menu to the mode-line
indicator of Isearch.  Currently clicking on the word "Isearch "
in the mode-line signals the error:

Debugger entered--Lisp error: (error #("Cannot find minor mode for ‘ Isearch’" ...
  signal(error (#("Cannot find minor mode for ‘ Isearch’" ...
  error("Cannot find minor mode for `%s'" #(" Isearch" ...
  minor-mode-menu-from-indicator(#(" Isearch" ...
  mouse-minor-mode-menu((down-mouse-1 ...
  funcall-interactively(mouse-minor-mode-menu ...
  call-interactively(mouse-minor-mode-menu nil nil)
  command-execute(mouse-minor-mode-menu)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sat, 17 Nov 2018 21:34:03 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32990 <at> debbugs.gnu.org, "Charles A. Roelli" <charles <at> aurox.ch>,
 Drew Adams <drew.adams <at> oracle.com>
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sat, 17 Nov 2018 23:32:09 +0200
>> That does exit Isearch, but that doesn't seem to
>> be what the bug report was about - it says that
>> you cannot move the divider.
>
> Right.  It would be nice to be able to resize windows during Isearch
> without causing the latter to exit.  That would, however, amount to a
> feature request and the bug report did not ask for it.

This is now implemented in master for Emacs 27.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sun, 18 Nov 2018 01:51:02 GMT) Full text and rfc822 format available.

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

From: Drew Adams <drew.adams <at> oracle.com>
To: Juri Linkov <juri <at> linkov.net>, charles <at> aurox.ch
Cc: 32990 <at> debbugs.gnu.org
Subject: RE: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sat, 17 Nov 2018 17:49:58 -0800 (PST)
> What do you think about adding also some menu to the mode-line
> indicator of Isearch.

Sure, please do.  Isearch has a lot it could add to
such a menu, including lots of toggles.

> Currently clicking on the word "Isearch "
> in the mode-line signals the error:
> 
> Debugger entered--Lisp error: (error #("Cannot find minor mode for ‘
> Isearch’" ...

I don't see that in Emacs 26 (or before) on MS Windows.
With emacs -Q, clicking there just exits Isearch.

(With Isearch+ clicking there brings up menu `Isearch',
with items `Turn off minor mode' and `Help for minor
mode'.  But that might be due to other things in my
setup, not Isearch+.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sun, 18 Nov 2018 09:24:02 GMT) Full text and rfc822 format available.

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

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32990 <at> debbugs.gnu.org, "Charles A. Roelli" <charles <at> aurox.ch>,
 Drew Adams <drew.adams <at> oracle.com>
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sun, 18 Nov 2018 10:22:54 +0100
> This is now implemented in master for Emacs 27.

Great.

Many thanks, martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sun, 18 Nov 2018 20:24:01 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: Juri Linkov <juri <at> linkov.net>
Cc: eliz <at> gnu.org, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sun, 18 Nov 2018 21:24:58 +0100
> From: Juri Linkov <juri <at> linkov.net>
> Date: Sat, 17 Nov 2018 23:07:58 +0200
> 
> > There's a first draft of a menu- and tool-bar for Isearch at the end
> > of this message (on branch master).  Clicking the menu items and icons
> > should work okay with the mouse, but I haven't yet found a way to show
> > the menu with either "tmm-menubar" or TTY menus, since activating
> > these functions will normally exit Isearch.
> 
> What do you think about adding also some menu to the mode-line
> indicator of Isearch.

Good idea, will add it in.

> 			 Currently clicking on the word "Isearch "
> in the mode-line signals the error:
> 
> Debugger entered--Lisp error: (error #("Cannot find minor mode for ‘ Isearch’" ...
>   signal(error (#("Cannot find minor mode for ‘ Isearch’" ...
>   error("Cannot find minor mode for `%s'" #(" Isearch" ...
>   minor-mode-menu-from-indicator(#(" Isearch" ...
>   mouse-minor-mode-menu((down-mouse-1 ...
>   funcall-interactively(mouse-minor-mode-menu ...
>   call-interactively(mouse-minor-mode-menu nil nil)
>   command-execute(mouse-minor-mode-menu)

Maybe "debug-on-error" is on?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sun, 18 Nov 2018 23:08:03 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: charles <at> aurox.ch (Charles A. Roelli)
Cc: eliz <at> gnu.org, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Mon, 19 Nov 2018 00:42:35 +0200
>> 			 Currently clicking on the word "Isearch "
>> in the mode-line signals the error:
>> 
>> Debugger entered--Lisp error: (error #("Cannot find minor mode for ‘ Isearch’" ...
>>   signal(error (#("Cannot find minor mode for ‘ Isearch’" ...
>>   error("Cannot find minor mode for `%s'" #(" Isearch" ...
>>   minor-mode-menu-from-indicator(#(" Isearch" ...
>>   mouse-minor-mode-menu((down-mouse-1 ...
>>   funcall-interactively(mouse-minor-mode-menu ...
>>   call-interactively(mouse-minor-mode-menu nil nil)
>>   command-execute(mouse-minor-mode-menu)
>
> Maybe "debug-on-error" is on?

Yes, this backtrace is displayed when debug-on-error is on.
And when off, one-line error is displayed in the echo area.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Mon, 19 Nov 2018 20:14:02 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: juri <at> linkov.net
Cc: eliz <at> gnu.org, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Mon, 19 Nov 2018 21:14:51 +0100
Please try the change at the end of this message.

The Isearch menu now works when clicking the mode-line indicator and
tmm-menubar (M-`)/TTY menus (F10 from TTYs) should now work as
expected (no need to set `isearch-allow-scroll' to t).

----
* lisp/tmm.el (tmm-menubar-keymap): New function factored out from
'tmm-menubar'.
(tmm-menubar): Use 'tmm-menubar-keymap'.
(tmm-prompt): New optional argument 'no-execute'.

* lisp/isearch.el: Declare the new, non-autoloaded function
'tmm-menubar-keymap'.
(isearch-tmm-menubar): New function.
(isearch-menu-bar-map): New variable.
(isearch-mode-map): Define a menu-bar search menu and remap
'tmm-menubar' bindings to point to 'isearch-tmm-menubar'.
(isearch-tool-bar-old-map): New variable.
(isearch-tool-bar-image): New function.
(isearch-tool-bar-map): New variable.
(minor-mode-alist): Add a constant mode-line indicator for Isearch
so that 'minor-mode-menu-from-indicator' works (as used when
clicking mouse-1 on the mode-line of Isearch).
(minor-mode-map-alist): Add an entry for Isearch so that
'isearch-menu-bar-map' shows during search.
(isearch-mode, isearch-done): Save and restore possible
buffer-local 'tool-bar-map'.
(isearch-pre-command-hook): Additionally allow bindings in
'isearch-tool-bar-map' to pass through, as well as commands
'isearch-tmm-menubar' and 'menu-bar-open'.
(isearch-post-command-hook): Call 'force-mode-line-update' at its
end to make sure the menu- and tool-bars are up-to-date.
----
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 87f4d49..19a03e3 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -54,6 +54,7 @@
 ;;; Code:
 
 (eval-when-compile (require 'cl-lib))
+(declare-function tmm-menubar-keymap "tmm.el")
 
 ;; Some additional options and constants.
 
@@ -489,6 +490,156 @@ 'isearch-mode-help
 
 ;; Define isearch-mode keymap.
 
+(defun isearch-tmm-menubar ()
+  "Run `tmm-menubar' while `isearch-mode' is enabled."
+  (interactive)
+  (require 'tmm)
+  (run-hooks 'menu-bar-update-hook)
+  (let ((command nil))
+    (let ((menu-bar (tmm-menubar-keymap)))
+      (with-isearch-suspended
+       (setq command (let ((isearch-mode t)) ; Show bindings from
+                                             ; `isearch-mode-map' in
+                                             ; tmm's prompt.
+                       (tmm-prompt menu-bar nil nil t)))))
+    (call-interactively command)))
+
+(defvar isearch-menu-bar-map
+  (let ((map (make-sparse-keymap "Isearch")))
+    (define-key map [isearch-complete]
+      '(menu-item "Complete current search string" isearch-complete
+                  :help "Complete current search string over search history"))
+    (define-key map [isearch-complete-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-query-replace-regexp]
+      '(menu-item "Replace search string as regexp" isearch-query-replace-regexp
+                  :help "Replace matches for current search string as regexp"))
+    (define-key map [isearch-query-replace]
+      '(menu-item "Replace search string" isearch-query-replace
+                  :help "Replace matches for current search string"))
+    (define-key map [isearch-occur]
+      '(menu-item "Show all matches for search string" isearch-occur
+                  :help "Show all matches for current search string"))
+    (define-key map [isearch-highlight-regexp]
+      '(menu-item "Highlight all matches for search string"
+                  isearch-highlight-regexp
+                  :help "Highlight all matches for current search string"))
+    (define-key map [isearch-search-replace-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-toggle-specified-input-method]
+      '(menu-item "Turn on specific input method"
+                  isearch-toggle-specified-input-method
+                  :help "Turn on specific input method for search"))
+    (define-key map [isearch-toggle-input-method]
+      '(menu-item "Toggle input method" isearch-toggle-input-method
+                  :help "Toggle input method for search"))
+    (define-key map [isearch-input-method-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-char-by-name]
+      '(menu-item "Search for char by name" isearch-char-by-name
+                  :help "Search for character by name"))
+    (define-key map [isearch-quote-char]
+      '(menu-item "Search for literal char" isearch-quote-char
+                  :help "Search for literal char"))
+    (define-key map [isearch-special-char-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-toggle-word]
+      '(menu-item "Word matching" isearch-toggle-word
+                  :help "Word matching"
+                  :button (:toggle
+                           . (eq isearch-regexp-function 'word-search-regexp))))
+    (define-key map [isearch-toggle-symbol]
+      '(menu-item "Symbol matching" isearch-toggle-symbol
+                  :help "Symbol matching"
+                  :button (:toggle
+                           . (eq isearch-regexp-function
+                                 'isearch-symbol-regexp))))
+    (define-key map [isearch-toggle-regexp]
+      '(menu-item "Regexp matching" isearch-toggle-regexp
+                  :help "Regexp matching"
+                  :button (:toggle . isearch-regexp)))
+    (define-key map [isearch-toggle-invisible]
+      '(menu-item "Invisible text matching" isearch-toggle-invisible
+                  :help "Invisible text matching"
+                  :button (:toggle . isearch-invisible)))
+    (define-key map [isearch-toggle-char-fold]
+      '(menu-item "Character folding matching" isearch-toggle-char-fold
+                  :help "Character folding matching"
+                  :button (:toggle
+                           . (eq isearch-regexp-function
+                                 'char-fold-to-regexp))))
+    (define-key map [isearch-toggle-case-fold]
+      '(menu-item "Case folding matching" isearch-toggle-case-fold
+                  :help "Case folding matching"
+                  :button (:toggle . isearch-case-fold-search)))
+    (define-key map [isearch-toggle-lax-whitespace]
+      '(menu-item "Lax whitespace matching" isearch-toggle-lax-whitespace
+                  :help "Lax whitespace matching"
+                  :button (:toggle . isearch-lax-whitespace)))
+    (define-key map [isearch-toggle-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-del-char]
+      '(menu-item "Delete last character from search string" isearch-del-char
+                  :help "Delete last character from search string"))
+    (define-key map [isearch-yank-pop]
+      '(menu-item "Yank previous kill on search string" isearch-yank-pop
+                  :help "Replace yanked previous kill on search string"))
+    (define-key map [isearch-yank-kill]
+      '(menu-item "Yank current kill on search string" isearch-yank-kill
+                  :help "Append current kill to search string"))
+    (define-key map [isearch-yank-line]
+      '(menu-item "Yank rest of line on search string" isearch-yank-line
+                  :help "Yank the rest of the current line on search string"))
+    (define-key map [isearch-yank-symbol-or-char]
+      '(menu-item "Yank symbol/char on search string"
+                  isearch-yank-symbol-or-char
+                  :help "Yank next symbol or char on search string"))
+    (define-key map [isearch-yank-word-or-char]
+      '(menu-item "Yank word/char on search string"
+                  isearch-yank-word-or-char
+                  :help "Yank next word or char on search string"))
+    (define-key map [isearch-yank-char]
+      '(menu-item "Yank char on search string" isearch-yank-char
+                  :help "Yank char at point on search string"))
+    (define-key map [isearch-yank-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-edit-string]
+      '(menu-item "Edit current search string" isearch-edit-string
+                  :help "Edit current search string"))
+    (define-key map [isearch-ring-retreat]
+      '(menu-item "Edit previous search string" isearch-ring-retreat
+                  :help "Edit previous search string in Isearch history"))
+    (define-key map [isearch-ring-advance]
+      '(menu-item "Edit next search string" isearch-ring-advance
+                  :help "Edit next search string in Isearch history"))
+    (define-key map [isearch-delete-char]
+      '(menu-item "Cancel last input item" isearch-delete-char
+                  :help "Cancel the last Isearch command"))
+    (define-key map [isearch-repeat-backward]
+      '(menu-item "Repeat search backward" isearch-repeat-backward
+                  :help "Repeat current search backward"))
+    (define-key map [isearch-repeat-forward]
+      '(menu-item "Repeat search forward" isearch-repeat-forward
+                  :help "Repeat current search forward"))
+    (define-key map [isearch-nonincremental]
+      '(menu-item "Nonincremental search" isearch-exit
+                  :help "Start nonincremental search"
+                  :visible (string-equal isearch-string "")))
+    (define-key map [isearch-exit]
+      '(menu-item "Finish search" isearch-exit
+                  :help "Finish search leaving point where it is"
+                  :visible (not (string-equal isearch-string ""))))
+    (define-key map [isearch-abort]
+      '(menu-item "Remove characters not found" isearch-abort
+                  :help "Quit current search"
+                  :visible (not isearch-success)))
+    (define-key map [isearch-cancel]
+      `(menu-item "Cancel search" isearch-cancel
+                  :help "Cancel current search and return to starting point"
+                  :filter ,(lambda (binding)
+                             (if isearch-success 'isearch-abort binding))))
+    map))
+
 (defvar isearch-mode-map
   (let ((i 0)
 	(map (make-keymap)))
@@ -595,9 +746,59 @@ isearch-mode-map
     ;; characters to the search string.  See iso-transl.el.
     (define-key map "\C-x8\r" 'isearch-char-by-name)
 
+    (define-key map [menu-bar search-menu]
+      (list 'menu-item "Isearch" isearch-menu-bar-map))
+    (define-key map [remap tmm-menubar] 'isearch-tmm-menubar)
+
     map)
   "Keymap for `isearch-mode'.")
 
+(defvar isearch-tool-bar-old-map nil
+  "Variable holding the old local value of `tool-bar-map', if any.")
+
+(defun isearch-tool-bar-image (image-name)
+  "Return an image specification for IMAGE-NAME."
+  (eval (tool-bar--image-expression image-name)))
+
+(defvar isearch-tool-bar-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [isearch-describe-mode]
+      (list 'menu-item "Help" 'isearch-describe-mode
+            :help "Get help for Isearch"
+            :image '(isearch-tool-bar-image "help")))
+    (define-key map [isearch-occur]
+      (list 'menu-item "Show hits" 'isearch-occur
+            :help "Show each search hit"
+            :image '(isearch-tool-bar-image "index")))
+    (define-key map [isearch-query-replace]
+      (list 'menu-item "Replace" 'isearch-query-replace
+            :help "Replace search string"
+            :image '(isearch-tool-bar-image "search-replace")))
+    (define-key map [isearch-delete-char]
+      (list 'menu-item "Undo" 'isearch-delete-char
+            :help "Undo last input item"
+            :image '(isearch-tool-bar-image "undo")))
+    (define-key map [isearch-exit]
+      (list 'menu-item "Finish" 'isearch-exit
+            :help "Finish search leaving point where it is"
+            :image '(isearch-tool-bar-image "exit")
+            :visible '(not (string-equal isearch-string ""))))
+    (define-key map [isearch-cancel]
+      (list 'menu-item "Abort" 'isearch-cancel
+            :help "Abort search"
+            :image '(isearch-tool-bar-image "close")
+            :filter (lambda (binding)
+                      (if isearch-success 'isearch-abort binding))))
+    (define-key map [isearch-repeat-forward]
+      (list 'menu-item "Repeat forward" 'isearch-repeat-forward
+            :help "Repeat search forward"
+            :image '(isearch-tool-bar-image "right-arrow")))
+    (define-key map [isearch-repeat-backward]
+      (list 'menu-item "Repeat backward" 'isearch-repeat-backward
+            :help "Repeat search backward"
+            :image '(isearch-tool-bar-image "left-arrow")))
+    map))
+
 (defvar minibuffer-local-isearch-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map minibuffer-local-map)
@@ -728,10 +929,18 @@ isearch--saved-overriding-local-map
 
 ;; Minor-mode-alist changes - kind of redundant with the
 ;; echo area, but if isearching in multiple windows, it can be useful.
+;; Also, clicking the mode-line indicator pops up
+;; `isearch-menu-bar-map'.
 
 (or (assq 'isearch-mode minor-mode-alist)
     (nconc minor-mode-alist
-	   (list '(isearch-mode isearch-mode))))
+	   (list '(isearch-mode " Isearch"))))
+
+;; We add an entry for `isearch-mode' to `minor-mode-map-alist' so
+;; that `isearch-menu-bar-map' can show on the menu bar.
+(or (assq 'isearch-mode minor-mode-map-alist)
+    (nconc minor-mode-map-alist
+           (list (cons 'isearch-mode isearch-mode-map))))
 
 (defvar-local isearch-mode nil) ;; Name of the minor mode, if non-nil.
 
@@ -981,6 +1190,10 @@ isearch-mode
 	isearch-original-minibuffer-message-timeout minibuffer-message-timeout
 	minibuffer-message-timeout nil)
 
+  (if (local-variable-p 'tool-bar-map)
+      (setq isearch-tool-bar-old-map tool-bar-map))
+  (setq-local tool-bar-map isearch-tool-bar-map)
+
   ;; We must bypass input method while reading key.  When a user type
   ;; printable character, appropriate input method is turned on in
   ;; minibuffer to read multibyte characters.
@@ -1147,6 +1360,12 @@ isearch-done
       (setq input-method-function isearch-input-method-function)
     (kill-local-variable 'input-method-function))
 
+  (if isearch-tool-bar-old-map
+      (progn
+        (setq-local tool-bar-map isearch-tool-bar-old-map)
+        (setq isearch-tool-bar-old-map nil))
+    (kill-local-variable 'tool-bar-map))
+
   (force-mode-line-update)
 
   ;; If we ended in the middle of some intangible text,
@@ -2500,7 +2719,12 @@ isearch-pre-command-hook
      ;; `set-transient-map' thingy like `universal-argument--mode'.
      ((not (eq overriding-terminal-local-map isearch--saved-overriding-local-map)))
      ;; Don't exit Isearch for isearch key bindings.
-     ((commandp (lookup-key isearch-mode-map key nil)))
+     ((or (commandp (lookup-key isearch-mode-map key nil))
+          (commandp
+           (lookup-key
+            `(keymap (tool-bar menu-item nil ,isearch-tool-bar-map)) key))))
+     ;; Allow key bindings that open a menubar.
+     ((memq this-command '(isearch-tmm-menubar menu-bar-open)))
      ;; Optionally edit the search string instead of exiting.
      ((eq search-exit-option 'edit)
       (setq this-command 'isearch-edit-string))
@@ -2564,7 +2788,8 @@ isearch-post-command-hook
         (when isearch-forward
           (goto-char isearch-pre-move-point))
         (isearch-search-and-update)))
-    (setq isearch-pre-move-point nil))))
+    (setq isearch-pre-move-point nil)))
+  (force-mode-line-update))
 
 (defun isearch-quote-char (&optional count)
   "Quote special characters for incremental search.
diff --git a/lisp/tmm.el b/lisp/tmm.el
index ff62774..4e3f254 100644
--- a/lisp/tmm.el
+++ b/lisp/tmm.el
@@ -42,6 +42,23 @@ tmm-km-list
 (defvar tmm-next-shortcut-digit)
 (defvar tmm-table-undef)
 
+(defun tmm-menubar-keymap ()
+  "Return the current menu-bar keymap.
+
+The ordering of the return value respects `menu-bar-final-items'."
+  (let ((menu-bar '())
+        (menu-end '()))
+    (map-keymap
+     (lambda (key binding)
+       (push (cons key binding)
+             ;; If KEY is the name of an item that we want to put last,
+             ;; move it to the end.
+             (if (memq key menu-bar-final-items)
+                 menu-end
+               menu-bar)))
+     (tmm-get-keybind [menu-bar]))
+    `(keymap ,@(nreverse menu-bar) ,@(nreverse menu-end))))
+
 ;;;###autoload (define-key global-map "\M-`" 'tmm-menubar)
 ;;;###autoload (define-key global-map [menu-bar mouse-1] 'tmm-menubar-mouse)
 
@@ -58,19 +75,8 @@ tmm-menubar
   (interactive)
   (run-hooks 'menu-bar-update-hook)
   ;; Obey menu-bar-final-items; put those items last.
-  (let ((menu-bar '())
-        (menu-end '())
+  (let ((menu-bar (tmm-menubar-keymap))
 	menu-bar-item)
-    (map-keymap
-     (lambda (key binding)
-       (push (cons key binding)
-             ;; If KEY is the name of an item that we want to put last,
-             ;; move it to the end.
-             (if (memq key menu-bar-final-items)
-                 menu-end
-               menu-bar)))
-     (tmm-get-keybind [menu-bar]))
-    (setq menu-bar `(keymap ,@(nreverse menu-bar) ,@(nreverse menu-end)))
     (if x-position
 	(let ((column 0)
               prev-key)
@@ -154,7 +160,7 @@ tmm--completion-table
 (defvar tmm--history nil)
 
 ;;;###autoload
-(defun tmm-prompt (menu &optional in-popup default-item)
+(defun tmm-prompt (menu &optional in-popup default-item no-execute)
   "Text-mode emulation of calling the bindings in keymap.
 Creates a text-mode menu of possible choices.  You can access the elements
 in the menu in two ways:
@@ -165,7 +171,9 @@ tmm-prompt
 MENU is like the MENU argument to `x-popup-menu': either a
 keymap or an alist of alists.
 DEFAULT-ITEM, if non-nil, specifies an initial default choice.
-Its value should be an event that has a binding in MENU."
+Its value should be an event that has a binding in MENU.
+NO-EXECUTE, if non-nil, means to return the command the user selects
+instead of executing it."
   ;; If the optional argument IN-POPUP is t,
   ;; then MENU is an alist of elements of the form (STRING . VALUE).
   ;; That is used for recursive calls only.
@@ -268,7 +276,7 @@ tmm-prompt
 	   ;; We just did the inner level of a -popup menu.
 	   choice)
 	  ;; We just did the outer level.  Do the inner level now.
-	  (not-menu (tmm-prompt choice t))
+	  (not-menu (tmm-prompt choice t nil no-execute))
 	  ;; We just handled a menu keymap and found another keymap.
 	  ((keymapp choice)
 	   (if (symbolp choice)
@@ -276,11 +284,11 @@ tmm-prompt
 	   (condition-case nil
 	       (require 'mouse)
 	     (error nil))
-	   (tmm-prompt choice))
+	   (tmm-prompt choice nil nil no-execute))
 	  ;; We just handled a menu keymap and found a command.
 	  (choice
 	   (if chosen-string
-	       (progn
+	       (if no-execute choice
 		 (setq last-command-event chosen-string)
 		 (call-interactively choice))
 	     choice)))))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Mon, 19 Nov 2018 22:09:01 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: charles <at> aurox.ch (Charles A. Roelli)
Cc: eliz <at> gnu.org, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Mon, 19 Nov 2018 23:44:04 +0200
> Please try the change at the end of this message.

Thanks, I tried, and have one suggestion: due to the long menu it
doesn't fit into the frame's height, so to click an item at the end of
the menu requires scrolling that takes time to scroll.  I suggest to
create more submenus, for example, a Yank submenu for all yank commands.

> The Isearch menu now works when clicking the mode-line indicator and

I tried clicking Isearch items in the mode-line indicator such as
"Repeat search forward", but it cancels Isearch (and leaves Isearch
highlighting).

> tmm-menubar (M-`)/TTY menus (F10 from TTYs) should now work as
> expected (no need to set `isearch-allow-scroll' to t).

From tmm I tried "C==>Cancel last input item DEL", but it does nothing.
Do you see the same?

>  (or (assq 'isearch-mode minor-mode-alist)
>      (nconc minor-mode-alist
> -	   (list '(isearch-mode isearch-mode))))
> +	   (list '(isearch-mode " Isearch"))))

This duplicates the constant string " Isearch" in two places.
Why this change was necessary?

> @@ -2564,7 +2788,8 @@ isearch-post-command-hook
>          (when isearch-forward
>            (goto-char isearch-pre-move-point))
>          (isearch-search-and-update)))
> -    (setq isearch-pre-move-point nil))))
> +    (setq isearch-pre-move-point nil)))
> +  (force-mode-line-update))

What problems caused adding force-mode-line-update?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Tue, 20 Nov 2018 19:48:02 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: Juri Linkov <juri <at> linkov.net>
Cc: eliz <at> gnu.org, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Tue, 20 Nov 2018 20:49:39 +0100
> From: Juri Linkov <juri <at> linkov.net>
> Date: Mon, 19 Nov 2018 23:44:04 +0200
> 
> Thanks, I tried, and have one suggestion: due to the long menu it
> doesn't fit into the frame's height, so to click an item at the end of
> the menu requires scrolling that takes time to scroll.  I suggest to
> create more submenus, for example, a Yank submenu for all yank commands.

Thanks for testing.  I made a Yank submenu as you suggest, which
makes the menu height more reasonable.

> I tried clicking Isearch items in the mode-line indicator such as
> "Repeat search forward", but it cancels Isearch (and leaves Isearch
> highlighting).

Should be fixed in the next version of the change.
(`isearch-mouse-leave-buffer' needed to allow command
`mouse-minor-mode-menu'.)

> > tmm-menubar (M-`)/TTY menus (F10 from TTYs) should now work as
> > expected (no need to set `isearch-allow-scroll' to t).
> 
> >From tmm I tried "C==>Cancel last input item DEL", but it does nothing.
> Do you see the same?

Yes.  This may be `with-isearch-suspended's doing (as used in
`isearch-tmm-menubar'): it pushes a new state of Isearch after running
its arg BODY, so we will have to compensate for that somehow.

> >  (or (assq 'isearch-mode minor-mode-alist)
> >      (nconc minor-mode-alist
> > -	   (list '(isearch-mode isearch-mode))))
> > +	   (list '(isearch-mode " Isearch"))))
> 
> This duplicates the constant string " Isearch" in two places.
> Why this change was necessary?

It's no longer necessary and will be gone from the next version of the
change.  It was necessary because clicking the Isearch mode-line
indicator was actually quitting Isearch.  Fixed by the above change to
`isearch-mouse-leave-buffer'.
 
> > @@ -2564,7 +2788,8 @@ isearch-post-command-hook
> >          (when isearch-forward
> >            (goto-char isearch-pre-move-point))
> >          (isearch-search-and-update)))
> > -    (setq isearch-pre-move-point nil))))
> > +    (setq isearch-pre-move-point nil)))
> > +  (force-mode-line-update))
> 
> What problems caused adding force-mode-line-update?

The menu- and tool-bars are not always updated after typing a
character during Isearch, so some of the items in those keymaps may be
wrongly displayed if we do not always force their recalculation.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Wed, 21 Nov 2018 20:13:01 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: juri <at> linkov.net
Cc: eliz <at> gnu.org, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Wed, 21 Nov 2018 21:14:30 +0100
> Date: Tue, 20 Nov 2018 20:49:39 +0100
> From: charles <at> aurox.ch (Charles A. Roelli)
>
> > >From tmm I tried "C==>Cancel last input item DEL", but it does nothing.
> > Do you see the same?
> 
> Yes.  This may be `with-isearch-suspended's doing (as used in
> `isearch-tmm-menubar'): it pushes a new state of Isearch after running
> its arg BODY, so we will have to compensate for that somehow.

Should be fixed in the following change based on the latest master.
In with-isearch-suspended, the state of Isearch is now only pushed if
the new state is not `equal' to the state of Isearch we had before
running the body (which should be in (car isearch-cmds), I think).


----
* lisp/tmm.el (tmm-menubar-keymap): New function factored out from
'tmm-menubar'.
(tmm-menubar): Use 'tmm-menubar-keymap'.
(tmm-prompt): New optional argument 'no-execute'.

* lisp/isearch.el: Declare the new, non-autoloaded function
'tmm-menubar-keymap'.
(isearch-tmm-menubar): New function.
(isearch-menu-bar-yank-map, isearch-menu-bar-map): New variables.
(isearch-mode-map): Define a menu-bar search menu and remap
'tmm-menubar' bindings to point to 'isearch-tmm-menubar'.
(isearch-tool-bar-old-map): New variable.
(isearch-tool-bar-image): New function.
(isearch-tool-bar-map): New variable.
(minor-mode-map-alist): Add an entry for Isearch so that
'isearch-menu-bar-map' shows during search.
(isearch-mode, isearch-done): Save and restore possible
buffer-local 'tool-bar-map' using 'isearch-tool-bar-old-map'.
(isearch-mouse-leave-buffer): Allow 'mouse-minor-mode-menu'.
(with-isearch-suspended): Only push state of Isearch if it has changed
since running the body of this macro.
(isearch-pre-command-hook): Additionally allow bindings in
'isearch-tool-bar-map' to pass through, as well as commands
'isearch-tmm-menubar', 'menu-bar-open' and
'mouse-minor-mode-menu'.
(isearch-post-command-hook): Call 'force-mode-line-update' at its
end to make sure the menu- and tool-bars are up-to-date.

----
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 6d94ef6..eb3cca7 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -54,6 +54,7 @@
 ;;; Code:
 
 (eval-when-compile (require 'cl-lib))
+(declare-function tmm-menubar-keymap "tmm.el")
 
 ;; Some additional options and constants.
 
@@ -489,6 +490,160 @@ 'isearch-mode-help
 
 ;; Define isearch-mode keymap.
 
+(defun isearch-tmm-menubar ()
+  "Run `tmm-menubar' while `isearch-mode' is enabled."
+  (interactive)
+  (require 'tmm)
+  (run-hooks 'menu-bar-update-hook)
+  (let ((command nil))
+    (let ((menu-bar (tmm-menubar-keymap)))
+      (with-isearch-suspended
+       (setq command (let ((isearch-mode t)) ; Show bindings from
+                                             ; `isearch-mode-map' in
+                                             ; tmm's prompt.
+                       (tmm-prompt menu-bar nil nil t)))))
+    (call-interactively command)))
+
+(defvar isearch-menu-bar-yank-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [isearch-yank-pop]
+      '(menu-item "Previous kill" isearch-yank-pop
+                  :help "Replace previous yanked kill on search string"))
+    (define-key map [isearch-yank-kill]
+      '(menu-item "Current kill" isearch-yank-kill
+                  :help "Append current kill to search string"))
+    (define-key map [isearch-yank-line]
+      '(menu-item "Rest of line" isearch-yank-line
+                  :help "Yank the rest of the current line on search string"))
+    (define-key map [isearch-yank-symbol-or-char]
+      '(menu-item "Symbol/char"
+                  isearch-yank-symbol-or-char
+                  :help "Yank next symbol or char on search string"))
+    (define-key map [isearch-yank-word-or-char]
+      '(menu-item "Word/char"
+                  isearch-yank-word-or-char
+                  :help "Yank next word or char on search string"))
+    (define-key map [isearch-yank-char]
+      '(menu-item "Char" isearch-yank-char
+                  :help "Yank char at point on search string"))
+    map))
+
+(defvar isearch-menu-bar-map
+  (let ((map (make-sparse-keymap "Isearch")))
+    (define-key map [isearch-complete]
+      '(menu-item "Complete current search string" isearch-complete
+                  :help "Complete current search string over search history"))
+    (define-key map [isearch-complete-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-query-replace-regexp]
+      '(menu-item "Replace search string as regexp" isearch-query-replace-regexp
+                  :help "Replace matches for current search string as regexp"))
+    (define-key map [isearch-query-replace]
+      '(menu-item "Replace search string" isearch-query-replace
+                  :help "Replace matches for current search string"))
+    (define-key map [isearch-occur]
+      '(menu-item "Show all matches for search string" isearch-occur
+                  :help "Show all matches for current search string"))
+    (define-key map [isearch-highlight-regexp]
+      '(menu-item "Highlight all matches for search string"
+                  isearch-highlight-regexp
+                  :help "Highlight all matches for current search string"))
+    (define-key map [isearch-search-replace-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-toggle-specified-input-method]
+      '(menu-item "Turn on specific input method"
+                  isearch-toggle-specified-input-method
+                  :help "Turn on specific input method for search"))
+    (define-key map [isearch-toggle-input-method]
+      '(menu-item "Toggle input method" isearch-toggle-input-method
+                  :help "Toggle input method for search"))
+    (define-key map [isearch-input-method-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-char-by-name]
+      '(menu-item "Search for char by name" isearch-char-by-name
+                  :help "Search for character by name"))
+    (define-key map [isearch-quote-char]
+      '(menu-item "Search for literal char" isearch-quote-char
+                  :help "Search for literal char"))
+    (define-key map [isearch-special-char-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-toggle-word]
+      '(menu-item "Word matching" isearch-toggle-word
+                  :help "Word matching"
+                  :button (:toggle
+                           . (eq isearch-regexp-function 'word-search-regexp))))
+    (define-key map [isearch-toggle-symbol]
+      '(menu-item "Symbol matching" isearch-toggle-symbol
+                  :help "Symbol matching"
+                  :button (:toggle
+                           . (eq isearch-regexp-function
+                                 'isearch-symbol-regexp))))
+    (define-key map [isearch-toggle-regexp]
+      '(menu-item "Regexp matching" isearch-toggle-regexp
+                  :help "Regexp matching"
+                  :button (:toggle . isearch-regexp)))
+    (define-key map [isearch-toggle-invisible]
+      '(menu-item "Invisible text matching" isearch-toggle-invisible
+                  :help "Invisible text matching"
+                  :button (:toggle . isearch-invisible)))
+    (define-key map [isearch-toggle-char-fold]
+      '(menu-item "Character folding matching" isearch-toggle-char-fold
+                  :help "Character folding matching"
+                  :button (:toggle
+                           . (eq isearch-regexp-function
+                                 'char-fold-to-regexp))))
+    (define-key map [isearch-toggle-case-fold]
+      '(menu-item "Case folding matching" isearch-toggle-case-fold
+                  :help "Case folding matching"
+                  :button (:toggle . isearch-case-fold-search)))
+    (define-key map [isearch-toggle-lax-whitespace]
+      '(menu-item "Lax whitespace matching" isearch-toggle-lax-whitespace
+                  :help "Lax whitespace matching"
+                  :button (:toggle . isearch-lax-whitespace)))
+    (define-key map [isearch-toggle-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-yank-menu]
+      `(menu-item "Yank on search string" ,isearch-menu-bar-yank-map))
+    (define-key map [isearch-edit-string]
+      '(menu-item "Edit current search string" isearch-edit-string
+                  :help "Edit current search string"))
+    (define-key map [isearch-ring-retreat]
+      '(menu-item "Edit previous search string" isearch-ring-retreat
+                  :help "Edit previous search string in Isearch history"))
+    (define-key map [isearch-ring-advance]
+      '(menu-item "Edit next search string" isearch-ring-advance
+                  :help "Edit next search string in Isearch history"))
+    (define-key map [isearch-del-char]
+      '(menu-item "Delete last char from search string" isearch-del-char
+                  :help "Delete last character from search string"))
+    (define-key map [isearch-delete-char]
+      '(menu-item "Cancel last input item" isearch-delete-char
+                  :help "Cancel the last Isearch command"))
+    (define-key map [isearch-repeat-backward]
+      '(menu-item "Repeat search backward" isearch-repeat-backward
+                  :help "Repeat current search backward"))
+    (define-key map [isearch-repeat-forward]
+      '(menu-item "Repeat search forward" isearch-repeat-forward
+                  :help "Repeat current search forward"))
+    (define-key map [isearch-nonincremental]
+      '(menu-item "Nonincremental search" isearch-exit
+                  :help "Start nonincremental search"
+                  :visible (string-equal isearch-string "")))
+    (define-key map [isearch-exit]
+      '(menu-item "Finish search" isearch-exit
+                  :help "Finish search leaving point where it is"
+                  :visible (not (string-equal isearch-string ""))))
+    (define-key map [isearch-abort]
+      '(menu-item "Remove characters not found" isearch-abort
+                  :help "Quit current search"
+                  :visible (not isearch-success)))
+    (define-key map [isearch-cancel]
+      `(menu-item "Cancel search" isearch-cancel
+                  :help "Cancel current search and return to starting point"
+                  :filter ,(lambda (binding)
+                             (if isearch-success 'isearch-abort binding))))
+    map))
+
 (defvar isearch-mode-map
   (let ((i 0)
 	(map (make-keymap)))
@@ -595,9 +750,59 @@ isearch-mode-map
     ;; characters to the search string.  See iso-transl.el.
     (define-key map "\C-x8\r" 'isearch-char-by-name)
 
+    (define-key map [menu-bar search-menu]
+      (list 'menu-item "Isearch" isearch-menu-bar-map))
+    (define-key map [remap tmm-menubar] 'isearch-tmm-menubar)
+
     map)
   "Keymap for `isearch-mode'.")
 
+(defvar isearch-tool-bar-old-map nil
+  "Variable holding the old local value of `tool-bar-map', if any.")
+
+(defun isearch-tool-bar-image (image-name)
+  "Return an image specification for IMAGE-NAME."
+  (eval (tool-bar--image-expression image-name)))
+
+(defvar isearch-tool-bar-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [isearch-describe-mode]
+      (list 'menu-item "Help" 'isearch-describe-mode
+            :help "Get help for Isearch"
+            :image '(isearch-tool-bar-image "help")))
+    (define-key map [isearch-occur]
+      (list 'menu-item "Show hits" 'isearch-occur
+            :help "Show each search hit"
+            :image '(isearch-tool-bar-image "index")))
+    (define-key map [isearch-query-replace]
+      (list 'menu-item "Replace" 'isearch-query-replace
+            :help "Replace search string"
+            :image '(isearch-tool-bar-image "search-replace")))
+    (define-key map [isearch-delete-char]
+      (list 'menu-item "Undo" 'isearch-delete-char
+            :help "Undo last input item"
+            :image '(isearch-tool-bar-image "undo")))
+    (define-key map [isearch-exit]
+      (list 'menu-item "Finish" 'isearch-exit
+            :help "Finish search leaving point where it is"
+            :image '(isearch-tool-bar-image "exit")
+            :visible '(not (string-equal isearch-string ""))))
+    (define-key map [isearch-cancel]
+      (list 'menu-item "Abort" 'isearch-cancel
+            :help "Abort search"
+            :image '(isearch-tool-bar-image "close")
+            :filter (lambda (binding)
+                      (if isearch-success 'isearch-abort binding))))
+    (define-key map [isearch-repeat-forward]
+      (list 'menu-item "Repeat forward" 'isearch-repeat-forward
+            :help "Repeat search forward"
+            :image '(isearch-tool-bar-image "right-arrow")))
+    (define-key map [isearch-repeat-backward]
+      (list 'menu-item "Repeat backward" 'isearch-repeat-backward
+            :help "Repeat search backward"
+            :image '(isearch-tool-bar-image "left-arrow")))
+    map))
+
 (defvar minibuffer-local-isearch-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map minibuffer-local-map)
@@ -728,11 +933,19 @@ isearch--saved-overriding-local-map
 
 ;; Minor-mode-alist changes - kind of redundant with the
 ;; echo area, but if isearching in multiple windows, it can be useful.
+;; Also, clicking the mode-line indicator pops up
+;; `isearch-menu-bar-map'.
 
 (or (assq 'isearch-mode minor-mode-alist)
     (nconc minor-mode-alist
 	   (list '(isearch-mode isearch-mode))))
 
+;; We add an entry for `isearch-mode' to `minor-mode-map-alist' so
+;; that `isearch-menu-bar-map' can show on the menu bar.
+(or (assq 'isearch-mode minor-mode-map-alist)
+    (nconc minor-mode-map-alist
+           (list (cons 'isearch-mode isearch-mode-map))))
+
 (defvar-local isearch-mode nil) ;; Name of the minor mode, if non-nil.
 
 (define-key global-map "\C-s" 'isearch-forward)
@@ -981,6 +1194,10 @@ isearch-mode
 	isearch-original-minibuffer-message-timeout minibuffer-message-timeout
 	minibuffer-message-timeout nil)
 
+  (if (local-variable-p 'tool-bar-map)
+      (setq isearch-tool-bar-old-map tool-bar-map))
+  (setq-local tool-bar-map isearch-tool-bar-map)
+
   ;; We must bypass input method while reading key.  When a user type
   ;; printable character, appropriate input method is turned on in
   ;; minibuffer to read multibyte characters.
@@ -1147,6 +1364,12 @@ isearch-done
       (setq input-method-function isearch-input-method-function)
     (kill-local-variable 'input-method-function))
 
+  (if isearch-tool-bar-old-map
+      (progn
+        (setq-local tool-bar-map isearch-tool-bar-old-map)
+        (setq isearch-tool-bar-old-map nil))
+    (kill-local-variable 'tool-bar-map))
+
   (force-mode-line-update)
 
   ;; If we ended in the middle of some intangible text,
@@ -1181,7 +1404,8 @@ isearch-done
 
 (defun isearch-mouse-leave-buffer ()
   "Exit Isearch unless the mouse command is allowed in Isearch."
-  (unless (eq (get this-command 'isearch-scroll) t)
+  (unless (or (eq this-command 'mouse-minor-mode-menu)
+              (eq (get this-command 'isearch-scroll) t))
     (isearch-done)))
 
 (defun isearch-update-ring (string &optional regexp)
@@ -1449,7 +1673,9 @@ with-isearch-suspended
 
 	;; Reinvoke the pending search.
 	(isearch-search)
-	(isearch-push-state)		; this pushes the correct state
+        (unless (and isearch-cmds
+                     (equal (car isearch-cmds) (isearch--get-state)))
+          (isearch-push-state))        ; this pushes the correct state
 	(isearch-update)
 	(if isearch-nonincremental
 	    (progn
@@ -2535,7 +2761,14 @@ isearch-pre-command-hook
      ;; `set-transient-map' thingy like `universal-argument--mode'.
      ((not (eq overriding-terminal-local-map isearch--saved-overriding-local-map)))
      ;; Don't exit Isearch for isearch key bindings.
-     ((commandp (lookup-key isearch-mode-map key nil)))
+     ((or (commandp (lookup-key isearch-mode-map key nil))
+          (commandp
+           (lookup-key
+            `(keymap (tool-bar menu-item nil ,isearch-tool-bar-map)) key))))
+     ;; Allow key bindings that open a menubar.
+     ((memq this-command '(isearch-tmm-menubar
+                           menu-bar-open
+                           mouse-minor-mode-menu)))
      ;; Optionally edit the search string instead of exiting.
      ((eq search-exit-option 'edit)
       (setq this-command 'isearch-edit-string))
@@ -2599,7 +2832,8 @@ isearch-post-command-hook
         (when isearch-forward
           (goto-char isearch-pre-move-point))
         (isearch-search-and-update)))
-    (setq isearch-pre-move-point nil))))
+    (setq isearch-pre-move-point nil)))
+  (force-mode-line-update))
 
 (defun isearch-quote-char (&optional count)
   "Quote special characters for incremental search.
diff --git a/lisp/tmm.el b/lisp/tmm.el
index ff62774..4e3f254 100644
--- a/lisp/tmm.el
+++ b/lisp/tmm.el
@@ -42,6 +42,23 @@ tmm-km-list
 (defvar tmm-next-shortcut-digit)
 (defvar tmm-table-undef)
 
+(defun tmm-menubar-keymap ()
+  "Return the current menu-bar keymap.
+
+The ordering of the return value respects `menu-bar-final-items'."
+  (let ((menu-bar '())
+        (menu-end '()))
+    (map-keymap
+     (lambda (key binding)
+       (push (cons key binding)
+             ;; If KEY is the name of an item that we want to put last,
+             ;; move it to the end.
+             (if (memq key menu-bar-final-items)
+                 menu-end
+               menu-bar)))
+     (tmm-get-keybind [menu-bar]))
+    `(keymap ,@(nreverse menu-bar) ,@(nreverse menu-end))))
+
 ;;;###autoload (define-key global-map "\M-`" 'tmm-menubar)
 ;;;###autoload (define-key global-map [menu-bar mouse-1] 'tmm-menubar-mouse)
 
@@ -58,19 +75,8 @@ tmm-menubar
   (interactive)
   (run-hooks 'menu-bar-update-hook)
   ;; Obey menu-bar-final-items; put those items last.
-  (let ((menu-bar '())
-        (menu-end '())
+  (let ((menu-bar (tmm-menubar-keymap))
 	menu-bar-item)
-    (map-keymap
-     (lambda (key binding)
-       (push (cons key binding)
-             ;; If KEY is the name of an item that we want to put last,
-             ;; move it to the end.
-             (if (memq key menu-bar-final-items)
-                 menu-end
-               menu-bar)))
-     (tmm-get-keybind [menu-bar]))
-    (setq menu-bar `(keymap ,@(nreverse menu-bar) ,@(nreverse menu-end)))
     (if x-position
 	(let ((column 0)
               prev-key)
@@ -154,7 +160,7 @@ tmm--completion-table
 (defvar tmm--history nil)
 
 ;;;###autoload
-(defun tmm-prompt (menu &optional in-popup default-item)
+(defun tmm-prompt (menu &optional in-popup default-item no-execute)
   "Text-mode emulation of calling the bindings in keymap.
 Creates a text-mode menu of possible choices.  You can access the elements
 in the menu in two ways:
@@ -165,7 +171,9 @@ tmm-prompt
 MENU is like the MENU argument to `x-popup-menu': either a
 keymap or an alist of alists.
 DEFAULT-ITEM, if non-nil, specifies an initial default choice.
-Its value should be an event that has a binding in MENU."
+Its value should be an event that has a binding in MENU.
+NO-EXECUTE, if non-nil, means to return the command the user selects
+instead of executing it."
   ;; If the optional argument IN-POPUP is t,
   ;; then MENU is an alist of elements of the form (STRING . VALUE).
   ;; That is used for recursive calls only.
@@ -268,7 +276,7 @@ tmm-prompt
 	   ;; We just did the inner level of a -popup menu.
 	   choice)
 	  ;; We just did the outer level.  Do the inner level now.
-	  (not-menu (tmm-prompt choice t))
+	  (not-menu (tmm-prompt choice t nil no-execute))
 	  ;; We just handled a menu keymap and found another keymap.
 	  ((keymapp choice)
 	   (if (symbolp choice)
@@ -276,11 +284,11 @@ tmm-prompt
 	   (condition-case nil
 	       (require 'mouse)
 	     (error nil))
-	   (tmm-prompt choice))
+	   (tmm-prompt choice nil nil no-execute))
 	  ;; We just handled a menu keymap and found a command.
 	  (choice
 	   (if chosen-string
-	       (progn
+	       (if no-execute choice
 		 (setq last-command-event chosen-string)
 		 (call-interactively choice))
 	     choice)))))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Wed, 21 Nov 2018 22:45:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: charles <at> aurox.ch (Charles A. Roelli)
Cc: eliz <at> gnu.org, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Thu, 22 Nov 2018 00:31:45 +0200
>> > >From tmm I tried "C==>Cancel last input item DEL", but it does nothing.
>> > Do you see the same?
>> 
>> Yes.  This may be `with-isearch-suspended's doing (as used in
>> `isearch-tmm-menubar'): it pushes a new state of Isearch after running
>> its arg BODY, so we will have to compensate for that somehow.
>
> Should be fixed in the following change based on the latest master.
> In with-isearch-suspended, the state of Isearch is now only pushed if
> the new state is not `equal' to the state of Isearch we had before
> running the body (which should be in (car isearch-cmds), I think).

Thanks, I tested your new version and have a few suggestions:

1. There are two menu items with the same action word "Cancel":
"Cancel search"
"Cancel last input item"

This is confusing terminology.  I suggest to rename the latter to
"Undo last input item"

2. Hard-coding command symbols with '(memq this-command ...' is
not a good style.  Isearch provides a special feature to put the
property 'isearch-scroll' (a misnomer, unfortunately) for the purpose
to not hard-code command symbols.

3. Please add a comment to with-isearch-suspended stating that pushing
a new state is not necessary for cases that don't change search
parameters.  So that such commands that use with-isearch-suspended
don't need special code to restore an old value of isearch-cmds.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Thu, 22 Nov 2018 20:28:02 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: Juri Linkov <juri <at> linkov.net>
Cc: eliz <at> gnu.org, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Thu, 22 Nov 2018 21:29:25 +0100
> From: Juri Linkov <juri <at> linkov.net>
> Date: Thu, 22 Nov 2018 00:31:45 +0200
>
> Thanks, I tested your new version and have a few suggestions:
> 
> 1. There are two menu items with the same action word "Cancel":
> "Cancel search"
> "Cancel last input item"
> 
> This is confusing terminology.  I suggest to rename the latter to
> "Undo last input item"

Done, thanks.

> 2. Hard-coding command symbols with '(memq this-command ...' is
> not a good style.  

I've consolidated the list of commands into
'isearch-menu-bar-commands' (list of commands that can open a menu bar
during Isearch).  I also updated 'isearch-mouse-leave-buffer' to allow
commands listed in new var 'isearch-mouse-commands' (list of mouse
commands allowed during Isearch).

> 		     Isearch provides a special feature to put the
> property 'isearch-scroll' (a misnomer, unfortunately) for the purpose
> to not hard-code command symbols.

'isearch-scroll' does not work on 'isearch-tmm-menubar' since
'isearch-tmm-menubar' runs arbitrary Isearch commands and can
therefore move point, which violates 'isearch-scroll's main
requirement.
 
> 3. Please add a comment to with-isearch-suspended stating that pushing
> a new state is not necessary for cases that don't change search
> parameters.  So that such commands that use with-isearch-suspended
> don't need special code to restore an old value of isearch-cmds.

Done, thanks.  I'm attaching the latest change again.



----
* lisp/tmm.el (tmm-menubar-keymap): New function factored out from
'tmm-menubar'.
(tmm-menubar): Use 'tmm-menubar-keymap'.
(tmm-prompt): New optional argument 'no-execute'.

* lisp/isearch.el: Declare the new, non-autoloaded function
'tmm-menubar-keymap'.
(isearch-tmm-menubar): New function.
(isearch-menu-bar-commands): New variable.
(isearch-menu-bar-yank-map, isearch-menu-bar-map): New variables.
(isearch-mode-map): Define a menu-bar search menu and remap
'tmm-menubar' bindings to point to 'isearch-tmm-menubar'.
(isearch-tool-bar-old-map): New variable.
(isearch-tool-bar-image): New function.
(isearch-tool-bar-map): New variable.
(minor-mode-map-alist): Add an entry for Isearch so that
'isearch-menu-bar-map' shows during search.
(isearch-mode, isearch-done): Save and restore possible
buffer-local 'tool-bar-map' using 'isearch-tool-bar-old-map'.
(iseacrh-mouse-commands): New variable.
(isearch-mouse-leave-buffer): Allow commands in
isearch-mouse-commands.
(with-isearch-suspended): Only push changed states of Isearch
after running the body argument of this macro.
(isearch-pre-command-hook): Additionally allow bindings in
'isearch-tool-bar-map' to pass through, as well as commands
in isearch-menu-bar-commands.
(isearch-post-command-hook): Call 'force-mode-line-update' at its
end to make sure the menu- and tool-bars are up-to-date.

----
diff --git a/lisp/isearch.el b/lisp/isearch.el
index b05805c..15f66ee 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -54,6 +54,7 @@
 ;;; Code:
 
 (eval-when-compile (require 'cl-lib))
+(declare-function tmm-menubar-keymap "tmm.el")
 
 ;; Some additional options and constants.
 
@@ -489,6 +490,164 @@ 'isearch-mode-help
 
 ;; Define isearch-mode keymap.
 
+(defun isearch-tmm-menubar ()
+  "Run `tmm-menubar' while `isearch-mode' is enabled."
+  (interactive)
+  (require 'tmm)
+  (run-hooks 'menu-bar-update-hook)
+  (let ((command nil))
+    (let ((menu-bar (tmm-menubar-keymap)))
+      (with-isearch-suspended
+       (setq command (let ((isearch-mode t)) ; Show bindings from
+                                             ; `isearch-mode-map' in
+                                             ; tmm's prompt.
+                       (tmm-prompt menu-bar nil nil t)))))
+    (call-interactively command)))
+
+(defvar isearch-menu-bar-commands
+  '(isearch-tmm-menubar menu-bar-open mouse-minor-mode-menu)
+  "List of commands that can open a menu during Isearch.")
+
+(defvar isearch-menu-bar-yank-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [isearch-yank-pop]
+      '(menu-item "Previous kill" isearch-yank-pop
+                  :help "Replace previous yanked kill on search string"))
+    (define-key map [isearch-yank-kill]
+      '(menu-item "Current kill" isearch-yank-kill
+                  :help "Append current kill to search string"))
+    (define-key map [isearch-yank-line]
+      '(menu-item "Rest of line" isearch-yank-line
+                  :help "Yank the rest of the current line on search string"))
+    (define-key map [isearch-yank-symbol-or-char]
+      '(menu-item "Symbol/char"
+                  isearch-yank-symbol-or-char
+                  :help "Yank next symbol or char on search string"))
+    (define-key map [isearch-yank-word-or-char]
+      '(menu-item "Word/char"
+                  isearch-yank-word-or-char
+                  :help "Yank next word or char on search string"))
+    (define-key map [isearch-yank-char]
+      '(menu-item "Char" isearch-yank-char
+                  :help "Yank char at point on search string"))
+    map))
+
+(defvar isearch-menu-bar-map
+  (let ((map (make-sparse-keymap "Isearch")))
+    (define-key map [isearch-complete]
+      '(menu-item "Complete current search string" isearch-complete
+                  :help "Complete current search string over search history"))
+    (define-key map [isearch-complete-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-query-replace-regexp]
+      '(menu-item "Replace search string as regexp" isearch-query-replace-regexp
+                  :help "Replace matches for current search string as regexp"))
+    (define-key map [isearch-query-replace]
+      '(menu-item "Replace search string" isearch-query-replace
+                  :help "Replace matches for current search string"))
+    (define-key map [isearch-occur]
+      '(menu-item "Show all matches for search string" isearch-occur
+                  :help "Show all matches for current search string"))
+    (define-key map [isearch-highlight-regexp]
+      '(menu-item "Highlight all matches for search string"
+                  isearch-highlight-regexp
+                  :help "Highlight all matches for current search string"))
+    (define-key map [isearch-search-replace-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-toggle-specified-input-method]
+      '(menu-item "Turn on specific input method"
+                  isearch-toggle-specified-input-method
+                  :help "Turn on specific input method for search"))
+    (define-key map [isearch-toggle-input-method]
+      '(menu-item "Toggle input method" isearch-toggle-input-method
+                  :help "Toggle input method for search"))
+    (define-key map [isearch-input-method-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-char-by-name]
+      '(menu-item "Search for char by name" isearch-char-by-name
+                  :help "Search for character by name"))
+    (define-key map [isearch-quote-char]
+      '(menu-item "Search for literal char" isearch-quote-char
+                  :help "Search for literal char"))
+    (define-key map [isearch-special-char-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-toggle-word]
+      '(menu-item "Word matching" isearch-toggle-word
+                  :help "Word matching"
+                  :button (:toggle
+                           . (eq isearch-regexp-function 'word-search-regexp))))
+    (define-key map [isearch-toggle-symbol]
+      '(menu-item "Symbol matching" isearch-toggle-symbol
+                  :help "Symbol matching"
+                  :button (:toggle
+                           . (eq isearch-regexp-function
+                                 'isearch-symbol-regexp))))
+    (define-key map [isearch-toggle-regexp]
+      '(menu-item "Regexp matching" isearch-toggle-regexp
+                  :help "Regexp matching"
+                  :button (:toggle . isearch-regexp)))
+    (define-key map [isearch-toggle-invisible]
+      '(menu-item "Invisible text matching" isearch-toggle-invisible
+                  :help "Invisible text matching"
+                  :button (:toggle . isearch-invisible)))
+    (define-key map [isearch-toggle-char-fold]
+      '(menu-item "Character folding matching" isearch-toggle-char-fold
+                  :help "Character folding matching"
+                  :button (:toggle
+                           . (eq isearch-regexp-function
+                                 'char-fold-to-regexp))))
+    (define-key map [isearch-toggle-case-fold]
+      '(menu-item "Case folding matching" isearch-toggle-case-fold
+                  :help "Case folding matching"
+                  :button (:toggle . isearch-case-fold-search)))
+    (define-key map [isearch-toggle-lax-whitespace]
+      '(menu-item "Lax whitespace matching" isearch-toggle-lax-whitespace
+                  :help "Lax whitespace matching"
+                  :button (:toggle . isearch-lax-whitespace)))
+    (define-key map [isearch-toggle-separator]
+      '(menu-item "--"))
+    (define-key map [isearch-yank-menu]
+      `(menu-item "Yank on search string" ,isearch-menu-bar-yank-map))
+    (define-key map [isearch-edit-string]
+      '(menu-item "Edit current search string" isearch-edit-string
+                  :help "Edit current search string"))
+    (define-key map [isearch-ring-retreat]
+      '(menu-item "Edit previous search string" isearch-ring-retreat
+                  :help "Edit previous search string in Isearch history"))
+    (define-key map [isearch-ring-advance]
+      '(menu-item "Edit next search string" isearch-ring-advance
+                  :help "Edit next search string in Isearch history"))
+    (define-key map [isearch-del-char]
+      '(menu-item "Delete last char from search string" isearch-del-char
+                  :help "Delete last character from search string"))
+    (define-key map [isearch-delete-char]
+      '(menu-item "Undo last input item" isearch-delete-char
+                  :help "Undo the effect of the last Isearch command"))
+    (define-key map [isearch-repeat-backward]
+      '(menu-item "Repeat search backward" isearch-repeat-backward
+                  :help "Repeat current search backward"))
+    (define-key map [isearch-repeat-forward]
+      '(menu-item "Repeat search forward" isearch-repeat-forward
+                  :help "Repeat current search forward"))
+    (define-key map [isearch-nonincremental]
+      '(menu-item "Nonincremental search" isearch-exit
+                  :help "Start nonincremental search"
+                  :visible (string-equal isearch-string "")))
+    (define-key map [isearch-exit]
+      '(menu-item "Finish search" isearch-exit
+                  :help "Finish search leaving point where it is"
+                  :visible (not (string-equal isearch-string ""))))
+    (define-key map [isearch-abort]
+      '(menu-item "Remove characters not found" isearch-abort
+                  :help "Quit current search"
+                  :visible (not isearch-success)))
+    (define-key map [isearch-cancel]
+      `(menu-item "Cancel search" isearch-cancel
+                  :help "Cancel current search and return to starting point"
+                  :filter ,(lambda (binding)
+                             (if isearch-success 'isearch-abort binding))))
+    map))
+
 (defvar isearch-mode-map
   (let ((i 0)
 	(map (make-keymap)))
@@ -595,9 +754,59 @@ isearch-mode-map
     ;; characters to the search string.  See iso-transl.el.
     (define-key map "\C-x8\r" 'isearch-char-by-name)
 
+    (define-key map [menu-bar search-menu]
+      (list 'menu-item "Isearch" isearch-menu-bar-map))
+    (define-key map [remap tmm-menubar] 'isearch-tmm-menubar)
+
     map)
   "Keymap for `isearch-mode'.")
 
+(defvar isearch-tool-bar-old-map nil
+  "Variable holding the old local value of `tool-bar-map', if any.")
+
+(defun isearch-tool-bar-image (image-name)
+  "Return an image specification for IMAGE-NAME."
+  (eval (tool-bar--image-expression image-name)))
+
+(defvar isearch-tool-bar-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [isearch-describe-mode]
+      (list 'menu-item "Help" 'isearch-describe-mode
+            :help "Get help for Isearch"
+            :image '(isearch-tool-bar-image "help")))
+    (define-key map [isearch-occur]
+      (list 'menu-item "Show hits" 'isearch-occur
+            :help "Show each search hit"
+            :image '(isearch-tool-bar-image "index")))
+    (define-key map [isearch-query-replace]
+      (list 'menu-item "Replace" 'isearch-query-replace
+            :help "Replace search string"
+            :image '(isearch-tool-bar-image "search-replace")))
+    (define-key map [isearch-delete-char]
+      (list 'menu-item "Undo" 'isearch-delete-char
+            :help "Undo last input item"
+            :image '(isearch-tool-bar-image "undo")))
+    (define-key map [isearch-exit]
+      (list 'menu-item "Finish" 'isearch-exit
+            :help "Finish search leaving point where it is"
+            :image '(isearch-tool-bar-image "exit")
+            :visible '(not (string-equal isearch-string ""))))
+    (define-key map [isearch-cancel]
+      (list 'menu-item "Abort" 'isearch-cancel
+            :help "Abort search"
+            :image '(isearch-tool-bar-image "close")
+            :filter (lambda (binding)
+                      (if isearch-success 'isearch-abort binding))))
+    (define-key map [isearch-repeat-forward]
+      (list 'menu-item "Repeat forward" 'isearch-repeat-forward
+            :help "Repeat search forward"
+            :image '(isearch-tool-bar-image "right-arrow")))
+    (define-key map [isearch-repeat-backward]
+      (list 'menu-item "Repeat backward" 'isearch-repeat-backward
+            :help "Repeat search backward"
+            :image '(isearch-tool-bar-image "left-arrow")))
+    map))
+
 (defvar minibuffer-local-isearch-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map minibuffer-local-map)
@@ -728,11 +937,19 @@ isearch--saved-overriding-local-map
 
 ;; Minor-mode-alist changes - kind of redundant with the
 ;; echo area, but if isearching in multiple windows, it can be useful.
+;; Also, clicking the mode-line indicator pops up
+;; `isearch-menu-bar-map'.
 
 (or (assq 'isearch-mode minor-mode-alist)
     (nconc minor-mode-alist
 	   (list '(isearch-mode isearch-mode))))
 
+;; We add an entry for `isearch-mode' to `minor-mode-map-alist' so
+;; that `isearch-menu-bar-map' can show on the menu bar.
+(or (assq 'isearch-mode minor-mode-map-alist)
+    (nconc minor-mode-map-alist
+           (list (cons 'isearch-mode isearch-mode-map))))
+
 (defvar-local isearch-mode nil) ;; Name of the minor mode, if non-nil.
 
 (define-key global-map "\C-s" 'isearch-forward)
@@ -986,6 +1203,10 @@ isearch-mode
 	isearch-original-minibuffer-message-timeout minibuffer-message-timeout
 	minibuffer-message-timeout nil)
 
+  (if (local-variable-p 'tool-bar-map)
+      (setq isearch-tool-bar-old-map tool-bar-map))
+  (setq-local tool-bar-map isearch-tool-bar-map)
+
   ;; We must bypass input method while reading key.  When a user type
   ;; printable character, appropriate input method is turned on in
   ;; minibuffer to read multibyte characters.
@@ -1152,6 +1373,12 @@ isearch-done
       (setq input-method-function isearch-input-method-function)
     (kill-local-variable 'input-method-function))
 
+  (if isearch-tool-bar-old-map
+      (progn
+        (setq-local tool-bar-map isearch-tool-bar-old-map)
+        (setq isearch-tool-bar-old-map nil))
+    (kill-local-variable 'tool-bar-map))
+
   (force-mode-line-update)
 
   ;; If we ended in the middle of some intangible text,
@@ -1184,9 +1411,17 @@ isearch-done
 
   (and (not edit) isearch-recursive-edit (exit-recursive-edit)))
 
+(defvar isearch-mouse-commands '(mouse-minor-mode-menu)
+  "List of mouse commands that are allowed during Isearch.")
+
 (defun isearch-mouse-leave-buffer ()
-  "Exit Isearch unless the mouse command is allowed in Isearch."
-  (unless (eq (get this-command 'isearch-scroll) t)
+  "Exit Isearch unless the mouse command is allowed in Isearch.
+
+Mouse commands are allowed in Isearch if they have a non-nil
+`isearch-scroll' property or if they are listed in
+`isearch-mouse-commands'."
+  (unless (or (memq this-command isearch-mouse-commands)
+              (eq (get this-command 'isearch-scroll) t))
     (isearch-done)))
 
 (defun isearch-update-ring (string &optional regexp)
@@ -1454,7 +1689,11 @@ with-isearch-suspended
 
 	;; Reinvoke the pending search.
 	(isearch-search)
-	(isearch-push-state)		; this pushes the correct state
+        ;; If no code has changed the search parameters, then pushing
+        ;; a new state of Isearch should not be necessary.
+        (unless (and isearch-cmds
+                     (equal (car isearch-cmds) (isearch--get-state)))
+          (isearch-push-state))        ; this pushes the correct state
 	(isearch-update)
 	(if isearch-nonincremental
 	    (progn
@@ -2540,7 +2779,12 @@ isearch-pre-command-hook
      ;; `set-transient-map' thingy like `universal-argument--mode'.
      ((not (eq overriding-terminal-local-map isearch--saved-overriding-local-map)))
      ;; Don't exit Isearch for isearch key bindings.
-     ((commandp (lookup-key isearch-mode-map key nil)))
+     ((or (commandp (lookup-key isearch-mode-map key nil))
+          (commandp
+           (lookup-key
+            `(keymap (tool-bar menu-item nil ,isearch-tool-bar-map)) key))))
+     ;; Allow key bindings that open a menubar.
+     ((memq this-command isearch-menu-bar-commands))
      ;; Optionally edit the search string instead of exiting.
      ((eq search-exit-option 'edit)
       (setq this-command 'isearch-edit-string))
@@ -2604,7 +2848,8 @@ isearch-post-command-hook
         (when isearch-forward
           (goto-char isearch-pre-move-point))
         (isearch-search-and-update)))
-    (setq isearch-pre-move-point nil))))
+    (setq isearch-pre-move-point nil)))
+  (force-mode-line-update))
 
 (defun isearch-quote-char (&optional count)
   "Quote special characters for incremental search.
diff --git a/lisp/tmm.el b/lisp/tmm.el
index ff62774..4e3f254 100644
--- a/lisp/tmm.el
+++ b/lisp/tmm.el
@@ -42,6 +42,23 @@ tmm-km-list
 (defvar tmm-next-shortcut-digit)
 (defvar tmm-table-undef)
 
+(defun tmm-menubar-keymap ()
+  "Return the current menu-bar keymap.
+
+The ordering of the return value respects `menu-bar-final-items'."
+  (let ((menu-bar '())
+        (menu-end '()))
+    (map-keymap
+     (lambda (key binding)
+       (push (cons key binding)
+             ;; If KEY is the name of an item that we want to put last,
+             ;; move it to the end.
+             (if (memq key menu-bar-final-items)
+                 menu-end
+               menu-bar)))
+     (tmm-get-keybind [menu-bar]))
+    `(keymap ,@(nreverse menu-bar) ,@(nreverse menu-end))))
+
 ;;;###autoload (define-key global-map "\M-`" 'tmm-menubar)
 ;;;###autoload (define-key global-map [menu-bar mouse-1] 'tmm-menubar-mouse)
 
@@ -58,19 +75,8 @@ tmm-menubar
   (interactive)
   (run-hooks 'menu-bar-update-hook)
   ;; Obey menu-bar-final-items; put those items last.
-  (let ((menu-bar '())
-        (menu-end '())
+  (let ((menu-bar (tmm-menubar-keymap))
 	menu-bar-item)
-    (map-keymap
-     (lambda (key binding)
-       (push (cons key binding)
-             ;; If KEY is the name of an item that we want to put last,
-             ;; move it to the end.
-             (if (memq key menu-bar-final-items)
-                 menu-end
-               menu-bar)))
-     (tmm-get-keybind [menu-bar]))
-    (setq menu-bar `(keymap ,@(nreverse menu-bar) ,@(nreverse menu-end)))
     (if x-position
 	(let ((column 0)
               prev-key)
@@ -154,7 +160,7 @@ tmm--completion-table
 (defvar tmm--history nil)
 
 ;;;###autoload
-(defun tmm-prompt (menu &optional in-popup default-item)
+(defun tmm-prompt (menu &optional in-popup default-item no-execute)
   "Text-mode emulation of calling the bindings in keymap.
 Creates a text-mode menu of possible choices.  You can access the elements
 in the menu in two ways:
@@ -165,7 +171,9 @@ tmm-prompt
 MENU is like the MENU argument to `x-popup-menu': either a
 keymap or an alist of alists.
 DEFAULT-ITEM, if non-nil, specifies an initial default choice.
-Its value should be an event that has a binding in MENU."
+Its value should be an event that has a binding in MENU.
+NO-EXECUTE, if non-nil, means to return the command the user selects
+instead of executing it."
   ;; If the optional argument IN-POPUP is t,
   ;; then MENU is an alist of elements of the form (STRING . VALUE).
   ;; That is used for recursive calls only.
@@ -268,7 +276,7 @@ tmm-prompt
 	   ;; We just did the inner level of a -popup menu.
 	   choice)
 	  ;; We just did the outer level.  Do the inner level now.
-	  (not-menu (tmm-prompt choice t))
+	  (not-menu (tmm-prompt choice t nil no-execute))
 	  ;; We just handled a menu keymap and found another keymap.
 	  ((keymapp choice)
 	   (if (symbolp choice)
@@ -276,11 +284,11 @@ tmm-prompt
 	   (condition-case nil
 	       (require 'mouse)
 	     (error nil))
-	   (tmm-prompt choice))
+	   (tmm-prompt choice nil nil no-execute))
 	  ;; We just handled a menu keymap and found a command.
 	  (choice
 	   (if chosen-string
-	       (progn
+	       (if no-execute choice
 		 (setq last-command-event chosen-string)
 		 (call-interactively choice))
 	     choice)))))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Thu, 22 Nov 2018 22:05:01 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: charles <at> aurox.ch (Charles A. Roelli)
Cc: eliz <at> gnu.org, 32990 <at> debbugs.gnu.org
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Thu, 22 Nov 2018 23:59:53 +0200
> Done, thanks.  I'm attaching the latest change again.

Thanks for these changes.  I tried again and it works great.
Please push your patch unless Eli has more comments.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Fri, 23 Nov 2018 08:18:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32990 <at> debbugs.gnu.org, charles <at> aurox.ch
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Fri, 23 Nov 2018 10:17:14 +0200
> From: Juri Linkov <juri <at> linkov.net>
> Cc: eliz <at> gnu.org,  32990 <at> debbugs.gnu.org
> Date: Thu, 22 Nov 2018 23:59:53 +0200
> 
> > Done, thanks.  I'm attaching the latest change again.
> 
> Thanks for these changes.  I tried again and it works great.
> Please push your patch unless Eli has more comments.

No further comments from me, thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sat, 24 Nov 2018 11:23:02 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 32990 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sat, 24 Nov 2018 12:25:01 +0100
> Date: Fri, 23 Nov 2018 10:17:14 +0200
> From: Eli Zaretskii <eliz <at> gnu.org>
> CC: charles <at> aurox.ch, 32990 <at> debbugs.gnu.org
> 
> > From: Juri Linkov <juri <at> linkov.net>
> > Cc: eliz <at> gnu.org,  32990 <at> debbugs.gnu.org
> > Date: Thu, 22 Nov 2018 23:59:53 +0200
> > 
> > > Done, thanks.  I'm attaching the latest change again.
> > 
> > Thanks for these changes.  I tried again and it works great.
> > Please push your patch unless Eli has more comments.
> 
> No further comments from me, thanks.

Thanks for reviewing.  Should I also add a NEWS entry, as follows?



diff --git a/etc/NEWS b/etc/NEWS
index f413bbe..a822704 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -687,6 +687,9 @@ the shift key.
 *** Isearch now remembers the regexp-based search mode for words/symbols
 and case-sensitivity together with search strings in the search ring.
 
+---
+*** Isearch now has its own tool-bar and menu-bar menu.
+
 ** Debugger
 
 +++




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sat, 24 Nov 2018 11:46:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: charles <at> aurox.ch
Cc: 32990 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sat, 24 Nov 2018 13:44:50 +0200
> Date: Sat, 24 Nov 2018 12:25:01 +0100
> From: charles <at> aurox.ch (Charles A. Roelli)
> CC: juri <at> linkov.net, 32990 <at> debbugs.gnu.org
> 
> Thanks for reviewing.  Should I also add a NEWS entry, as follows?
> 
> 
> 
> diff --git a/etc/NEWS b/etc/NEWS
> index f413bbe..a822704 100644
> --- a/etc/NEWS
> +++ b/etc/NEWS
> @@ -687,6 +687,9 @@ the shift key.
>  *** Isearch now remembers the regexp-based search mode for words/symbols
>  and case-sensitivity together with search strings in the search ring.
>  
> +---
> +*** Isearch now has its own tool-bar and menu-bar menu.
> +

LGTM, thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Sat, 24 Nov 2018 12:50:01 GMT) Full text and rfc822 format available.

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

From: charles <at> aurox.ch (Charles A. Roelli)
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 32990 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Sat, 24 Nov 2018 13:51:31 +0100
> Date: Sat, 24 Nov 2018 13:44:50 +0200
> From: Eli Zaretskii <eliz <at> gnu.org>
> 
> > diff --git a/etc/NEWS b/etc/NEWS
> > index f413bbe..a822704 100644
> > --- a/etc/NEWS
> > +++ b/etc/NEWS
> > @@ -687,6 +687,9 @@ the shift key.
> >  *** Isearch now remembers the regexp-based search mode for words/symbols
> >  and case-sensitivity together with search strings in the search ring.
> >  
> > +---
> > +*** Isearch now has its own tool-bar and menu-bar menu.
> > +
> 
> LGTM, thanks.

Great, it's now pushed.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32990; Package emacs. (Tue, 02 Apr 2019 00:23:02 GMT) Full text and rfc822 format available.

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

From: Noam Postavsky <npostavs <at> gmail.com>
To: charles <at> aurox.ch (Charles A. Roelli)
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32990 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#32990: 26.1.50; isearch-forward + t-m-m/mark-active doc
Date: Mon, 01 Apr 2019 20:22:07 -0400
close 32990 26.2
quit

charles <at> aurox.ch (Charles A. Roelli) writes:
>
> Great, it's now pushed.

Sounds like this is finished, closing.





bug marked as fixed in version 26.2, send any further explanations to 32990 <at> debbugs.gnu.org and charles <at> aurox.ch Request was from Noam Postavsky <npostavs <at> gmail.com> to control <at> debbugs.gnu.org. (Tue, 02 Apr 2019 00:23:04 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, 30 Apr 2019 11:24:06 GMT) Full text and rfc822 format available.

This bug report was last modified 4 years and 363 days ago.

Previous Next


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