[Bash-completion-commits] [SCM] bash-completion branch, master, updated. b6434541ccae0d24dae6d567ac3a7f6b72235c5e

Ville Skyttä ville.skytta at iki.fi
Sat Dec 26 14:20:38 UTC 2009


The following commit has been merged in the master branch:
commit 000cae95bc2c64692bd3fce1cfbe8ab1779580d6
Author: Ville Skyttä <ville.skytta at iki.fi>
Date:   Sat Dec 26 16:19:24 2009 +0200

    Add dir-only handling to scp remote/local completion functions, operate directly on $cur.

diff --git a/contrib/rsync b/contrib/rsync
index f273e0d..146c8bd 100644
--- a/contrib/rsync
+++ b/contrib/rsync
@@ -70,7 +70,7 @@ _rsync()
                         break
                     fi
                 done
-                [ "$shell" = ssh ] && _scp_remote_files "$cur"
+                [ "$shell" = ssh ] && _scp_remote_files
             fi
             ;;
         *)
diff --git a/contrib/ssh b/contrib/ssh
index 5e1035f..a545406 100644
--- a/contrib/ssh
+++ b/contrib/ssh
@@ -246,12 +246,14 @@ shopt -u hostcomplete && complete -F _sftp sftp
 # things we want to escape in remote scp paths
 _scp_path_esc="[][(){}<>\",:;^&\!$=?\`|\\ ']"
 
+# Complete remote files with ssh.  If the first arg is -d, complete on dirs
+# only.  Returns paths escaped with three backslashes.
 _scp_remote_files()
 {
     local IFS=$'\t\n'
 
     # remove backslash escape from the first colon
-    local cur=${1/\\:/:}
+    cur=${cur/\\:/:}
 
     local userhost=${cur%%?(\\):*}
     local path=${cur#*:}
@@ -264,23 +266,45 @@ _scp_remote_files()
         path=$(ssh -o 'Batchmode yes' $userhost pwd 2>/dev/null)
     fi
 
-    # escape spaces; remove executables, aliases, pipes and sockets;
-    # add space at end of file names
-    COMPREPLY=( "${COMPREPLY[@]}" $( ssh -o 'Batchmode yes' $userhost \
-        command ls -aF1d "$path*" 2>/dev/null | \
-        sed -e 's/'$_scp_path_esc'/\\\\\\&/g' -e 's/[*@|=]$//g' \
-        -e 's/[^\/]$/& /g' ) )
+    local files
+    if [ "$1" = -d ] ; then
+        # escape problematic characters; remove non-dirs
+        files=$( ssh -o 'Batchmode yes' $userhost \
+            command ls -aF1d "$path*" 2>/dev/null | \
+            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
+        files=$( ssh -o 'Batchmode yes' $userhost \
+            command ls -aF1d "$path*" 2>/dev/null | \
+            sed -e 's/'$_scp_path_esc'/\\\\\\&/g' -e 's/[*@|=]$//g' \
+            -e 's/[^\/]$/& /g' )
+    fi
+    COMPREPLY=( "${COMPREPLY[@]}" $files )
 }
 
 # This approach is used instead of _filedir to get a space appended
 # after local file/dir completions, and -o nospace retained for others.
-# Args: 1=prefix to strip (optional)
+# If first arg is -d, complete on directory names only.  The next arg is
+# an optional prefix to add to returned completions.
 _scp_local_files()
 {
     local IFS=$'\t\n'
-    COMPREPLY=( "${COMPREPLY[@]}" $( command ls -aF1d $cur* 2>/dev/null | \
-        sed -e "s/$_scp_path_esc/\\\\&/g" -e 's/[*@|=]$//g' \
-        -e 's/[^\/]$/& /g' -e "s/^/$1/") )
+
+    local dirsonly=false
+    if [ "$1" = -d ]; then
+        dirsonly=true
+        shift
+    fi
+
+    if $dirsonly ; then
+        COMPREPLY=( "${COMPREPLY[@]}" $( command ls -aF1d $cur* 2>/dev/null | \
+            sed -e "s/$_scp_path_esc/\\\\&/g" -e '/[^\/]$/d' -e "s/^/$1/") )
+    else
+        COMPREPLY=( "${COMPREPLY[@]}" $( command ls -aF1d $cur* 2>/dev/null | \
+            sed -e "s/$_scp_path_esc/\\\\&/g" -e 's/[*@|=]$//g' \
+            -e 's/[^\/]$/& /g' -e "s/^/$1/") )
+    fi
 }
 
 # scp(1) completion
@@ -321,7 +345,7 @@ _scp()
     _expand || return 0
 
     if [[ "$cur" == *:* ]]; then
-        _scp_remote_files "$cur"
+        _scp_remote_files
         return 0
     fi
 

-- 
bash-completion



More information about the Bash-completion-commits mailing list