From de7c201a10857e5d424dbd8db880a6f24ba250f9 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 29 Apr 2013 18:19:37 +0530 Subject: [PATCH 1/5] git-completion.bash: lexical sorting for diff.statGraphWidth df44483a (diff --stat: add config option to limit graph width, 2012-03-01) added the option diff.startGraphWidth to the list of configuration variables in git-completion.bash, but failed to notice that the list is sorted alphabetically. Move it to its rightful place in the list. Signed-off-by: Ramkumar Ramachandra Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index f67b0f008b..c8e07975db 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -2054,13 +2054,13 @@ _git_config () core.whitespace core.worktree diff.autorefreshindex - diff.statGraphWidth diff.external diff.ignoreSubmodules diff.mnemonicprefix diff.noprefix diff.renameLimit diff.renames + diff.statGraphWidth diff.suppressBlankEmpty diff.tool diff.wordRegex From 2651baaea9f9c607c09f715c7640616e39b5c60d Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 29 Apr 2013 18:19:38 +0530 Subject: [PATCH 2/5] git-completion.bash: add diff.submodule to config list c47ef57 (diff: introduce diff.submodule configuration variable, 2012-11-13) introduced the diff.submodule configuration variable, but forgot to teach git-completion.bash about it. Fix this. Signed-off-by: Ramkumar Ramachandra Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index c8e07975db..471a15e2fd 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1859,6 +1859,10 @@ _git_config () " return ;; + diff.submodule) + __gitcomp "log short" + return + ;; help.format) __gitcomp "man info web html" return @@ -2061,6 +2065,7 @@ _git_config () diff.renameLimit diff.renames diff.statGraphWidth + diff.submodule diff.suppressBlankEmpty diff.tool diff.wordRegex From a05490edbf7beb49266b3f4e4524e996428fa41d Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 29 Apr 2013 18:19:39 +0530 Subject: [PATCH 3/5] git-completion.bash: complete branch.*.rebase as boolean 6fac1b83 (completion: add missing config variables, 2009-06-29) added "rebase" to the list of completions for "branch.*.*", but forgot to specify completions for the values that this configuration variable can take (namely "false" and "true"). Fix this. Signed-off-by: Ramkumar Ramachandra Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 471a15e2fd..e769800393 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1820,6 +1820,10 @@ _git_config () __gitcomp_nl "$(__git_refs)" return ;; + branch.*.rebase) + __gitcomp "false true" + return + ;; remote.*.fetch) local remote="${prev#remote.}" remote="${remote%.fetch}" From 1ca6d4bc426435ecb87c6eb7802e83ff0a2f1667 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Sat, 27 Apr 2013 15:34:05 -0500 Subject: [PATCH 4/5] complete: zsh: trivial simplification There should be no functional changes. The only reason I wrapped this code around a sub-function is because zsh did the same in it's bashcompinit script in order to declare the special variable 'words' as hidden, but only in this context. There's no need for that any more since we access __git_main directly, so 'words' is not modified, so there's no need for the sub-function. In zsh mode the array indexes are different though. Signed-off-by: Felipe Contreras Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.zsh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh index cf8116d477..93d8f42061 100644 --- a/contrib/completion/git-completion.zsh +++ b/contrib/completion/git-completion.zsh @@ -72,14 +72,14 @@ __gitcomp_file () _git () { local _ret=1 - () { - emulate -L ksh - local cur cword prev - cur=${words[CURRENT-1]} - prev=${words[CURRENT-2]} - let cword=CURRENT-1 - __${service}_main - } + local cur cword prev + + cur=${words[CURRENT]} + prev=${words[CURRENT-1]} + let cword=CURRENT-1 + + emulate ksh -c __${service}_main + let _ret && _default -S '' && _ret=0 return _ret } From 4911589bd1cdb79e6b8f658d5caebc440a656046 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Sat, 27 Apr 2013 15:34:06 -0500 Subject: [PATCH 5/5] complete: zsh: use zsh completion for the main cmd So that we can have a nice zsh completion output: % git add -- add file contents to the index bisect -- find by binary search the change that introduced a bug branch -- list, create, or delete branches checkout -- checkout a branch or paths to the working tree clone -- clone a repository into a new directory commit -- record changes to the repository diff -- show changes between commits, commit and working tree, etc fetch -- download objects and refs from another repository grep -- print lines matching a pattern init -- create an empty Git repository or reinitialize an existing one log -- show commit logs merge -- join two or more development histories together mv -- move or rename a file, a directory, or a symlink pull -- fetch from and merge with another repository or a local branch push -- update remote refs along with associated objects rebase -- forward-port local commits to the updated upstream head reset -- reset current HEAD to the specified state rm -- remove files from the working tree and from the index show -- show various types of objects status -- show the working tree status tag -- create, list, delete or verify a tag object signed with GPG And other niceties, like 'git --git-dir=' showing only directories. For the rest, the bash completion stuff is still used. Also, add my copyright, since this more than a thin wrapper. Signed-off-by: Felipe Contreras Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.zsh | 120 +++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh index 93d8f42061..49f0cb8f69 100644 --- a/contrib/completion/git-completion.zsh +++ b/contrib/completion/git-completion.zsh @@ -2,6 +2,8 @@ # zsh completion wrapper for git # +# Copyright (c) 2012-2013 Felipe Contreras +# # You need git's bash completion script installed somewhere, by default on the # same directory as this script. # @@ -21,6 +23,9 @@ complete () return 0 } +zstyle -T ':completion:*:*:git:*' tag-order && \ + zstyle ':completion:*:*:git:*' tag-order 'common-commands' + zstyle -s ":completion:*:*:git:*" script script test -z "$script" && script="$(dirname ${funcsourcetrace[1]%:*})"/git-completion.bash ZSH_VERSION='' . "$script" @@ -69,6 +74,115 @@ __gitcomp_file () compadd -Q -p "${2-}" -f -- ${=1} && _ret=0 } +__git_zsh_bash_func () +{ + emulate -L ksh + + local command=$1 + + local completion_func="_git_${command//-/_}" + declare -f $completion_func >/dev/null && $completion_func && return + + local expansion=$(__git_aliased_command "$command") + if [ -n "$expansion" ]; then + completion_func="_git_${expansion//-/_}" + declare -f $completion_func >/dev/null && $completion_func + fi +} + +__git_zsh_cmd_common () +{ + local -a list + list=( + add:'add file contents to the index' + bisect:'find by binary search the change that introduced a bug' + branch:'list, create, or delete branches' + checkout:'checkout a branch or paths to the working tree' + clone:'clone a repository into a new directory' + commit:'record changes to the repository' + diff:'show changes between commits, commit and working tree, etc' + fetch:'download objects and refs from another repository' + grep:'print lines matching a pattern' + init:'create an empty Git repository or reinitialize an existing one' + log:'show commit logs' + merge:'join two or more development histories together' + mv:'move or rename a file, a directory, or a symlink' + pull:'fetch from and merge with another repository or a local branch' + push:'update remote refs along with associated objects' + rebase:'forward-port local commits to the updated upstream head' + reset:'reset current HEAD to the specified state' + rm:'remove files from the working tree and from the index' + show:'show various types of objects' + status:'show the working tree status' + tag:'create, list, delete or verify a tag object signed with GPG') + _describe -t common-commands 'common commands' list && _ret=0 +} + +__git_zsh_cmd_alias () +{ + local -a list + list=(${${${(0)"$(git config -z --get-regexp '^alias\.')"}#alias.}%$'\n'*}) + _describe -t alias-commands 'aliases' list $* && _ret=0 +} + +__git_zsh_cmd_all () +{ + local -a list + emulate ksh -c __git_compute_all_commands + list=( ${=__git_all_commands} ) + _describe -t all-commands 'all commands' list && _ret=0 +} + +__git_zsh_main () +{ + local curcontext="$curcontext" state state_descr line + typeset -A opt_args + local -a orig_words + + orig_words=( ${words[@]} ) + + _arguments -C \ + '(-p --paginate --no-pager)'{-p,--paginate}'[pipe all output into ''less'']' \ + '(-p --paginate)--no-pager[do not pipe git output into a pager]' \ + '--git-dir=-[set the path to the repository]: :_directories' \ + '--bare[treat the repository as a bare repository]' \ + '(- :)--version[prints the git suite version]' \ + '--exec-path=-[path to where your core git programs are installed]:: :_directories' \ + '--html-path[print the path where git''s HTML documentation is installed]' \ + '--info-path[print the path where the Info files are installed]' \ + '--man-path[print the manpath (see `man(1)`) for the man pages]' \ + '--work-tree=-[set the path to the working tree]: :_directories' \ + '--namespace=-[set the git namespace]' \ + '--no-replace-objects[do not use replacement refs to replace git objects]' \ + '(- :)--help[prints the synopsis and a list of the most commonly used commands]: :->arg' \ + '(-): :->command' \ + '(-)*:: :->arg' && return + + case $state in + (command) + _alternative \ + 'alias-commands:alias:__git_zsh_cmd_alias' \ + 'common-commands:common:__git_zsh_cmd_common' \ + 'all-commands:all:__git_zsh_cmd_all' && _ret=0 + ;; + (arg) + local command="${words[1]}" __git_dir + + if (( $+opt_args[--bare] )); then + __git_dir='.' + else + __git_dir=${opt_args[--git-dir]} + fi + + (( $+opt_args[--help] )) && command='help' + + words=( ${orig_words[@]} ) + + __git_zsh_bash_func $command + ;; + esac +} + _git () { local _ret=1 @@ -78,7 +192,11 @@ _git () prev=${words[CURRENT-1]} let cword=CURRENT-1 - emulate ksh -c __${service}_main + if (( $+functions[__${service}_zsh_main] )); then + __${service}_zsh_main + else + emulate ksh -c __${service}_main + fi let _ret && _default -S '' && _ret=0 return _ret