Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

bash completion and spaces

16 views
Skip to first unread message

Victor Sudakov

unread,
Apr 22, 2021, 4:30:05 AM4/22/21
to
Dear Colleagues,

I have an example app which can be run only as "app3 -h test1 -s foo" or
"app3 -h test2 -s bar". So I decided to provide it with a small manual
completion for convenience.

[vas@test2 ~]$ ./list.sh
-h test1 -s foo
-h test2 -s bar
[vas@test2 ~]$ complete -C ./list.sh app3
[vas@test2 ~]$

The result however is discouraging, the completion mechanism won't add
whole lines of parameters, it's trying to split on spaces (here I press
<TAB> several times:

[vas@test2 ~]$ app3 -h -h -h test

Can you please give a hint how to make it complete "app3" with either
"-h test1 -s foo" or "-h test2 -s bar" as a whole?

I would not like to make all this too complicated, write complex
completion funcions if possible. A static (-W) completion would be even
better.

--
Victor Sudakov VAS4-RIPE
http://vas.tomsk.ru/
2:5005/49@fidonet
signature.asc

David Wright

unread,
Apr 22, 2021, 10:20:04 AM4/22/21
to
Perhaps:

alias app3a='app3 -h test1 -s foo'
alias app3b='app3 -h test2 -s bar'

Cheers,
David.

Victor Sudakov

unread,
Apr 22, 2021, 1:10:04 PM4/22/21
to
No, not alias, I'd like to do it via bash completion. I may want to make
it dynamic eventually, the problem is in the spaces.
signature.asc

David Wright

unread,
Apr 23, 2021, 11:10:03 PM4/23/21
to
On Thu 22 Apr 2021 at 21:38:53 (+0700), Victor Sudakov wrote:
> David Wright wrote:
It's claimed that you can overcome this, in

https://stackoverflow.com/questions/11070370/bash-completion-for-strings-with-spaces-and-punctuation

but I'd be balancing the possibility of side-effects with redefining Space
against the benefits of completing a few strings.

I also don't understand what you mean by "dynamic", particularly as
you wrote "A static (-W) completion" above. You could always generate
lists of aliases dynamically, too.

Cheers,
David.

Victor Sudakov

unread,
Apr 24, 2021, 2:50:04 AM4/24/21
to
Yes, this describes my case, unfortunately it lacks an example. Maybe
googling for COMP_WORDBREAKS will yield some examples. Thanks for the
link.

>
> but I'd be balancing the possibility of side-effects with redefining Space
> against the benefits of completing a few strings.

If COMP_WORDBREAKS cannot be redefined within one and only one
completion, then perhaps the game is not worth the candle.

BTW on my current Debian system I don't see the space character in $COMP_WORDBREAKS.

>
> I also don't understand what you mean by "dynamic", particularly as
> you wrote "A static (-W) completion" above.

I actually meant that a simple example of static completion with spaces
(if someone cares to provide it) would help me understand the idea, and
I could use it in a dynamic completion later if I need to.

> You could always generate
> lists of aliases dynamically, too.

Well, I can make bash regenerate a completion list every time I
enter "app3<TAB>", probably it can be done with aliases as well?
signature.asc

davidson

