From 0c92c7d8acc591dbb9222a90696966adfc6a1cf3 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Mon, 13 Jan 2020 10:18:43 +0100 Subject: [PATCH] Fix remote path escaping for rsync and scp completions They need to be escaped twice, for the local and the remote shell. Also don't suggest local files as rsync remote paths (-a -> -xa) and fix completion for remote paths containing multiple consecutive spaces. Fixes #1872 [ci skip] --- share/completions/rsync.fish | 8 +++++--- share/completions/scp.fish | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/share/completions/rsync.fish b/share/completions/rsync.fish index d270c0dfb..39aeff3f6 100644 --- a/share/completions/rsync.fish +++ b/share/completions/rsync.fish @@ -1,5 +1,5 @@ function __rsync_remote_target - commandline -ct | string match -r '.*::?(?:.*/)?' + commandline -ct | string match -r '.*::?(?:.*/)?' | string unescape end complete -c rsync -s v -l verbose -d "Increase verbosity" @@ -125,12 +125,14 @@ complete -c rsync -d Hostname -a " # # Remote path # -complete -c rsync -d "Remote path" -n "commandline -ct | string match -q '*:*'" -a " +complete -c rsync -d "Remote path" -n "commandline -ct | string match -q '*:*'" -xa " ( # Prepend any user@host:/path information supplied before the remote completion. __rsync_remote_target )( # Get the list of remote files from the specified rsync server. - rsync --list-only (__rsync_remote_target) 2>/dev/null | string replace -r '^d.*' '\$0/' | tr -s ' ' | cut -d' ' -f 5- + rsync --list-only (__rsync_remote_target) 2>/dev/null | string replace -r '^d.*' '\$0/' | + string replace -r '(\S+\s+){4}' '' | # drop the first four columns + string escape -n ) " diff --git a/share/completions/scp.fish b/share/completions/scp.fish index c7b05ac3f..41a659906 100644 --- a/share/completions/scp.fish +++ b/share/completions/scp.fish @@ -54,7 +54,8 @@ complete -c scp -d "Local Path" -n "not string match @ -- (commandline -ct)" # Get the list of remote files from the scp target. complete -c scp -d "Remote Path" -f -n "commandline -ct | string match -e ':'" -a " (__scp_remote_target):( \ - command ssh (__scp2ssh_port_number) -o 'BatchMode yes' (__scp_remote_target) /bin/ls\ -dp\ (__scp_remote_path_prefix)\* 2>/dev/null + command ssh (__scp2ssh_port_number) -o 'BatchMode yes' (__scp_remote_target) /bin/ls\ -dp\ (__scp_remote_path_prefix | string unescape)\* 2>/dev/null | + string escape -n ) " complete -c scp -s B -d "Batch mode"