Subject: bug#29821: Ensure quick substitution only occurs at start of line

From: Noam Postavsky <[email-masked]>
Date: Sun, 31 Dec 2017 19:33:20 -0500

Jay Kamat <[email-masked]> writes:

> I'm filing this separately from #29157, because I think that issue got a
> bit overloaded with multiple eshell problems and is very hard to follow.

Yes, thanks.

> I recently noticed the changes in #29157, and I'm disappointed that we
> came to the conclusion to disable history expansion completely. I find
> it's rather useful, especially for things like:
>
> $ mv one.txt two.txtt
> # whoops!
> $ mv !!:$ two.txt

Hmm, using history expansion would mean typing

    M-p DEL C-a M-f M-d M-d ! ! : $

to get

    mv !!:$ two.txt

vs 

    M-p C-a M-f M-d M-d C-k C-y C-y DEL

to get

    mv two.txtt two.txt

Hardly seems worth the trouble of learning this syntax (and occasionally
triggering accidentally, which is why I disable it in bash too).  Is
having history expansion enabled by default very important?  You can
still enable it in your config.

> This is preferred (in my opinion) over lisp functions to keep muscle
> memory working between shells. If anything, I would suggest disabling
> quick substitution (as I don't find it more useful than using history
> directly most of the time)

(PS my suggestion is almost compatible with bash readline too, just M-p
needs to be C-p instead, and that incompatibility is present in the
history expansion case too).

> I've created a patch to try to fix the bug found in #29157, which was:
>
>> echo $PATH | sed "s/[^o]foo[^o]/bar/g"
>> Unknown predicate character ‘b’
>
> The fix is rather simple, it simply limits the quick substitution to the
> start of the line only (as observed in bash, as Andreas noted in the
> previous thread).
>
> I hope that we reconsider the decision to disable history expansion by
> default, it's a nice feature of eshell (which I have another patch I
> would like to submit later to try to expand it's functionality a bit
> more).
>
> Please let me know if you think this is a poor way of solving this issue
> (or if anything else seems wrong or missing), and I'll try to follow up.

I guess it's an improvement on what we have currently (the feature is
rather underspecified).  Should we consider also handling spaces like
bash does?  In bash I can do this:

    ~/tmp$ echo foo bar
    foo bar
    ~/tmp$ ^foo bar^blah^
    echo blah
    blah

In eshell (with and without your patch) I get:

    ~/src/emacs $ echo foo bar
    ("foo" "bar")
    ~/src/emacs $ ^foo bar^blah^
    ^foo: command not found