diff --git a/share/completions/scp.fish b/share/completions/scp.fish index 32b1d06e8..0b14ceaad 100644 --- a/share/completions/scp.fish +++ b/share/completions/scp.fish @@ -8,7 +8,14 @@ __fish_complete_ssh scp # scp specific completions # -complete -c scp -d Hostname -a " +# +# Hostname +# +complete \ + --command scp \ + --description Hostname \ + --condition "commandline --cut-at-cursor --current-token | string match --invert '*:*'" \ + --arguments " (__fish_print_hostnames): @@ -17,14 +24,28 @@ complete -c scp -d Hostname -a " commandline -ct |sed -ne 's/\(.*@\).*/\1/p' )(__fish_print_hostnames): -(__fish_print_users)@\tUsername +# Disable as username completion is not very useful +# (__fish_print_users)@\tUsername " +# +# Local path +# +complete \ + --command scp \ + --description "Local Path" \ + --condition "commandline -ct | string match ':'" + # # Remote path # -complete -c scp -d "Remote Path" -n "commandline -ct| __fish_sgrep -o '.*:'" -a " +complete \ + --command scp \ + --description "Remote Path" \ + --no-files \ + --condition "commandline --cut-at-cursor --current-token | string match --regex '.+:'" \ + --arguments " ( #Prepend any user@host information supplied before the remote completion @@ -43,4 +64,3 @@ complete -c scp -s p --description "Preserves modification times, access times, complete -c scp -s q --description "Do not display progress bar" complete -c scp -s r --description "Recursively copy" complete -c scp -s S --description "Encryption program" - diff --git a/share/completions/ssh.fish b/share/completions/ssh.fish index 691302982..10205d1f9 100644 --- a/share/completions/ssh.fish +++ b/share/completions/ssh.fish @@ -14,9 +14,10 @@ complete -x -c ssh -d Hostname -a " )(__fish_print_hostnames) " -complete -x -c ssh -d User -a " -(__fish_print_users | string match -r -v '^_')@ -" +# Disable as username completion is not very useful +# complete -x -c ssh -d User -a " +# (__fish_print_users | string match -r -v '^_')@ +# " complete -c ssh --description "Command to run" -x -a '(__fish_complete_subcommand --fcs-skip=2)' complete -c ssh -s a --description "Disables forwarding of the authentication agent" diff --git a/share/functions/__fish_print_hostnames.fish b/share/functions/__fish_print_hostnames.fish index 4bec16fb3..c9f5bd23e 100644 --- a/share/functions/__fish_print_hostnames.fish +++ b/share/functions/__fish_print_hostnames.fish @@ -1,16 +1,23 @@ function __fish_print_hostnames -d "Print a list of known hostnames" - # HACK: This only deals with ipv4 - # Print all hosts from /etc/hosts # use 'getent hosts' on OSes that support it (OpenBSD and Cygwin do not) - if type -q getent - and getent hosts >/dev/null 2>&1 # test if 'getent hosts' works and redirect output so errors don't print + if type -q getent; and getent hosts >/dev/null 2>&1 # test if 'getent hosts' works and redirect output so errors don't print # Ignore zero ips - getent hosts | string match -r -v '^0.0.0.0' | string replace -r '[0-9.]*\s*' '' | string split " " + getent hosts | string match --regex --invert '^0.0.0.0' \ + # Remove left addresses column + | string replace --regex '^\s*\S+\s+' '' \ + # Tokenize remaining hostnames and aliases columnss + | string split ' ' else if test -r /etc/hosts - # Ignore commented lines and functionally empty lines. Strip comments. - string match -r -v '^\s*0.0.0.0|^\s*#|^\s*$' /dev/null + set paths[$path_index] $relative_path/$paths[$path_index] + end + echo $paths[$path_index] + end + _recursive $paths + end + end + _recursive $ssh_config + end + set -l ssh_configs (_ssh_include /etc/ssh/ssh_config) (_ssh_include $ssh_config) + + for file in $ssh_configs if test -r $file # Print hosts from system wide ssh configuration file - # Note the non-capturing group to avoid printing "name" - string match -ri '\s*Host(?:name)?(?:\s+|\s*=\s*)\w.*' <$file | string replace -ri '^\s*Host(?:name)?\s*(\S+)' '$1' | string replace -r '\s+' ' ' | string split ' ' - set known_hosts $known_hosts (string match -ri '^\s*UserKnownHostsFile|^\s*GlobalKnownHostsFile' < $file \ - | string replace -ri '.*KnownHostsFile\s*' '') + string match --regex --ignore-case '^\s*Host\s+\S+' <$file \ + # We only want the value(s) + | string replace --regex --ignore-case '^\s*Host\s+' '' \ + # Print one per line + | string trim | string replace --regex '\s+' ' ' | string split ' ' \ + # Ignore hosts with a glob + | string match --invert '*\**' + # Extract known_host paths + set known_hosts $known_hosts (string match -ri '^\s*UserKnownHostsFile|^\s*GlobalKnownHostsFile' <$file \ + | string replace -ri '.*KnownHostsFile\s*' '') end end for file in $known_hosts