From patchwork Mon Nov 25 17:42:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [05, of, 11, V3] bash_completion: fix issue with subdirectories not being completed From: Sean Farley X-Patchwork-Id: 3125 Message-Id: To: mercurial-devel@selenic.com Date: Mon, 25 Nov 2013 12:42:18 -0500 # HG changeset patch # User Sean Farley # Date 1384976718 18000 # Wed Nov 20 14:45:18 2013 -0500 # Node ID df48c66a68fc2ac8705d210173202682909a3102 # Parent e5da42e61a49bfdd29b644e06fd54fc451a14e52 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