{"thread":{"id":"33656","subject":"[PATCH 0/2] completion: zsh: nice stuff","startedAt":"2013-04-27T20:34:04Z","lastAt":"2013-04-27T21:53:49Z","messageCount":5,"participants":["Felipe Contreras","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"215752","messageId":"1367094846-9830-1-git-send-email-felipe.contreras@gmail.com","threadId":"33656","inReplyTo":null,"subject":"[PATCH 0/2] completion: zsh: nice stuff","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-27T20:34:04Z","receivedAt":"2013-04-27T20:34:04Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Hi,\n\nOur thin wrapper seems to be doing a good job of providing all the bash\nfunctionality, to zsh, however, we can do more.\n\nThis patch enables zsh-specific functionality to list the main commands, and\ngeneral options. So we get:\n\n  % git <tab>\n  add       -- add file contents to the index\n  bisect    -- find by binary search the change that introduced a bug\n  branch    -- list, create, or delete branches\n  checkout  -- checkout a branch or paths to the working tree\n  clone     -- clone a repository into a new directory\n  ...\n\nAnd:\n\n  % git --\n  --bare      -- treat the repository as a bare repository\n  --exec-path -- path to where your core git programs are ...\n  --git-dir   -- set the path to the repository\n  --help      -- prints the synopsis and a list of the ..\n  --html-path -- print the path where gits HTML ...\n  --info-path -- print the path where the Info files are ...\n  --man-path  -- print the manpath (see `man(1)`) for the ...\n\nAnd:\n\n  % git --git-dir<tab>\n\nAutomatically adds the space, and then lists only directories.\n\nPlus a lot of very specific argument idioms that are only possible in zsh.\n\nIn addition, you can complete commands that are not shown in the list, like\n'git rerere'.\n\nPlus, the user can configure the main output of commands:\n\n  zstyle ':completion:*:*:git:*' tag-order '*'\n\nOr:\n\n  zstyle ':completion:*:*:git:*' tag-order 'alias-commands common-commands'\n\nIn short, pure awesomeness :)\n\nFelipe Contreras (2):\n  complete: zsh: trivial simplification\n  complete: zsh: use zsh completion for the main cmd\n\n contrib/completion/git-completion.zsh | 134 ++++++++++++++++++++++++++++++++--\n 1 file changed, 126 insertions(+), 8 deletions(-)\n\n-- \n1.8.2.1.1031.g2ee5873\n"},{"id":"215753","messageId":"1367094846-9830-2-git-send-email-felipe.contreras@gmail.com","threadId":"33656","inReplyTo":"1367094846-9830-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH 1/2] complete: zsh: trivial simplification","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-27T20:34:05Z","receivedAt":"2013-04-27T20:34:05Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"There should be no functional changes.\n\nThe only reason I wrapped this code around a sub-function is because zsh\ndid the same in it's bashcompinit script in order to declare the special\nvariable 'words' as hidden, but only in this context.\n\nThere's no need for that any more since we access __git_main directly,\nso 'words' is not modified, so there's no need for the sub-function.\n\nIn zsh mode the array indexes are different though.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.zsh | 16 ++++++++--------\n 1 file changed, 8 insertions(+), 8 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh\nindex cf8116d..93d8f42 100644\n--- a/contrib/completion/git-completion.zsh\n+++ b/contrib/completion/git-completion.zsh\n@@ -72,14 +72,14 @@ __gitcomp_file ()\n _git ()\n {\n \tlocal _ret=1\n-\t() {\n-\t\temulate -L ksh\n-\t\tlocal cur cword prev\n-\t\tcur=${words[CURRENT-1]}\n-\t\tprev=${words[CURRENT-2]}\n-\t\tlet cword=CURRENT-1\n-\t\t__${service}_main\n-\t}\n+\tlocal cur cword prev\n+\n+\tcur=${words[CURRENT]}\n+\tprev=${words[CURRENT-1]}\n+\tlet cword=CURRENT-1\n+\n+\temulate ksh -c __${service}_main\n+\n \tlet _ret && _default -S '' && _ret=0\n \treturn _ret\n }\n-- \n1.8.2.1.1031.g2ee5873\n"},{"id":"215754","messageId":"1367094846-9830-3-git-send-email-felipe.contreras@gmail.com","threadId":"33656","inReplyTo":"1367094846-9830-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH 2/2] complete: zsh: use zsh completion for the main cmd","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-27T20:34:06Z","receivedAt":"2013-04-27T20:34:06Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"So that we can have a nice zsh completion output:\n\n% git <tab>\nadd       -- add file contents to the index\nbisect    -- find by binary search the change that introduced a bug\nbranch    -- list, create, or delete branches\ncheckout  -- checkout a branch or paths to the working tree\nclone     -- clone a repository into a new directory\ncommit    -- record changes to the repository\ndiff      -- show changes between commits, commit and working tree, etc\nfetch     -- download objects and refs from another repository\ngrep      -- print lines matching a pattern\ninit      -- create an empty Git repository or reinitialize an existing one\nlog       -- show commit logs\nmerge     -- join two or more development histories together\nmv        -- move or rename a file, a directory, or a symlink\npull      -- fetch from and merge with another repository or a local branch\npush      -- update remote refs along with associated objects\nrebase    -- forward-port local commits to the updated upstream head\nreset     -- reset current HEAD to the specified state\nrm        -- remove files from the working tree and from the index\nshow      -- show various types of objects\nstatus    -- show the working tree status\ntag       -- create, list, delete or verify a tag object signed with GPG\n\nAnd other niceties, like 'git --git-dir=<tab>' showing only directories.\n\nFor the rest, the bash completion stuff is still used.\n\nAlso, add my copyright, since this more than a thin wrapper.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.zsh | 120 +++++++++++++++++++++++++++++++++-\n 1 file changed, 119 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh\nindex 93d8f42..49f0cb8 100644\n--- a/contrib/completion/git-completion.zsh\n+++ b/contrib/completion/git-completion.zsh\n@@ -2,6 +2,8 @@\n \n # zsh completion wrapper for git\n #\n+# Copyright (c) 2012-2013 Felipe Contreras <felipe.contreras@gmail.com>\n+#\n # You need git's bash completion script installed somewhere, by default on the\n # same directory as this script.\n #\n@@ -21,6 +23,9 @@ complete ()\n \treturn 0\n }\n \n+zstyle -T ':completion:*:*:git:*' tag-order && \\\n+\tzstyle ':completion:*:*:git:*' tag-order 'common-commands'\n+\n zstyle -s \":completion:*:*:git:*\" script script\n test -z \"$script\" && script=\"$(dirname ${funcsourcetrace[1]%:*})\"/git-completion.bash\n ZSH_VERSION='' . \"$script\"\n@@ -69,6 +74,115 @@ __gitcomp_file ()\n \tcompadd -Q -p \"${2-}\" -f -- ${=1} && _ret=0\n }\n \n+__git_zsh_bash_func ()\n+{\n+\temulate -L ksh\n+\n+\tlocal command=$1\n+\n+\tlocal completion_func=\"_git_${command//-/_}\"\n+\tdeclare -f $completion_func >/dev/null && $completion_func && return\n+\n+\tlocal expansion=$(__git_aliased_command \"$command\")\n+\tif [ -n \"$expansion\" ]; then\n+\t\tcompletion_func=\"_git_${expansion//-/_}\"\n+\t\tdeclare -f $completion_func >/dev/null && $completion_func\n+\tfi\n+}\n+\n+__git_zsh_cmd_common ()\n+{\n+\tlocal -a list\n+\tlist=(\n+\tadd:'add file contents to the index'\n+\tbisect:'find by binary search the change that introduced a bug'\n+\tbranch:'list, create, or delete branches'\n+\tcheckout:'checkout a branch or paths to the working tree'\n+\tclone:'clone a repository into a new directory'\n+\tcommit:'record changes to the repository'\n+\tdiff:'show changes between commits, commit and working tree, etc'\n+\tfetch:'download objects and refs from another repository'\n+\tgrep:'print lines matching a pattern'\n+\tinit:'create an empty Git repository or reinitialize an existing one'\n+\tlog:'show commit logs'\n+\tmerge:'join two or more development histories together'\n+\tmv:'move or rename a file, a directory, or a symlink'\n+\tpull:'fetch from and merge with another repository or a local branch'\n+\tpush:'update remote refs along with associated objects'\n+\trebase:'forward-port local commits to the updated upstream head'\n+\treset:'reset current HEAD to the specified state'\n+\trm:'remove files from the working tree and from the index'\n+\tshow:'show various types of objects'\n+\tstatus:'show the working tree status'\n+\ttag:'create, list, delete or verify a tag object signed with GPG')\n+\t_describe -t common-commands 'common commands' list && _ret=0\n+}\n+\n+__git_zsh_cmd_alias ()\n+{\n+\tlocal -a list\n+\tlist=(${${${(0)\"$(git config -z --get-regexp '^alias\\.')\"}#alias.}%$'\\n'*})\n+\t_describe -t alias-commands 'aliases' list $* && _ret=0\n+}\n+\n+__git_zsh_cmd_all ()\n+{\n+\tlocal -a list\n+\temulate ksh -c __git_compute_all_commands\n+\tlist=( ${=__git_all_commands} )\n+\t_describe -t all-commands 'all commands' list && _ret=0\n+}\n+\n+__git_zsh_main ()\n+{\n+\tlocal curcontext=\"$curcontext\" state state_descr line\n+\ttypeset -A opt_args\n+\tlocal -a orig_words\n+\n+\torig_words=( ${words[@]} )\n+\n+\t_arguments -C \\\n+\t\t'(-p --paginate --no-pager)'{-p,--paginate}'[pipe all output into ''less'']' \\\n+\t\t'(-p --paginate)--no-pager[do not pipe git output into a pager]' \\\n+\t\t'--git-dir=-[set the path to the repository]: :_directories' \\\n+\t\t'--bare[treat the repository as a bare repository]' \\\n+\t\t'(- :)--version[prints the git suite version]' \\\n+\t\t'--exec-path=-[path to where your core git programs are installed]:: :_directories' \\\n+\t\t'--html-path[print the path where git''s HTML documentation is installed]' \\\n+\t\t'--info-path[print the path where the Info files are installed]' \\\n+\t\t'--man-path[print the manpath (see `man(1)`) for the man pages]' \\\n+\t\t'--work-tree=-[set the path to the working tree]: :_directories' \\\n+\t\t'--namespace=-[set the git namespace]' \\\n+\t\t'--no-replace-objects[do not use replacement refs to replace git objects]' \\\n+\t\t'(- :)--help[prints the synopsis and a list of the most commonly used commands]: :->arg' \\\n+\t\t'(-): :->command' \\\n+\t\t'(-)*:: :->arg' && return\n+\n+\tcase $state in\n+\t(command)\n+\t\t_alternative \\\n+                         'alias-commands:alias:__git_zsh_cmd_alias' \\\n+                         'common-commands:common:__git_zsh_cmd_common' \\\n+                         'all-commands:all:__git_zsh_cmd_all' && _ret=0\n+\t\t;;\n+\t(arg)\n+\t\tlocal command=\"${words[1]}\" __git_dir\n+\n+\t\tif (( $+opt_args[--bare] )); then\n+\t\t\t__git_dir='.'\n+\t\telse\n+\t\t\t__git_dir=${opt_args[--git-dir]}\n+\t\tfi\n+\n+\t\t(( $+opt_args[--help] )) && command='help'\n+\n+\t\twords=( ${orig_words[@]} )\n+\n+\t\t__git_zsh_bash_func $command\n+\t\t;;\n+\tesac\n+}\n+\n _git ()\n {\n \tlocal _ret=1\n@@ -78,7 +192,11 @@ _git ()\n \tprev=${words[CURRENT-1]}\n \tlet cword=CURRENT-1\n \n-\temulate ksh -c __${service}_main\n+\tif (( $+functions[__${service}_zsh_main] )); then\n+\t\t__${service}_zsh_main\n+\telse\n+\t\temulate ksh -c __${service}_main\n+\tfi\n \n \tlet _ret && _default -S '' && _ret=0\n \treturn _ret\n-- \n1.8.2.1.1031.g2ee5873\n"},{"id":"215762","messageId":"7vtxmrsleq.fsf@alter.siamese.dyndns.org","threadId":"33656","inReplyTo":"1367094846-9830-3-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH 2/2] complete: zsh: use zsh completion for the main cmd","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-04-27T21:39:41Z","receivedAt":"2013-04-27T21:39:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> +__git_zsh_cmd_common ()\n> +{\n> +\tlocal -a list\n> +\tlist=(\n> +\tadd:'add file contents to the index'\n> +\tbisect:'find by binary search the change that introduced a bug'\n> +\tbranch:'list, create, or delete branches'\n> +\tcheckout:'checkout a branch or paths to the working tree'\n> +\tclone:'clone a repository into a new directory'\n> +\tcommit:'record changes to the repository'\n> +\tdiff:'show changes between commits, commit and working tree, etc'\n> +\tfetch:'download objects and refs from another repository'\n> +\tgrep:'print lines matching a pattern'\n> +\tinit:'create an empty Git repository or reinitialize an existing one'\n> +\tlog:'show commit logs'\n> +\tmerge:'join two or more development histories together'\n> +\tmv:'move or rename a file, a directory, or a symlink'\n> +\tpull:'fetch from and merge with another repository or a local branch'\n> +\tpush:'update remote refs along with associated objects'\n> +\trebase:'forward-port local commits to the updated upstream head'\n> +\treset:'reset current HEAD to the specified state'\n> +\trm:'remove files from the working tree and from the index'\n> +\tshow:'show various types of objects'\n> +\tstatus:'show the working tree status'\n> +\ttag:'create, list, delete or verify a tag object signed with GPG')\n\nMaintaining this list feels somewhat painful.  Isn't this something\nwe can help by tweaking \"git help\"?\n"},{"id":"215764","messageId":"CAMP44s1dEydqNWH+dFTCj13dfOCVym9XHCYnx12E5hosYNF9Rg@mail.gmail.com","threadId":"33656","inReplyTo":"7vtxmrsleq.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/2] complete: zsh: use zsh completion for the main cmd","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-27T21:53:49Z","receivedAt":"2013-04-27T21:53:49Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Sat, Apr 27, 2013 at 4:39 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n>> +__git_zsh_cmd_common ()\n>> +{\n>> +     local -a list\n>> +     list=(\n>> +     add:'add file contents to the index'\n>> +     bisect:'find by binary search the change that introduced a bug'\n>> +     branch:'list, create, or delete branches'\n>> +     checkout:'checkout a branch or paths to the working tree'\n>> +     clone:'clone a repository into a new directory'\n>> +     commit:'record changes to the repository'\n>> +     diff:'show changes between commits, commit and working tree, etc'\n>> +     fetch:'download objects and refs from another repository'\n>> +     grep:'print lines matching a pattern'\n>> +     init:'create an empty Git repository or reinitialize an existing one'\n>> +     log:'show commit logs'\n>> +     merge:'join two or more development histories together'\n>> +     mv:'move or rename a file, a directory, or a symlink'\n>> +     pull:'fetch from and merge with another repository or a local branch'\n>> +     push:'update remote refs along with associated objects'\n>> +     rebase:'forward-port local commits to the updated upstream head'\n>> +     reset:'reset current HEAD to the specified state'\n>> +     rm:'remove files from the working tree and from the index'\n>> +     show:'show various types of objects'\n>> +     status:'show the working tree status'\n>> +     tag:'create, list, delete or verify a tag object signed with GPG')\n>\n> Maintaining this list feels somewhat painful.  Isn't this something\n> we can help by tweaking \"git help\"?\n\nYes, that's the way Bazaar does it (bzr shell-complete), but for now\nthis does the trick.\n\nAlso, I've been carrying around the patches from Stephen Boyd that add\n--dump-raw-long-options. I think it would be better if somehow 'git\nhelp' learned how to throw this output for both commands and\narguments, and then use the first part for bash, or specify bash\nformat somehow. Of course, we would need to add support for\ndescriptions in the option parser.\n\nIt's the big world-domination plan for completions, but I haven't had\ntime to work on that.\n\nCheers.\n\n-- \nFelipe Contreras\n"}]}