I'm trying to write a completion for a command (call it gs) that takes an SSH hostname as its first argument, and an arbitrary string as the second argument.

I've stolen this from the default SSH completion:

# Load completions shared by various ssh tools like ssh, scp and sftp.
__fish_complete_ssh ssh
# Also retrieve `user@host` entries from history
function __ssh_history_completions
    history --prefix ssh --max=100 | string replace -rf '.* ([A-Za-z0-9._:-]+@[A-Za-z0-9._:-]+).*' '$1'

And I use it to complete the arguments to my gs command:

complete -c gs -d Remote -xa "(__fish_complete_user_at_hosts)"
complete -c gs -d Remote -ka '(__ssh_history_completions)'

This works, but it completes SSH hostnames for both arguments:

  • if I type gs <tab>, fish correctly completes SSH hostnames,
  • if I type gs somehost <tab>, fish incorrectly completes SSH hostnames again (this argument should just not be completed, it's an arbitrary string).

How can I make this completion only affect the first positional argument to my command?

1 Answer 1


Use the --condition or -n option to complete, with the helper function __fish_is_first_arg:

complete -c gs -d Remote -xa "(__fish_complete_user_at_hosts)" -n '__fish_is_first_arg'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .