From patchwork Tue Nov 26 19:54:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [05, of, 15, V5] bash_completion: fix issue with subdirectories not being completed From: Sean Farley X-Patchwork-Id: 3159 Message-Id: <537128f084ab2cacb9be.1385499284@laptop.local> To: mercurial-devel@selenic.com Date: Tue, 26 Nov 2013 14:54:44 -0500 # HG changeset patch # User Sean Farley # Date 1384976718 18000 # Wed Nov 20 14:45:18 2013 -0500 # Node ID 537128f084ab2cacb9be8697f9f2719f992d4086 # Parent 4db0f0775ba835bd8678fee77846b39de17e5fbc 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. diff --git a/contrib/bash_completion b/contrib/bash_completion --- a/contrib/bash_completion +++ b/contrib/bash_completion @@ -82,19 +82,17 @@ _hg_debugpathcomplete() { local files="$(_hg_cmd debugpathcomplete $1 "$cur")" local IFS=$'\n' - compopt -o filenames 2>/dev/null COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur")) } _hg_status() { local files="$(_hg_cmd status -n$1 "glob:$cur**")" local IFS=$'\n' - compopt -o filenames 2>/dev/null COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur")) } _hg_bookmarks() { @@ -126,10 +124,23 @@ done 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 # global options that receive an argument local global_args='--cwd|-R|--repository' @@ -160,40 +171,46 @@ fi done 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 # global options case "$prev" in -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 # canonicalize the command name and try again help=$(_hg_cmd help "$cmd") @@ -203,10 +220,11 @@ fi cmd=${help#hg } cmd=${cmd%%[$' \n']*} canonical=1 _hg_command_specific + _hg_fix_wordlist } _hg_command_specific() { if [ "$(type -t "_hg_cmd_$cmd")" = function ]; then @@ -289,12 +307,12 @@ esac 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 # bookmarks