From 8a8dde930c9ec25df2279f6495e970faad970527 Mon Sep 17 00:00:00 2001 From: gokhan Date: Tue, 12 Apr 2022 03:43:36 +0300 Subject: [PATCH 1/6] scp remote file completion extended with port parsing --- completions/ssh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/completions/ssh b/completions/ssh index 06ac0bd21f4..dd7bbe1cdb6 100644 --- a/completions/ssh +++ b/completions/ssh @@ -427,6 +427,10 @@ _scp_path_esc='[][(){}<>"'"'"',:;^&!$=?`\\|[:space:]]' _scp_remote_files() { local IFS=$'\n' + + # Parse port number from whole command + __sshport=`echo ${COMP_WORDS[@]} | sed -n 's/.*-*P\([ 0-9]*\)[ ].*/\1/p' ` + [[ -n $"{__sshport// }" ]] && __sshoption="-p $__sshport" || __sshoption="" # remove backslash escape from the first colon cur=${cur/\\:/:} @@ -440,21 +444,21 @@ _scp_remote_files() # default to home dir of specified user on remote host if [[ -z $path ]]; then - path=$(ssh -o 'Batchmode yes' "$userhost" pwd 2>/dev/null) + path=$(ssh $__sshoption -o 'Batchmode yes' "$userhost" pwd 2>/dev/null) fi local files if [[ ${1-} == -d ]]; then # escape problematic characters; remove non-dirs # shellcheck disable=SC2090 - files=$(ssh -o 'Batchmode yes' "$userhost" \ + files=$(ssh $__sshoption -o 'Batchmode yes' "$userhost" \ command ls -aF1dL "$path*" 2>/dev/null | command sed -e 's/'"$_scp_path_esc"'/\\\\\\&/g' -e '/[^\/]$/d') else # escape problematic characters; remove executables, aliases, pipes # and sockets; add space at end of file names # shellcheck disable=SC2090 - files=$(ssh -o 'Batchmode yes' "$userhost" \ + files=$(ssh $__sshoption -o 'Batchmode yes' "$userhost" \ command ls -aF1dL "$path*" 2>/dev/null | command sed -e 's/'"$_scp_path_esc"'/\\\\\\&/g' -e 's/[*@|=]$//g' \ -e 's/[^\/]$/& /g') From b9374816cb019fbe2ab325ade2a7390850ac147e Mon Sep 17 00:00:00 2001 From: gokhan Date: Tue, 12 Apr 2022 11:10:52 +0300 Subject: [PATCH 2/6] minor fix for parsing, solves hostname patterns problem --- completions/ssh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/completions/ssh b/completions/ssh index dd7bbe1cdb6..1b3074203a3 100644 --- a/completions/ssh +++ b/completions/ssh @@ -429,7 +429,7 @@ _scp_remote_files() local IFS=$'\n' # Parse port number from whole command - __sshport=`echo ${COMP_WORDS[@]} | sed -n 's/.*-*P\([ 0-9]*\)[ ].*/\1/p' ` + __sshport=`echo ${COMP_WORDS[@]} | sed -n 's/^.*\( -\w*P\)\([ 0-9]*\)[ ].*/\2/p' ` [[ -n $"{__sshport// }" ]] && __sshoption="-p $__sshport" || __sshoption="" # remove backslash escape from the first colon From 05839eb54d5a880a56e7bf7d1132b509301633dd Mon Sep 17 00:00:00 2001 From: gokhan Date: Wed, 13 Apr 2022 00:50:55 +0300 Subject: [PATCH 3/6] fix issues from @akinomyoga suggestions --- completions/ssh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/completions/ssh b/completions/ssh index 1b3074203a3..d5069c91ef2 100644 --- a/completions/ssh +++ b/completions/ssh @@ -429,8 +429,8 @@ _scp_remote_files() local IFS=$'\n' # Parse port number from whole command - __sshport=`echo ${COMP_WORDS[@]} | sed -n 's/^.*\( -\w*P\)\([ 0-9]*\)[ ].*/\2/p' ` - [[ -n $"{__sshport// }" ]] && __sshoption="-p $__sshport" || __sshoption="" + local sshport=$(command echo ${COMP_WORDS[@]} | command sed -n 's/^.*\( -[a-zA-Z0-9]*P\)\([ 0-9][0-9]*\)[ ].*/\2/p') + [[ -n "${sshport// }" ]] && local sshoption="-p $sshport" || local sshoption="" # remove backslash escape from the first colon cur=${cur/\\:/:} @@ -444,21 +444,21 @@ _scp_remote_files() # default to home dir of specified user on remote host if [[ -z $path ]]; then - path=$(ssh $__sshoption -o 'Batchmode yes' "$userhost" pwd 2>/dev/null) + path=$(ssh $sshoption -o 'Batchmode yes' "$userhost" pwd 2>/dev/null) fi local files if [[ ${1-} == -d ]]; then # escape problematic characters; remove non-dirs # shellcheck disable=SC2090 - files=$(ssh $__sshoption -o 'Batchmode yes' "$userhost" \ + files=$(ssh $sshoption -o 'Batchmode yes' "$userhost" \ command ls -aF1dL "$path*" 2>/dev/null | command sed -e 's/'"$_scp_path_esc"'/\\\\\\&/g' -e '/[^\/]$/d') else # escape problematic characters; remove executables, aliases, pipes # and sockets; add space at end of file names # shellcheck disable=SC2090 - files=$(ssh $__sshoption -o 'Batchmode yes' "$userhost" \ + files=$(ssh $sshoption -o 'Batchmode yes' "$userhost" \ command ls -aF1dL "$path*" 2>/dev/null | command sed -e 's/'"$_scp_path_esc"'/\\\\\\&/g' -e 's/[*@|=]$//g' \ -e 's/[^\/]$/& /g') From d217b9d312f37e3e2ec7fdf5cf7afc7c38bf4125 Mon Sep 17 00:00:00 2001 From: gokhan Date: Wed, 13 Apr 2022 01:47:23 +0300 Subject: [PATCH 4/6] minor fix for multiple space chars btw -P and portnumbers --- completions/ssh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/completions/ssh b/completions/ssh index d5069c91ef2..2170bb47ab1 100644 --- a/completions/ssh +++ b/completions/ssh @@ -429,7 +429,7 @@ _scp_remote_files() local IFS=$'\n' # Parse port number from whole command - local sshport=$(command echo ${COMP_WORDS[@]} | command sed -n 's/^.*\( -[a-zA-Z0-9]*P\)\([ 0-9][0-9]*\)[ ].*/\2/p') + local sshport=$(command echo ${COMP_WORDS[@]} | command sed -n 's/^.*\( -[a-zA-Z0-9]*P\)\([ ]*[0-9]*\)[ ].*/\2/p') [[ -n "${sshport// }" ]] && local sshoption="-p $sshport" || local sshoption="" # remove backslash escape from the first colon From f1476ba8c146172890d75d86b8f477f6094f87e0 Mon Sep 17 00:00:00 2001 From: gokhan Date: Fri, 15 Apr 2022 03:24:59 +0300 Subject: [PATCH 5/6] port parser moved to _scp; words is using for parse now, now '-o PORT' is also parsing --- completions/ssh | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/completions/ssh b/completions/ssh index 2170bb47ab1..897d5e4e550 100644 --- a/completions/ssh +++ b/completions/ssh @@ -366,6 +366,7 @@ _sftp() local ipvx + case $prev in -*[BDlPRs]) return @@ -427,11 +428,9 @@ _scp_path_esc='[][(){}<>"'"'"',:;^&!$=?`\\|[:space:]]' _scp_remote_files() { local IFS=$'\n' - - # Parse port number from whole command - local sshport=$(command echo ${COMP_WORDS[@]} | command sed -n 's/^.*\( -[a-zA-Z0-9]*P\)\([ ]*[0-9]*\)[ ].*/\2/p') - [[ -n "${sshport// }" ]] && local sshoption="-p $sshport" || local sshoption="" - + + sshoption=$1 + # remove backslash escape from the first colon cur=${cur/\\:/:} @@ -507,6 +506,31 @@ _scp() } local ipvx + + # Parse Port number from command + local sshport="" + local sshoption="" + local i + for ((i = 0; i < ${#words[@]}; i++)); do + if [[ ${words[i]} =~ -[a-zA-Z0-9]*P[0-9]*$ ]]; then + if [[ ${words[i]: -1} == P ]]; then + ((i+=1)) + [[ ${words[i]} =~ ^[0-9]+$ ]] && sshport=${words[i]} + else + sshport=$(echo ${words[i]} | command sed -n 's/-.*P\([0-9]\{1,\}\)/\1/p') + fi + elif [[ ${words[i]} =~ -[a-zA-Z0-9]*o$ ]]; then + if [[ ${words[i+1],,} == port ]]; then + ((i+=3)) + [[ ${words[i]} =~ ^[0-9]+$ ]] && sshport=${words[i]} + fi + elif [[ ${words[i]} =~ -[a-zA-Z0-9]*o[pP][oO][rR][tT]$ ]]; then + ((i+=2)) + [[ ${words[i]} =~ ^[0-9]+$ ]] && sshport=${words[i]} + fi + done + + [[ ${sshport// } ]] && sshoption="-p $sshport" case $prev in -*c) @@ -553,7 +577,7 @@ _scp() case $cur in !(*:*)/* | [.~]*) ;; # looks like a path *:*) - _scp_remote_files + _scp_remote_files "$sshoption" return ;; esac From 5b8dceba89ef858a917f612ddea9051c98ee3813 Mon Sep 17 00:00:00 2001 From: gokhan Date: Fri, 15 Apr 2022 17:48:37 +0300 Subject: [PATCH 6/6] _comp_xfunc_ssh_scp_remote_files() function argument parser for -d and -p options --- completions/ssh | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/completions/ssh b/completions/ssh index dfa42f75101..f6896c9f0f6 100644 --- a/completions/ssh +++ b/completions/ssh @@ -430,14 +430,24 @@ _sftp() # shellcheck disable=SC2089 _comp_cmd_scp__path_esc='[][(){}<>"'"'"',:;^&!$=?`\\|[:space:]]' -# Complete remote files with ssh. If the first arg is -d, complete on dirs -# only. Returns paths escaped with three backslashes. +# Complete remote files with ssh. If the arg is -d, complete on dirs +# only. Returns paths escaped with three backslashes. +# Pass argument as "-p portnumber" for non-default ssh connection port. # shellcheck disable=SC2120 _comp_xfunc_ssh_scp_remote_files() { local IFS=$'\n' - sshoption=$1 + local sshoption + local dirsonly=false + local i + for i in "$@"; do + if [[ ${i-} == -d ]]; then + dirsonly=true + elif [[ ${i:0:2} == -p ]]; then + sshoption=$1 + fi + done # remove backslash escape from the first colon cur=${cur/\\:/:} @@ -455,7 +465,7 @@ _comp_xfunc_ssh_scp_remote_files() fi local files - if [[ ${1-} == -d ]]; then + if $dirsonly; then # escape problematic characters; remove non-dirs # shellcheck disable=SC2090 files=$(ssh $sshoption -o 'Batchmode yes' "$userhost" \