bash_completion: fix issue with subdirectories not being completed
authorSean Farley <sean.michael.farley@gmail.com>
Wed, 20 Nov 2013 14:45:18 -0500
changeset 20126 25cb1d96c307
parent 20125 191ab08e7099
child 20127 6b771bcd1a62
bash_completion: fix issue with subdirectories not being completed Previously, if there was a directory between the file and first-level directory (e.g. 'bar' in foo/bar/file), then bash_completion would only list 'foo/file' instead of 'foo/bar/file'. This behavior was introduced in 80f3ae36f908 to fix spaces in file names. In this patch, we keep that behavior while also fixing subdirectory completion by reverting 80f3ae36f908 and instead add backslashes to whitespace manually. This approach means adding the completion option 'nospace' since we do this manually now.
contrib/bash_completion
--- a/contrib/bash_completion	Wed Nov 20 13:19:55 2013 -0500
+++ b/contrib/bash_completion	Wed Nov 20 14:45:18 2013 -0500
@@ -84,7 +84,6 @@
 {
     local files="$(_hg_cmd debugpathcomplete $1 "$cur")"
     local IFS=$'\n'
-    compopt -o filenames 2>/dev/null
     COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
 }
 
@@ -92,7 +91,6 @@
 {
     local files="$(_hg_cmd status -n$1 "glob:$cur**")"
     local IFS=$'\n'
-    compopt -o filenames 2>/dev/null
     COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur"))
 }
 
@@ -128,6 +126,19 @@
     echo $(($count - 1))
 }
 
+_hg_fix_wordlist()
+{
+    local LASTCHAR=' '
+    if [ ${#COMPREPLY[@]} = 1 ]; then
+        [ -d "$COMPREPLY" ] && LASTCHAR=/
+        COMPREPLY=$(printf %q%s "$COMPREPLY" "$LASTCHAR")
+    else
+        for ((i=0; i < ${#COMPREPLY[@]}; i++)); do
+            [ -d "${COMPREPLY[$i]}" ] && COMPREPLY[$i]=${COMPREPLY[$i]}/
+        done
+    fi
+}
+
 _hg()
 {
     local cur prev cmd cmd_index opts i aliashg
@@ -162,12 +173,14 @@
 
     if [[ "$cur" == -* ]]; then
         if [ "$(type -t "_hg_opt_$cmd")" = function ] && "_hg_opt_$cmd"; then
+            _hg_fix_wordlist
             return
         fi
 
         opts=$(_hg_cmd debugcomplete --options "$cmd")
 
         COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur"))
+        _hg_fix_wordlist
         return
     fi
 
@@ -176,22 +189,26 @@
         -R|--repository)
             _hg_paths
             _hg_repos
+            _hg_fix_wordlist
             return
         ;;
         --cwd)
             # Stick with default bash completion
+            _hg_fix_wordlist
             return
         ;;
     esac
 
     if [ -z "$cmd" ] || [ $COMP_CWORD -eq $i ]; then
         _hg_commands
+        _hg_fix_wordlist
         return
     fi
 
     # try to generate completion candidates for whatever command the user typed
     local help
     if _hg_command_specific; then
+        _hg_fix_wordlist
         return
     fi
 
@@ -205,6 +222,7 @@
     cmd=${cmd%%[$' \n']*}
     canonical=1
     _hg_command_specific
+    _hg_fix_wordlist
 }
 
 _hg_command_specific()
@@ -291,8 +309,8 @@
     return 0
 }
 
-complete -o bashdefault -o default -F _hg hg \
-    || complete -o default -F _hg hg
+complete -o bashdefault -o default -o nospace -F _hg hg \
+    || complete -o default -o nospace -F _hg hg
 
 
 # Completion for commands provided by extensions