unread,
Apr 24, 2021, 9:40:05 AM4/24/21
to
On Sat, 24 Apr 2021 Victor Sudakov wrote:
> David Wright wrote:
>>>>>
>>>>> I have an example app which can be run only as "app3 -h test1 -s
>>>>> foo" or "app3 -h test2 -s bar". So I decided to provide it with
>>>>> a small manual completion for convenience.
>>>>>
>>>>> [vas@test2 ~]$ ./list.sh
>>>>> -h test1 -s foo
>>>>> -h test2 -s bar
>>>>> [vas@test2 ~]$ complete -C ./list.sh app3
>>>>> [vas@test2 ~]$
>>>>>
>>>>> The result however is discouraging, the completion mechanism
>>>>> won't add whole lines of parameters, it's trying to split on
>>>>> spaces (here I press <TAB> several times:
>>>>>
>>>>> [vas@test2 ~]$ app3 -h -h -h test
>>>>>
>>>>> Can you please give a hint how to make it complete "app3" with either
>>>>> "-h test1 -s foo" or "-h test2 -s bar" as a whole?

Almost entirely idle curiosity: the arguments test1/test2 and foo/bar
which your app3 requires, are they arbitrary strings? Or are they
instead paths to files, or perhaps one of the other 20-odd categories
recognised by the -A option for bash builtin "complete"?

>>>>> I would not like to make all this too complicated, write complex
>>>>> completion funcions if possible.

In the case you describe, you might find the behaviour of readline
function "menu-complete" slightly more helpful than the readline
function "complete" presently mapped to TAB (given that you find the
behaviour of "complete" completely unhelpful, naturally enough).

See readline(3) for some documentation.

You could, say, map Shift-TAB to "menu-complete" in ~/.inputrc

(In emacs to get Shift-TAB to produce a literal Shift-TAB, you'll need
to hit Ctrl-q first.)

I make this suggestion as a partial workaround/improvement to present
situation. I doubt you'll find it an ideal solution.

>>>>> A static (-W) completion would be even
>>>>> better.
>>>>
>>>> Perhaps:
>>>>
>>>> alias app3a='app3 -h test1 -s foo'
>>>> alias app3b='app3 -h test2 -s bar'
>>>
>>> No, not alias, I'd like to do it via bash completion. I may want to make
>>> it dynamic eventually, the problem is in the spaces.
>>
>> It's claimed that you can overcome this, in
>>
>> https://stackoverflow.com/questions/11070370/bash-completion-for-strings-with-spaces-and-punctuation
>
> Yes, this describes my case, unfortunately it lacks an example. Maybe
> googling for COMP_WORDBREAKS will yield some examples. Thanks for the
> link.
>
>>
>> but I'd be balancing the possibility of side-effects with redefining Space
>> against the benefits of completing a few strings.
>
> If COMP_WORDBREAKS cannot be redefined within one and only one
> completion, then perhaps the game is not worth the candle.
>
> BTW on my current Debian system I don't see the space character in $COMP_WORDBREAKS.

If you have xxd installed, what does xxd show you?

$ printf "%s" "$COMP_WORDBREAKS" | xxd

If you do not have xxd installed, what does od show you?

$ printf "%s" "$COMP_WORDBREAKS" | od -A x -t x1z -v

Anyways, good luck. I think this is an interesting problem.

--
Ce qui est important est rarement urgent
et ce qui est urgent est rarement important
-- Dwight David Eisenhower

David Wright

unread,
Apr 24, 2021, 12:10:04 PM4/24/21
to
As davidson showed, it is there. My only suggestion would be a study of
/usr/share/bash-completion/completions/{cpan2dist,udisksctl,mount.linux,git},
the four commands that manipulate COMP_WORDBREAKS, to see if there are
any hints. Not my cup of tea.

> > I also don't understand what you mean by "dynamic", particularly as
> > you wrote "A static (-W) completion" above.
>
> I actually meant that a simple example of static completion with spaces
> (if someone cares to provide it) would help me understand the idea, and
> I could use it in a dynamic completion later if I need to.
>
> > You could always generate
> > lists of aliases dynamically, too.
>
> Well, I can make bash regenerate a completion list every time I
> enter "app3<TAB>", probably it can be done with aliases as well?

I think aliases can only work at the level of the entire command line,
ie the aliases must have been defined by the time you start typing the
line (which is why you can't define and use an alias in the same line).

OTOH bash completion completes at a character-to-character level AIUI,
ie <TAB> always recalculates a fresh list (though you have to rubout
one character and press <TAB> again to actually complete with it).

Cheers,
David.

Victor Sudakov

unread,
Apr 26, 2021, 1:30:05 AM4/26/21
to
davidson wrote:
> On Sat, 24 Apr 2021 Victor Sudakov wrote:
> > David Wright wrote:
> > > > > >
> > > > > > I have an example app which can be run only as "app3 -h test1 -s
> > > > > > foo" or "app3 -h test2 -s bar". So I decided to provide it with
> > > > > > a small manual completion for convenience.
> > > > > >
> > > > > > [vas@test2 ~]$ ./list.sh
> > > > > > -h test1 -s foo
> > > > > > -h test2 -s bar
> > > > > > [vas@test2 ~]$ complete -C ./list.sh app3
> > > > > > [vas@test2 ~]$
> > > > > >
> > > > > > The result however is discouraging, the completion mechanism
> > > > > > won't add whole lines of parameters, it's trying to split on
> > > > > > spaces (here I press <TAB> several times:
> > > > > >
> > > > > > [vas@test2 ~]$ app3 -h -h -h test
> > > > > >
> > > > > > Can you please give a hint how to make it complete "app3" with either
> > > > > > "-h test1 -s foo" or "-h test2 -s bar" as a whole?
>
> Almost entirely idle curiosity: the arguments test1/test2 and foo/bar
> which your app3 requires, are they arbitrary strings? Or are they
> instead paths to files, or perhaps one of the other 20-odd categories
> recognised by the -A option for bash builtin "complete"?

"-h" are hosts to connect to, so I could probably get them completed as "-A hostname",
but the remaining arguments are arbitrary strings.

>
> > > > > > I would not like to make all this too complicated, write complex
> > > > > > completion funcions if possible.
>
> In the case you describe, you might find the behaviour of readline
> function "menu-complete" slightly more helpful than the readline
> function "complete" presently mapped to TAB (given that you find the
> behaviour of "complete" completely unhelpful, naturally enough).
>
> See readline(3) for some documentation.
>
> You could, say, map Shift-TAB to "menu-complete" in ~/.inputrc
>
> (In emacs to get Shift-TAB to produce a literal Shift-TAB, you'll need
> to hit Ctrl-q first.)
>
> I make this suggestion as a partial workaround/improvement to present
> situation. I doubt you'll find it an ideal solution.

I'm surprised to find out that it has become so complicated.

[dd]

> >
> > BTW on my current Debian system I don't see the space character in $COMP_WORDBREAKS.
>
> If you have xxd installed, what does xxd show you?

I actually looked with `hd` and expected to see 0x20 there, but
somehow see none of it:

$ echo $COMP_WORDBREAKS | hd
00000000 22 27 40 3e 3c 3d 3b 7c 26 28 3a 0a |"'@><=;|&(:.|
0000000c
signature.asc

Victor Sudakov

unread,
Apr 26, 2021, 1:40:04 AM4/26/21
to
David Wright wrote:

[dd]

>
> > > I also don't understand what you mean by "dynamic", particularly as
> > > you wrote "A static (-W) completion" above.
> >
> > I actually meant that a simple example of static completion with spaces
> > (if someone cares to provide it) would help me understand the idea, and
> > I could use it in a dynamic completion later if I need to.
> >
> > > You could always generate
> > > lists of aliases dynamically, too.
> >
> > Well, I can make bash regenerate a completion list every time I
> > enter "app3<TAB>", probably it can be done with aliases as well?
>
> I think aliases can only work at the level of the entire command line,
> ie the aliases must have been defined by the time you start typing the
> line (which is why you can't define and use an alias in the same line).
>
> OTOH bash completion completes at a character-to-character level AIUI,
> ie <TAB> always recalculates a fresh list (though you have to rubout
> one character and press <TAB> again to actually complete with it).

Yes, that's why I wanted to do it with completion, but now I don't feel
like investing too much time and effort into such a complicated thing.
Completion is supposed to save your time and effort, not consume it.
signature.asc

davidson

unread,
Apr 26, 2021, 5:50:04 AM4/26/21
to
Above I count 12 characters piped from echo to hd. The final character
is a newline added by echo, so that leaves 11 characters attributable
to the content of COMP_WORDBREAKS.

But try this, below. It will tell you the length (in characters) of
the content of COMP_WORDBREAKS.

$ echo ${#COMP_WORDBREAKS}
14

So, when you do...

$ echo $COMP_WORDBREAKS | hd
00000000 22 27 40 3e 3c 3d 3b 7c 26 28 3a 0a |"'@><=;|&(:.|
0000000c

...what accounts for the three missing characters (namely SPACE, TAB,
and NEWLINE)?

TLDR: The shell's "word splitting" removes them, because you have not
double-quoted the variable.

Surround the variable with double-quotes, and I expect you will see
that they are the first three characters of the content of
COMP_WORDBREAKS.

$ echo "$COMP_WORDBREAKS" | hd
00000000 20 09 0a 22 27 40 3e 3c 3d 3b 7c 26 28 3a 0a | .."'@><=;|&(:.|
0000000f

For more explanation, see

bash(1), section EXPANSION (esp. subsection "Word Splitting")
https://mywiki.wooledge.org/WordSplitting
https://mywiki.wooledge.org/Arguments

Thomas Schmitt

unread,
Apr 26, 2021, 6:10:04 AM4/26/21
to
Hi,

> what accounts for the three missing characters (namely SPACE, TAB,
> and NEWLINE)?

They get eaten by the shell parser if you do not use quotation marks:

$ echo $COMP_WORDBREAKS | wc -c
11
$ echo "$COMP_WORDBREAKS" | wc -c
14

So to see all characters (including the newline added by "echo") i do:

$ echo "$COMP_WORDBREAKS" | hd
00000000 20 09 0a 22 27 3e 3c 3d 3b 7c 26 28 3a 0a | .."'><=;|&(:.|
0000000e

Your COMP_WORDBREAKS and mine differ in length, though

$ echo ${#COMP_WORDBREAKS}
13

Mine is missing '@'.


Have a nice day :)

Thomas

Greg Wooledge

unread,
Apr 26, 2021, 7:40:04 AM4/26/21
to
On Mon, Apr 26, 2021 at 12:04:45PM +0200, Thomas Schmitt wrote:
> > what accounts for the three missing characters (namely SPACE, TAB,
> > and NEWLINE)?
>
> They get eaten by the shell parser if you do not use quotation marks:
>
> $ echo $COMP_WORDBREAKS | wc -c
> 11
> $ echo "$COMP_WORDBREAKS" | wc -c
> 14

Not the parser, technically. The correct term is word splitting. See
below if you want more details.

> So to see all characters (including the newline added by "echo") i do:
>
> $ echo "$COMP_WORDBREAKS" | hd
> 00000000 20 09 0a 22 27 3e 3c 3d 3b 7c 26 28 3a 0a | .."'><=;|&(:.|
> 0000000e

Even better, when you're dealing with arbitrary data that may include
characters which echo might interpret:

printf %s "$COMP_WORDBREAKS" | hd

It looks like there aren't any in this particular case, but it's a good
habit to develop for future cases.


Word splitting: an unquoted substitution such as $COMP_WORDBREAKS undergoes
two more rounds of alterations: word splitting, and pathname expansion.
The word splitting round uses the contents of the IFS variable, or the
default value of "space tab newline" if IFS is unset.

Each character of IFS is treated as a word delimiter, and may cause a
split. The characters of IFS are divided into two types: whitespace,
and non-whitespace. All consecutive IFS whitespace characters are grouped
together and treated as a single delimiter. Also, any single IFS
non-whitespace character may be surrounded by any number of adjacent IFS
whitespace characters, and that whole group is treated as a single
delimiter. Finally, any leading or trailing IFS whitespace characters are
trimmed from the value and discarded.

In your "$COMP_WORDBREAKS", you can see that the value begins with space,
tab and newline. Those are all IFS whitespace characters, so they're
discarded. The rest of the value is free of IFS whitespace characters,
so there are no further alterations. The result is the single word
"'><=;|&(:. which is then passed to the pathname expansion round.

(There are no globbing characters in this value, so pathname expansion
will not occur. But in general, it's a thing you need to be aware of.)

Some simple demonstrations:

$ string=' hi there '
$ printf '<%s> ' "$string" ; echo
< hi there >
$ printf '<%s> ' $string ; echo
<hi> <there>
$ IFS=h
$ printf '<%s> ' $string ; echo
< > <i t> <ere >
$ IFS='h '
$ printf '<%s> ' $string ; echo
<> <i> <t> <ere>

The last one shows an IFS value with both whitespace and non-whitespace
characters in it. The leading spaces are trimmed, leaving h as the
first character. As a non-whitespace character, that one is *not* trimmed,
so it delimits an initial empty field from the rest of the string.

An example with pathname expansion:

$ IFS=$' \t\n'
$ string='/* a comment */'
$ cd /tmp
$ echo $string
/backup /bin /boot /chroot /command /dev /etc /hd /home /initrd.img /initrd.img.old /lib /lib64 /lost+found /media /mnt /opt /package /proc /root /run /sbin /service /srv /stuff /sys /tmp /usr /var /vmlinuz /vmlinuz.old a comment dumps/ ssh-6i8aLIWw2QgZ/ ssh-T5JLPWVvU9xw/ systemd-private-d50cab7eaba04f88b49c7e97e3d1043b-ModemManager.service-iD7GSh/ systemd-private-d50cab7eaba04f88b49c7e97e3d1043b-ntp.service-GeOK4e/ systemd-private-d50cab7eaba04f88b49c7e97e3d1043b-systemd-logind.service-se4pDh/ Temp-10bb8392-9d61-4469-bf31-5b5ef6c29a88/ Temp-1ffbc72d-62a7-46d4-a403-481053966525/

Word splitting occurs first, giving the four words /* a comment */
and then pathname expansion (globbing) occurs on the first and last
words. All of the resulting words are given as arguments to echo.

All of this is why proper quoting is absolutely essential when working
with the shell. It cannot possibly be said enough times.

Thomas Schmitt

unread,
Apr 26, 2021, 8:00:04 AM4/26/21
to
Hi,

Greg Wooledge wrote:
> Not the parser, technically. The correct term is word splitting.

Always good to know which part of the shell tries to bite me. :))


> $ string=' hi there '
> [...]
> $ printf '<%s> ' $string ; echo
> <hi> <there>

As C programmer i am now tempted to scream.
(This command should really not have the same name as printf(3).)


> All of this is why proper quoting is absolutely essential when working
> with the shell.

+1

Greg Wooledge

unread,
Apr 26, 2021, 8:20:04 AM4/26/21
to
On Mon, Apr 26, 2021 at 01:49:42PM +0200, Thomas Schmitt wrote:
> > $ string=' hi there '
> > [...]
> > $ printf '<%s> ' $string ; echo
> > <hi> <there>
>
> As C programmer i am now tempted to scream.
> (This command should really not have the same name as printf(3).)

There are a few changes between printf(3) and printf(1), and a few
more bash extensions added to bash's builtin implementation.

The big change here is that if you supply more arguments than there
are format specifiers, printf(1) implicitly loops, and reuses the
format specifier as many times as needed to consume all of the extra
arguments. This is incredibly handy when used correctly.

The biggest change for bash's builtin is the -v option, which lets
you store the formatted result in a variable. This is better than
using a command substitution, because it doesn't fork, and because
it doesn't drop trailing newlines the way a command substitution does.

There are several smaller changes as well, but you can dive into those
on your own. :-)

davidson

unread,
Apr 26, 2021, 2:00:05 PM4/26/21
to
On Mon, 26 Apr 2021 Victor Sudakov wrote:
> davidson wrote:
>> On Sat, 24 Apr 2021 Victor Sudakov wrote:
>>> David Wright wrote:
>>>>>>>
>>>>>>> I have an example app which can be run only as "app3 -h test1 -s
>>>>>>> foo" or "app3 -h test2 -s bar". So I decided to provide it with
>>>>>>> a small manual completion for convenience.
>>>>>>>
>>>>>>> [vas@test2 ~]$ ./list.sh
>>>>>>> -h test1 -s foo
>>>>>>> -h test2 -s bar
>>>>>>> [vas@test2 ~]$ complete -C ./list.sh app3
>>>>>>> [vas@test2 ~]$
>>>>>>>
>>>>>>> The result however is discouraging, the completion mechanism
>>>>>>> won't add whole lines of parameters, it's trying to split on
>>>>>>> spaces (here I press <TAB> several times:
>>>>>>>
>>>>>>> [vas@test2 ~]$ app3 -h -h -h test
>>>>>>>
>>>>>>> Can you please give a hint how to make it complete "app3" with
>>>>>>> either "-h test1 -s foo" or "-h test2 -s bar" as a whole?

% Proposal A

Are all the real arguments to '-h' (the hostnames) named with a common
prefix, like they are in your example?

If so, you can do this:

$ complete -P "-h test" -W "'1 -s foo' '2 -s bar'" app3

At bash prompt, type "app3 1", then hit TAB, and you'll get

$ app3 -h test1 -s foo

Or type "app3 2", then hit TAB, and you'll get

$ app3 -h test2 -s bar


% Proposal B

On the other hand, if your hostnames are *not* structured like that,
then you can do something like the following instead:

$ complete -P "-h " -W "'chestnut -s foo' 'cherry -s bar'" app3

Now, at the bash prompt type "app3" followed by a space and an
*unambiguous* prefix of a hostname

$ app3 ches

and then hit TAB, to obtain

$ app3 -h chestnut -s foo

>>
>> Almost entirely idle curiosity: the arguments test1/test2 and
>> foo/bar which your app3 requires, are they arbitrary strings? Or
>> are they instead paths to files, or perhaps one of the other 20-odd
>> categories recognised by the -A option for bash builtin "complete"?
>
> "-h" are hosts to connect to, so I could probably get them completed as "-A hostname",
> but the remaining arguments are arbitrary strings.

% Proposal C

In that case, you could get all but the last argument completed like
so:

$ complete -A hostname -P '-h ' -S ' -s'

Type the command, followed by an unambiguous prefix of desired
hostname from either /etc/hosts or $HOSTFILE

$ app3 ban

Hit TAB (which performs readline(3) function "complete"), and (if
banana is the only hostname starting with 'ban') then the line becomes

$ app3 -h banana -s

No completion for final argument, so incomplete.

>>>>>>> I would not like to make all this too complicated, write complex
>>>>>>> completion funcions if possible.
>>
>> In the case you describe, you might find the behaviour of readline
>> function "menu-complete" slightly more helpful than the readline
>> function "complete" presently mapped to TAB (given that you find the
>> behaviour of "complete" completely unhelpful, naturally enough).
>>
>> See readline(3) for some documentation.
>>
>> You could, say, map Shift-TAB to "menu-complete" in ~/.inputrc
>>
>> (In emacs to get Shift-TAB to produce a literal Shift-TAB, you'll need
>> to hit Ctrl-q first.)
>>
>> I make this suggestion as a partial workaround/improvement to present
>> situation. I doubt you'll find it an ideal solution.
>
> I'm surprised to find out that it has become so complicated.
>

Adding a line to inputrc, to enable a readline function by assigning a
keystroke to it, does not seem especially complicated. Maybe I have
not explained it clearly?

% Proposal D

$ cat ~/.inputrc # a literal Shift-TAB is inside the double quotes
"� ": menu-complete

$ complete -W "'-h test1 -s foo' '-h test2 -s bar'" app3

At a bash prompt, type "app3" followed by a space, then hit Shift-TAB,
and the line becomes

$ app3 -h test1 -s foo

Hit Shift-TAB again, and it becomes

$ app3 -h test2 -s bar

Hit Shift-TAB again, and it becomes the (rather unhelpful) ambiguous
prefix

$ app3 -h test

Hit Shift-TAB again, and the you're back to the start of the cycle

$ app3 -h test1 -s foo

Of course, the longer the list of completions, the less attractive
this last solution becomes.

> [dd]
>
>>>
>>> BTW on my current Debian system I don't see the space character in $COMP_WORDBREAKS.
>>
>> If you have xxd installed, what does xxd show you?
>
> I actually looked with `hd` and expected to see 0x20 there, but
> somehow see none of it:
>
> $ echo $COMP_WORDBREAKS | hd
> 00000000 22 27 40 3e 3c 3d 3b 7c 26 28 3a 0a |"'@><=;|&(:.|
> 0000000c
>
>
>

--

davidson

unread,
Apr 26, 2021, 2:30:05 PM4/26/21
to
On Mon, 26 Apr 2021 davidson wrote:

Two corrections to previous message.

[dd]
>
> % Proposal C
>
> In that case, you could get all but the last argument completed like
> so:
>
> $ complete -A hostname -P '-h ' -S ' -s'

1. At the end of the line above, the command name is missing.

$ complete -A hostname -P '-h ' -S ' -s' app3

[dd]
>
> % Proposal D
>
> $ cat ~/.inputrc # a literal Shift-TAB is inside the double quotes
> "� ": menu-complete

2. The '^[' above is an artifact of...something. In my ~/.inputrc
there is nothing inside those double quotes except for a literal
Shift-TAB (encoded as ASCII ESC character 0x1b followed by TAB 0x09).

David Wright

unread,
Apr 26, 2021, 3:10:04 PM4/26/21
to
On Mon 26 Apr 2021 at 18:27:57 (+0000), davidson wrote:
> On Mon, 26 Apr 2021 davidson wrote:
>
> Two corrections to previous message.

> > % Proposal D
> >
> > $ cat ~/.inputrc # a literal Shift-TAB is inside the double quotes
> > " ": menu-complete
>
> 2. The '^[' above is an artifact of...something. In my ~/.inputrc
> there is nothing inside those double quotes except for a literal
> Shift-TAB (encoded as ASCII ESC character 0x1b followed by TAB 0x09).

It's an "artifact" of whatever your email displays Escape with.
Mutt shows ^[ , whereas less shows ESC in inverse video.
Less -r "gobbles up" part of the string, so that you see
" menu-complete
unless you search for <SPACE>, in which case the line changes to
" ": menu-complete
(with all the spaces in inverse-video.
Emacs (my composition window in mutt) makes things less ambiguous,
displaying the ^[ in cyan.

Thanks for all the completion menus: a useful set of examples.

Cheers,
David.

Victor Sudakov

unread,
Apr 26, 2021, 11:10:03 PM4/26/21
to
davidson wrote:
> >
> > I actually looked with `hd` and expected to see 0x20 there, but
> > somehow see none of it:
> >
> > $ echo $COMP_WORDBREAKS | hd
> > 00000000 22 27 40 3e 3c 3d 3b 7c 26 28 3a 0a |"'@><=;|&(:.|
> > 0000000c
>
> Above I count 12 characters piped from echo to hd. The final character
> is a newline added by echo, so that leaves 11 characters attributable
> to the content of COMP_WORDBREAKS.
>
> But try this, below. It will tell you the length (in characters) of
> the content of COMP_WORDBREAKS.
>
> $ echo ${#COMP_WORDBREAKS}
> 14
>
> So, when you do...
>
> $ echo $COMP_WORDBREAKS | hd
> 00000000 22 27 40 3e 3c 3d 3b 7c 26 28 3a 0a |"'@><=;|&(:.|
> 0000000c
>
> ...what accounts for the three missing characters (namely SPACE, TAB,
> and NEWLINE)?
>
> TLDR: The shell's "word splitting" removes them, because you have not
> double-quoted the variable.

Oh, I see. Thanks.
signature.asc
0 new messages