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

Ville Skyttä ville.skytta at iki.fi
Fri Dec 25 10:30:55 UTC 2009


The following commit has been merged in the master branch:
commit 329890a73b14b4fc32e9fdd3e8148c9eebbe2ffc
Author: Ville Skyttä <ville.skytta at iki.fi>
Date:   Fri Dec 25 12:30:01 2009 +0200

    Extract scp local/remote file treatment into functions, reuse them in rsync.

diff --git a/contrib/rsync b/contrib/rsync
index 8ddcc97..f273e0d 100644
--- a/contrib/rsync
+++ b/contrib/rsync
@@ -5,11 +5,9 @@ _rsync()
 {
     # TODO: _split_longopt
 
-    local cur prev shell i userhost path
-
     COMPREPLY=()
-    cur=`_get_cword :`
-    prev=${COMP_WORDS[COMP_CWORD-1]}
+    local cur=`_get_cword :`
+    local prev=`_get_pword :`
 
     _expand || return 0
 
@@ -63,42 +61,27 @@ _rsync()
                 --no-detach' -- "$cur" ) )
             ;;
         *:*)
-            # find which remote shell is used
-            shell=ssh
-            for (( i=1; i < COMP_CWORD; i++ )); do
-                if [[ "${COMP_WORDS[i]}" == -@(e|-rsh) ]]; then
-                    shell=${COMP_WORDS[i+1]}
-                    break
-                fi
-            done
-            if [[ "$shell" == ssh ]]; then
-                # remove backslash escape from :
-                cur=${cur/\\:/:}
-                userhost=${cur%%?(\\):*}
-                path=${cur#*:}
-                # unescape spaces
-                path=${path//\\\\\\\\ / }
-                if [ -z "$path" ]; then
-                    # default to home dir of specified user on remote host
-                    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=( $( ssh -o 'Batchmode yes' $userhost \
-                    command ls -aF1d "$path*" 2>/dev/null | \
-                    sed -e 's/ /\\\\\\\ /g' -e 's/[*@|=]$//g' \
-                    -e 's/[^\/]$/& /g' ) )
+            if type _scp_remote_files &>/dev/null; then
+                # find which remote shell is used
+                local i shell=ssh
+                for (( i=1; i < COMP_CWORD; i++ )); do
+                    if [[ "${COMP_WORDS[i]}" == -@(e|-rsh) ]]; then
+                        shell=${COMP_WORDS[i+1]}
+                        break
+                    fi
+                done
+                [ "$shell" = ssh ] && _scp_remote_files "$cur"
             fi
             ;;
         *)
             _known_hosts_real -c -a "$cur"
-            _filedir
+            type _scp_local_files &>/dev/null && _scp_local_files || _filedir
             ;;
     esac
 
     return 0
 } &&
-complete -F _rsync -o nospace -o filenames rsync
+complete -F _rsync -o nospace rsync
 
 # Local variables:
 # mode: shell-script
diff --git a/contrib/ssh b/contrib/ssh
index a8950a2..5e1035f 100644
--- a/contrib/ssh
+++ b/contrib/ssh
@@ -243,12 +243,51 @@ _sftp()
 }
 shopt -u hostcomplete && complete -F _sftp sftp
 
+# things we want to escape in remote scp paths
+_scp_path_esc="[][(){}<>\",:;^&\!$=?\`|\\ ']"
+
+_scp_remote_files()
+{
+    local IFS=$'\t\n'
+
+    # remove backslash escape from the first colon
+    local cur=${1/\\:/:}
+
+    local userhost=${cur%%?(\\):*}
+    local path=${cur#*:}
+
+    # unescape (3 backslashes to 1 for chars we escaped)
+    path=$( sed -e 's/\\\\\\\('$_scp_path_esc'\)/\\\1/g' <<<"$path" )
+
+    # default to home dir of specified user on remote host
+    if [ -z "$path" ]; then
+        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' ) )
+}
+
+# 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)
+_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/") )
+}
 
 # scp(1) completion
 #
 _scp()
 {
-    local configfile cur prev userhost path prefix
+    local configfile cur prev prefix
 
     COMPREPLY=()
     cur=`_get_cword ":"`
@@ -281,30 +320,12 @@ _scp()
 
     _expand || return 0
 
-    # things we want to backslash escape
-    local esc="[][(){}<>\",:;^&\!$=?\`|\\ ']"
-
     if [[ "$cur" == *:* ]]; then
-        local IFS=$'\t\n'
-        # remove backslash escape from the first colon
-        cur=${cur/\\:/:}
-        userhost=${cur%%?(\\):*}
-        path=${cur#*:}
-        # unescape (3 backslashes to 1 for chars we escaped)
-        path=$( sed -e 's/\\\\\\\('$esc'\)/\\\1/g' <<<"$path" )
-        if [ -z "$path" ]; then
-            # default to home dir of specified user on remote host
-            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=( $( ssh -o 'Batchmode yes' $userhost \
-            command ls -aF1d "$path*" 2>/dev/null | \
-            sed -e 's/'$esc'/\\\\\\&/g' -e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' ) )
+        _scp_remote_files "$cur"
         return 0
     fi
 
-    if [[ "$cur" = -F* ]]; then
+    if [[ "$cur" == -F* ]]; then
         cur=${cur#-F}
         prefix=-F
     else
@@ -339,12 +360,7 @@ _scp()
         esac
     fi
 
-    # This approach is used instead of _filedir to get a space appended
-    # after local file/dir completions, and -o nospace retained for others.
-    local IFS=$'\t\n'
-    COMPREPLY=( "${COMPREPLY[@]}" $( command ls -aF1d $cur* 2>/dev/null | \
-        sed -e "s/$esc/\\\\&/g" -e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' \
-        -e "s/^/$prefix/") )
+    _scp_local_files "$prefix"
 
     return 0
 }

-- 
bash-completion



More information about the Bash-completion-commits mailing list