I'm trying to create an autocomplete script for use with fish; i'm porting over a bash completion script for the same program.
The program has three top level commands, say foo
, bar
, and baz
and each has some subcommands, just say a
b
and c
for each.
What I'm seeing is that the top level commands auto complete ok, so if I type f
I'm getting foo
to autocomplete, but then if I hit tab again to see what it's sub commands are, i see foo
, bar
, baz
, a
, b
, c
and it should just be a
, b
, c
I am using as a reference the git completion script since it seems to work right. I am also using the git flow script as a reference as well.
I think this is handled in the git completion script by:
function __fish_git_needs_command
set cmd (commandline -opc)
if [ (count $cmd) -eq 1 -a $cmd[1] = 'git' ]
return 0
end
return 1
end
Which makes sense, you can only use the completion if there is a single arg to the command, the script itself; if you use that as the condition (-n
) for the call to complete on the top level commands, I think the right thing would happen.
However, what I'm seeing is not the case. I copied that function over to my script, changed "git" appropriately, and did not have any luck.
The trimmed down script is as follows:
function __fish_prog_using_command
set cmd (commandline -opc)
set subcommands $argv
if [ (count $cmd) = (math (count $subcommands) + 1) ]
for i in (seq (count $subcommands))
if not test $subcommands[$i] = $cmd[(math $i + 1)]
return 1
end
end
return 0
end
return 1
end
function __fish_git_needs_command
set cmd (commandline -opc)
set startsWith (echo "$cmd[1]" | grep -E 'prog$')
# there's got to be a better way to do this regex, fish newb alert
if [ (count $cmd) = 1 ]
# Is this always false? Is this the problem?
if [ $cmd[1] -eq $cmd[1] ]
return 1
end
end
return 0
end
complete --no-files -c prog -a bar -n "__fish_git_needs_command"
complete --no-files -c prog -a foo -n "__fish_git_needs_command"
complete --no-files -c prog -a a -n "__fish_prog_using_command foo"
complete --no-files -c prog -a b -n "__fish_prog_using_command foo"
complete --no-files -c prog -a c -n "__fish_prog_using_command foo"
complete --no-files -c prog -a baz -n "__fish_git_needs_command"
Any suggestions on how to make this work is much appreciated.
I guess you are aware that return 0
means true and that return 1
means false?
From your output it looks like your needs_command
function is not working properly, thus showing bar even when it has subcommands.
I just tried the following code and it works as expected:
function __fish_prog_needs_command
set cmd (commandline -opc)
if [ (count $cmd) -eq 1 -a $cmd[1] = 'prog' ]
return 0
end
return 1
end
function __fish_prog_using_command
set cmd (commandline -opc)
if [ (count $cmd) -gt 1 ]
if [ $argv[1] = $cmd[2] ]
return 0
end
end
return 1
end
complete -f -c prog -n '__fish_prog_needs_command' -a bar
complete -f -c prog -n '__fish_prog_needs_command' -a foo
complete -f -c prog -n '__fish_prog_using_command foo' -a a
complete -f -c prog -n '__fish_prog_using_command foo' -a b
complete -f -c prog -n '__fish_prog_using_command foo' -a c
complete -f -c prog -n '__fish_prog_needs_command' -a baz
Output from completion:
➤ prog <Tab>
bar baz foo
➤ prog foo <Tab>
a b c
➤ prog foo
Is this what you want?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With