On Tue, 15 Aug 2023 at 01:41, Chet Ramey <chet.ra...@case.edu> wrote:

> On 8/11/23 4:19 PM, Martin D Kealey wrote:
> > I think it would be helpful to start this sentence with "The selected
> > line…", to differentiate from the line just entered containing a "!".
>
> It's both, actually. The line being expanded is broken into words to bound
> the history expansion, since a history expansion doesn't extend to multiple
> words, and the event is broken into words for the rest of the process.
>

While the delimiters for picking history expansions out of a line of input
include all (most of?) the things that cause words to be delimited at the
shell grammar level, it differs sufficiently that telling the user to
consider the shell grammar is misleading and quite unhelpful.

Examples:

1. history expansion a double quote (U+0022) read as input as a literal
character with no special meaning; it does not delimit the "word" as far as
history expansion goes (so you can search for it)
$ "echo" ls -ld
ls -ld
$ !"e
$ echo ls -ld
ls -ld
$ !":*
$ ls -ld
drwx------ 3 martin martin 280 2023-08-15 18:32:15.139812360 +1000 ./

2. The list of exempted characters only applies to whatever immediately
follows "!". After that the history expansion continues without regard for
word boundaries, simply stopping when the next character isn't valid given
the context.

In particular, the :s/// replacements treat everything except the delimiter
and \ as literals in the pattern:

$ echo cat > /dev/null
$ !!:s/>/<
[expands to] echo cat < /dev/null
cat
$ !!:s=ho ca=ho tom/ca=
[expands to] echo tom/cat < /dev/null
tom/cat
$ who="Chet's fan club"
$ echo 'Hello world, meet $who'
Hello world, meet $who
$ !!:gs/'/"/
[expands to] echo "Hello world, meet $who"
Hello world, meet Chet's fan club

So citing "word splitting" of the *input* line is badly misleading.

This is in sharp contrast to selecting words from the target line, where it
makes approximately mimics how words are split in the shell grammar:
$ echo "hi ho" "it's off to work we go"
hi ho it's off to work we go
$ !:0-1, !:1, !:2*
$ echo "hi ho", "hi ho", "it's off to work we go"
hi ho, hi ho, it's off to work we go

-Martin

Reply via email to