unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* move to fail position in Isearch edit
@ 2008-11-11  6:42 Drew Adams
  2008-11-11  7:13 ` Mathias Dahl
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Drew Adams @ 2008-11-11  6:42 UTC (permalink / raw)
  To: emacs-devel

Any interest in this? I bind it to `M-e' in `minibuffer-local-isearch-map', so
`M-e M-e' puts the cursor at the match failure position. 

If you type a search string quickly and mistype a char or two, this lets you
correct the typo without discarding and retyping the rest of the search string:
`M-e M-e <corrections> C-s'.

(defun isearch-goto-success-end ()
    "Go to end of search string text that matches."
    (interactive)
    (goto-char (point-max))
    (let ((cmds  isearch-cmds)
          succ-msg)
      (when (or (not isearch-success) isearch-error)
        (while (or (not (isearch-success-state (car cmds))) 
                   (isearch-error-state (car cmds)))
          (pop cmds))
        (setq succ-msg  (and cmds (isearch-message-state (car cmds))))
        (backward-char (- (length isearch-string) (length succ-msg))))))

(define-key minibuffer-local-isearch-map 
            "\M-e" 'isearchp-goto-success-end)





^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: move to fail position in Isearch edit
  2008-11-11  6:42 move to fail position in Isearch edit Drew Adams
@ 2008-11-11  7:13 ` Mathias Dahl
  2008-11-11 15:07 ` Isearch: always try to find longest successful prefix [was: move to fail position in Isearch edit] Drew Adams
  2008-11-11 17:33 ` move to fail position in Isearch edit Juri Linkov
  2 siblings, 0 replies; 10+ messages in thread
From: Mathias Dahl @ 2008-11-11  7:13 UTC (permalink / raw)
  To: Drew Adams, emacs-devel

It sounds very useful. I know I would like it since I do these kinds
of errors myself.

2008/11/11, Drew Adams <drew.adams@oracle.com>:
> Any interest in this? I bind it to `M-e' in `minibuffer-local-isearch-map',
> so
> `M-e M-e' puts the cursor at the match failure position.
>
> If you type a search string quickly and mistype a char or two, this lets you
> correct the typo without discarding and retyping the rest of the search
> string:
> `M-e M-e <corrections> C-s'.
>
> (defun isearch-goto-success-end ()
>     "Go to end of search string text that matches."
>     (interactive)
>     (goto-char (point-max))
>     (let ((cmds  isearch-cmds)
>           succ-msg)
>       (when (or (not isearch-success) isearch-error)
>         (while (or (not (isearch-success-state (car cmds)))
>                    (isearch-error-state (car cmds)))
>           (pop cmds))
>         (setq succ-msg  (and cmds (isearch-message-state (car cmds))))
>         (backward-char (- (length isearch-string) (length succ-msg))))))
>
> (define-key minibuffer-local-isearch-map
>             "\M-e" 'isearchp-goto-success-end)
>
>
>
>




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Isearch: always try to find longest successful prefix [was: move to fail position in Isearch edit]
  2008-11-11  6:42 move to fail position in Isearch edit Drew Adams
  2008-11-11  7:13 ` Mathias Dahl
@ 2008-11-11 15:07 ` Drew Adams
  2008-11-11 17:32   ` Juri Linkov
  2008-11-11 17:33 ` move to fail position in Isearch edit Juri Linkov
  2 siblings, 1 reply; 10+ messages in thread
From: Drew Adams @ 2008-11-11 15:07 UTC (permalink / raw)
  To: emacs-devel

I suggested this:

> Any interest in this? I bind it to `M-e' in 
> `minibuffer-local-isearch-map', so `M-e M-e' puts the
> cursor at the match failure position. 
> 
> If you type a search string quickly and mistype a char or 
> two, this lets you correct the typo without discarding
> and retyping the rest of the search string:
> `M-e M-e <corrections> C-s'.
> 
> (defun isearch-goto-success-end ()
>     "Go to end of search string text that matches."
>     (interactive)
>     (goto-char (point-max))
>     (let ((cmds  isearch-cmds)
>           succ-msg)
>       (when (or (not isearch-success) isearch-error)
>         (while (or (not (isearch-success-state (car cmds))) 
>                    (isearch-error-state (car cmds)))
>           (pop cmds))
>         (setq succ-msg  (and cmds (isearch-message-state (car cmds))))
>         (backward-char (- (length isearch-string)
>                           (length succ-msg))))))
> 
> (define-key minibuffer-local-isearch-map 
>             "\M-e" 'isearchp-goto-success-end)

You'll notice that this would be a lot handier if Isearch always started out
(and resumed after Isearch edit) by treating the search string incrementally.

For example, suppose you search again with a previous search string `aaxbbb' by
hitting `C-s C-s' in a buffer where there is no match for `aaxbbb' but there are
matches for `aa'.

Isearch fails immediately, showing the entire search string, `aaxbbb', as a
failed match by highlighting it. If, however, you had typed `aaxbbb' to a fresh
`C-s', then the `aa' match would be located, and the failure highlighting would
correctly reflect the `aa' prefix match success and the `xbbb' suffix match
failure.

You could then, for example, hit RET to stop at the partial match (`aa')
position.

Or you could use the above code to quickly edit only the non-matching part. If,
for example, the buffer contained `aapbbb' or `aabbb', then a quick 1-character
change in the middle of the search string would put you on your way.

Besides these benefits would be the benefit of more consistency. Isearch would
always act the same (incrementally), even when it is given a complete string to
start with, just as if you had typed the string a character at a time.

I don't have the time to figure out what might need to be done to get this
behavior, which is preferable in my opinion. Perhaps someone who is an Isearch
guru (Juri?) will be interested and have the time?






^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Isearch: always try to find longest successful prefix [was: move to fail position in Isearch edit]
  2008-11-11 15:07 ` Isearch: always try to find longest successful prefix [was: move to fail position in Isearch edit] Drew Adams
@ 2008-11-11 17:32   ` Juri Linkov
  2008-11-11 20:19     ` Drew Adams
  0 siblings, 1 reply; 10+ messages in thread
From: Juri Linkov @ 2008-11-11 17:32 UTC (permalink / raw)
  To: Drew Adams; +Cc: emacs-devel

> You'll notice that this would be a lot handier if Isearch always started out
> (and resumed after Isearch edit) by treating the search string incrementally.
>
> For example, suppose you search again with a previous search string `aaxbbb' by
> hitting `C-s C-s' in a buffer where there is no match for `aaxbbb' but there are
> matches for `aa'.
>
> Isearch fails immediately, showing the entire search string, `aaxbbb', as a
> failed match by highlighting it. If, however, you had typed `aaxbbb' to a fresh
> `C-s', then the `aa' match would be located, and the failure highlighting would
> correctly reflect the `aa' prefix match success and the `xbbb' suffix match
> failure.

We could try implementing the idea suggested by Stefan in
http://thread.gmane.org/gmane.emacs.devel/74539/focus=74634
to iteratively remove the last char until a search succeeds.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: move to fail position in Isearch edit
  2008-11-11  6:42 move to fail position in Isearch edit Drew Adams
  2008-11-11  7:13 ` Mathias Dahl
  2008-11-11 15:07 ` Isearch: always try to find longest successful prefix [was: move to fail position in Isearch edit] Drew Adams
@ 2008-11-11 17:33 ` Juri Linkov
  2008-11-11 20:16   ` Drew Adams
  2008-11-11 20:33   ` Mathias Dahl
  2 siblings, 2 replies; 10+ messages in thread
From: Juri Linkov @ 2008-11-11 17:33 UTC (permalink / raw)
  To: Drew Adams; +Cc: emacs-devel

> Any interest in this? I bind it to `M-e' in `minibuffer-local-isearch-map', so
> `M-e M-e' puts the cursor at the match failure position.
>
> If you type a search string quickly and mistype a char or two, this lets you
> correct the typo without discarding and retyping the rest of the search string:
> `M-e M-e <corrections> C-s'.

Isn't it more convenient to type a new key to immediately remove the
failed part without entering the minibuffer for editing?  For example,
after typing `M-e' (selecting a good key is a difficult issue) it will
remove the failed part of the search string, go to the previous successful
matching point, and all this without activating the minibuffer.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: move to fail position in Isearch edit
  2008-11-11 17:33 ` move to fail position in Isearch edit Juri Linkov
@ 2008-11-11 20:16   ` Drew Adams
  2008-11-11 20:33   ` Mathias Dahl
  1 sibling, 0 replies; 10+ messages in thread
From: Drew Adams @ 2008-11-11 20:16 UTC (permalink / raw)
  To: 'Juri Linkov'; +Cc: emacs-devel

> > Any interest in this? I bind it to `M-e' in 
> > `minibuffer-local-isearch-map', so
> > `M-e M-e' puts the cursor at the match failure position.
> >
> > If you type a search string quickly and mistype a char or 
> > two, this lets you correct the typo without discarding
> > and retyping the rest of the search string:
> > `M-e M-e <corrections> C-s'.
> 
> Isn't it more convenient to type a new key to immediately remove the
> failed part without entering the minibuffer for editing?  For example,
> after typing `M-e' (selecting a good key is a difficult issue) it will
> remove the failed part of the search string, go to the 
> previous successful matching point, and all this without activating
> the minibuffer.

Maybe we're miscommunicating. If you just want to remove the failed suffix,
simply use `C-g'. No need for any new feature to do that.

This is not about that. This is about keeping the failed suffix but letting you
do something at the place where failure starts: delete chars, insert chars. IOW,
it's about editing the search string, starting at the position where match
failure begins.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: Isearch: always try to find longest successful prefix [was: move to fail position in Isearch edit]
  2008-11-11 17:32   ` Juri Linkov
@ 2008-11-11 20:19     ` Drew Adams
  0 siblings, 0 replies; 10+ messages in thread
From: Drew Adams @ 2008-11-11 20:19 UTC (permalink / raw)
  To: 'Juri Linkov'; +Cc: emacs-devel

> > You'll notice that this would be a lot handier if Isearch 
> > always started out (and resumed after Isearch edit) by
> > treating the search string incrementally.
> >
> > For example, suppose you search again with a previous 
> > search string `aaxbbb' by hitting `C-s C-s' in a buffer
> > where there is no match for `aaxbbb' but there are
> > matches for `aa'.
> >
> > Isearch fails immediately, showing the entire search 
> > string, `aaxbbb', as a failed match by highlighting it.
> > If, however, you had typed `aaxbbb' to a fresh
> > `C-s', then the `aa' match would be located, and the 
> > failure highlighting would correctly reflect the `aa'
> > prefix match success and the `xbbb' suffix match
> > failure.
> 
> We could try implementing the idea suggested by Stefan in
> http://thread.gmane.org/gmane.emacs.devel/74539/focus=74634
> to iteratively remove the last char until a search succeeds.

Yes. I forgot about that thread (which I in fact started!). FWIW, I've changed
my opinion about part of what I said in that thread. The change of opinion is
based on experience using a similar feature in Icicles minibuffer completion
(see below).

Stefan suggested in the thread you cite: "[S]tart from the user's input (which
doesn't match) and iteratively remove the last char until a search succeeds.  It
may not always give you the very best imaginable information, but least it gives
you the same info as Drew's proposed code in the case where the user just typed
the text one char at a time."

That's the same thing I'm saying now.

Or almost the same thing, depending on what he meant by "remove ... until a
search succeeds". Would that removal be just a way to _find_ the longest prefix
match, or would those non-matching chars also be removed from the user's input
string?

My suggestion is to (1) go ahead and find the longest prefix match (e.g. using
the method Stefan suggested: peel off chars at the end until you get a match),
and (2) move to that match location, but (3) do _not_ remove the failed part of
the input string.

Instead, just highlight the failed suffix and let the user optionally use a key
to edit the string with the cursor at the failure start position. IOW, treat
this case the same as the case where the user typed the search string
incrementally.

If the user doesn't want to edit at the failure position, s?he need only hit
`C-g' to remove the failed suffix altogether (as usual), instead of hitting the
edit-at-fail-position key.

IOW, give the user a choice; don't just remove the failed suffix automatically.
If the user wants to remove it, `C-g' will do that (nothing new here). If the
user wants to edit the string at the failure position, some new key would do
that (I proposed `M-e').

FWIW, this is exactly the approach I have used for some time now in Icicles, for
input completion failure highlighting. The failed suffix of your minibuffer
input is highlighted (by default). If you hit `C-M-l' then the cursor is moved
to the start of that failed suffix. If you hit `C-M-l' a second time then the
failed suffix is removed.

This two-step approach is great for editing the middle of your input, at a place
(where it failed) that you often want to tweak. And it's quick to hit the key
twice if you want to just delete the mismatch. (Originally, `C-M-l' just removed
the mismatch; the two-step behavior is better.)

In Isearch, however, if you are not editing the search string, then the "edit"
position (there is no cursor there) is always at the end of the input string. So
to edit a character in the middle of the input string, you must enter Isearch
edit mode (`M-e'). 

I see no way programmatically to enter edit mode and also move the cursor to the
failure position. That's why I proposed what I did: a first `M-e' to start
editing, and a second `M-e' to move to the failure position. That works fine.

What's missing is the piece I mentioned in the text quoted above that started
this thread: Isearch should _always_ act incrementally. That is apparently the
same thing Stefan was talking about, unless he meant to also remove the
non-matching suffix from the user's input. 

In my suggestion, Isearch would act no differently whether you type each
character or start a search with a complete string (e.g. `C-s C-s'). In both
cases, search would proceed as if you had typed each bit incrementally.

I don't know if that would be difficult to implement. It would be great if it
were somehow as simple as just telling the Isearch code to treat the input
string as if it were typed a bit at a time - analogously to just adding
`call-interactively' to a function call to pick up the interactive behavior. ;-)

Wrt Stefan's remark about the performance hit to find the failure position: It
should be about the same as what's needed for normal incremental search when you
type a char at a time - the same mechanism would be used. But of course extra
matches would be attempted - at most one for each failure character.

FWIW, in Icicles, the analogous highlighting can have a _much_ bigger
performance hit, because completion can be costly and it calls for multiple
completion attempts (with diminishing suffixes). It is especially costly for
some kinds of completion, such as possibly remote file-name completion. Because
of this, users can customize the use of such highlighting (during strict or lax
completion; on demand or automatically each time you update the input;
pending-input delay; max number of candidates; etc.).

FWIW, to optimize finding the longest matching prefix in Icicles, I do this:

1. Complete the input string through each of the last two chars, starting with
the last (whole string). That is, just as Stefan suggested, peel away one char
at a time. But do this only for the last two chars.

2. Then change to binary search (testing) for the other chars: split the input
and test, split half of that and test, etc.

The binary-search testing (#2) is (as always) very quick - much better than
checking each possible prefix with diminishing lengths, especially for long
input strings.

The reason for trying #1 first is that you often type at the end of the input
rather than in the middle, so it is common for a mismatch to start near the end.
And, especially with the feedback from mismatch highlighting, you tend to
correct a mismatch soon after you type it.

(Editing a directory component of existing file-name input would be a case where
you might introduce a mismatch that begins in the middle or near the beginning,
not near the end, of the input.)

For Isearch, I expect that simple right-to-left checking of diminishing prefixes
will be fine. Input is nearly always at the right end.

Except when it's not. ;-) For the case of `C-s C-s' or after yanking chunks, we
could try optimizing (e.g. binary testing). For yanking, the testing sequence
could take into account the position of the yank. But a simple right-to-left
approach should be tried first. My guess is that it will be sufficiently fast.








^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: move to fail position in Isearch edit
  2008-11-11 17:33 ` move to fail position in Isearch edit Juri Linkov
  2008-11-11 20:16   ` Drew Adams
@ 2008-11-11 20:33   ` Mathias Dahl
  2008-11-11 21:02     ` Drew Adams
  1 sibling, 1 reply; 10+ messages in thread
From: Mathias Dahl @ 2008-11-11 20:33 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Drew Adams, emacs-devel

> Isn't it more convenient to type a new key to immediately remove the
> failed part without entering the minibuffer for editing?

I agree. If it then allows you to continue typing more chars to search for.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: move to fail position in Isearch edit
  2008-11-11 20:33   ` Mathias Dahl
@ 2008-11-11 21:02     ` Drew Adams
  2008-11-11 21:36       ` Juri Linkov
  0 siblings, 1 reply; 10+ messages in thread
From: Drew Adams @ 2008-11-11 21:02 UTC (permalink / raw)
  To: 'Mathias Dahl', 'Juri Linkov'; +Cc: emacs-devel

> > Isn't it more convenient to type a new key to immediately remove the
> > failed part without entering the minibuffer for editing?
> 
> I agree. If it then allows you to continue typing more chars 
> to search for.

That's just what `C-g' does today. It removes the failed (mismatch) portion and
lets you continue to search. And that includes letting you type more characters
at the end of the search string. Nothing new there.

What I proposed is not about that - it's about editing chars in the middle of
the search string, keeping some or all of the chars that failed to match. See
the example I gave.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: move to fail position in Isearch edit
  2008-11-11 21:02     ` Drew Adams
@ 2008-11-11 21:36       ` Juri Linkov
  0 siblings, 0 replies; 10+ messages in thread
From: Juri Linkov @ 2008-11-11 21:36 UTC (permalink / raw)
  To: Drew Adams; +Cc: emacs-devel, 'Mathias Dahl'

>> > Isn't it more convenient to type a new key to immediately remove the
>> > failed part without entering the minibuffer for editing?
>>
>> I agree. If it then allows you to continue typing more chars
>> to search for.
>
> That's just what `C-g' does today. It removes the failed (mismatch) portion and
> lets you continue to search. And that includes letting you type more characters
> at the end of the search string. Nothing new there.
>
> What I proposed is not about that - it's about editing chars in the middle of
> the search string, keeping some or all of the chars that failed to match. See
> the example I gave.

I described what would be more useful without thinking about whether it
is implemented or not, and this happens to be already done ;)  So I really
can't comment about the usefulness of a special keybinding with a seemingly
rare use.  Instead we could keep the highlighting with `isearch-fail' face
of the failed portion in the editing minibuffer.  Thus it will provide a
visual indication to help moving point to the right place when necessary.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2008-11-11 21:36 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-11  6:42 move to fail position in Isearch edit Drew Adams
2008-11-11  7:13 ` Mathias Dahl
2008-11-11 15:07 ` Isearch: always try to find longest successful prefix [was: move to fail position in Isearch edit] Drew Adams
2008-11-11 17:32   ` Juri Linkov
2008-11-11 20:19     ` Drew Adams
2008-11-11 17:33 ` move to fail position in Isearch edit Juri Linkov
2008-11-11 20:16   ` Drew Adams
2008-11-11 20:33   ` Mathias Dahl
2008-11-11 21:02     ` Drew Adams
2008-11-11 21:36       ` Juri Linkov

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).