[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: bash completion and spaces



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




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


Reply to: