All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] completion: zsh: nice stuff
@ 2013-04-27 20:34 Felipe Contreras
  2013-04-27 20:34 ` [PATCH 1/2] complete: zsh: trivial simplification Felipe Contreras
  2013-04-27 20:34 ` [PATCH 2/2] complete: zsh: use zsh completion for the main cmd Felipe Contreras
  0 siblings, 2 replies; 5+ messages in thread
From: Felipe Contreras @ 2013-04-27 20:34 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Matthieu Moy, Ramkumar Ramachandra, Felipe Contreras

Hi,

Our thin wrapper seems to be doing a good job of providing all the bash
functionality, to zsh, however, we can do more.

This patch enables zsh-specific functionality to list the main commands, and
general options. So we get:

  % git <tab>
  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
  ...

And:

  % git --
  --bare      -- treat the repository as a bare repository
  --exec-path -- path to where your core git programs are ...
  --git-dir   -- set the path to the repository
  --help      -- prints the synopsis and a list of the ..
  --html-path -- print the path where gits HTML ...
  --info-path -- print the path where the Info files are ...
  --man-path  -- print the manpath (see `man(1)`) for the ...

And:

  % git --git-dir<tab>

Automatically adds the space, and then lists only directories.

Plus a lot of very specific argument idioms that are only possible in zsh.

In addition, you can complete commands that are not shown in the list, like
'git rerere'.

Plus, the user can configure the main output of commands:

  zstyle ':completion:*:*:git:*' tag-order '*'

Or:

  zstyle ':completion:*:*:git:*' tag-order 'alias-commands common-commands'

In short, pure awesomeness :)

Felipe Contreras (2):
  complete: zsh: trivial simplification
  complete: zsh: use zsh completion for the main cmd

 contrib/completion/git-completion.zsh | 134 ++++++++++++++++++++++++++++++++--
 1 file changed, 126 insertions(+), 8 deletions(-)

-- 
1.8.2.1.1031.g2ee5873

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] complete: zsh: trivial simplification
  2013-04-27 20:34 [PATCH 0/2] completion: zsh: nice stuff Felipe Contreras
@ 2013-04-27 20:34 ` Felipe Contreras
  2013-04-27 20:34 ` [PATCH 2/2] complete: zsh: use zsh completion for the main cmd Felipe Contreras
  1 sibling, 0 replies; 5+ messages in thread
From: Felipe Contreras @ 2013-04-27 20:34 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Matthieu Moy, Ramkumar Ramachandra, Felipe Contreras

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 <felipe.contreras@gmail.com>
---
 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 cf8116d..93d8f42 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
 }
-- 
1.8.2.1.1031.g2ee5873

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] complete: zsh: use zsh completion for the main cmd
  2013-04-27 20:34 [PATCH 0/2] completion: zsh: nice stuff Felipe Contreras
  2013-04-27 20:34 ` [PATCH 1/2] complete: zsh: trivial simplification Felipe Contreras
@ 2013-04-27 20:34 ` Felipe Contreras
  2013-04-27 21:39   ` Junio C Hamano
  1 sibling, 1 reply; 5+ messages in thread
From: Felipe Contreras @ 2013-04-27 20:34 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Matthieu Moy, Ramkumar Ramachandra, Felipe Contreras

So that we can have a nice zsh completion output:

% git <tab>
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=<tab>' 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 <felipe.contreras@gmail.com>
---
 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 93d8f42..49f0cb8 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 <felipe.contreras@gmail.com>
+#
 # 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
-- 
1.8.2.1.1031.g2ee5873

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] complete: zsh: use zsh completion for the main cmd
  2013-04-27 20:34 ` [PATCH 2/2] complete: zsh: use zsh completion for the main cmd Felipe Contreras
@ 2013-04-27 21:39   ` Junio C Hamano
  2013-04-27 21:53     ` Felipe Contreras
  0 siblings, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2013-04-27 21:39 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git, Matthieu Moy, Ramkumar Ramachandra

Felipe Contreras <felipe.contreras@gmail.com> writes:

> +__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')

Maintaining this list feels somewhat painful.  Isn't this something
we can help by tweaking "git help"?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] complete: zsh: use zsh completion for the main cmd
  2013-04-27 21:39   ` Junio C Hamano
@ 2013-04-27 21:53     ` Felipe Contreras
  0 siblings, 0 replies; 5+ messages in thread
From: Felipe Contreras @ 2013-04-27 21:53 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Matthieu Moy, Ramkumar Ramachandra

On Sat, Apr 27, 2013 at 4:39 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Felipe Contreras <felipe.contreras@gmail.com> writes:
>
>> +__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')
>
> Maintaining this list feels somewhat painful.  Isn't this something
> we can help by tweaking "git help"?

Yes, that's the way Bazaar does it (bzr shell-complete), but for now
this does the trick.

Also, I've been carrying around the patches from Stephen Boyd that add
--dump-raw-long-options. I think it would be better if somehow 'git
help' learned how to throw this output for both commands and
arguments, and then use the first part for bash, or specify bash
format somehow. Of course, we would need to add support for
descriptions in the option parser.

It's the big world-domination plan for completions, but I haven't had
time to work on that.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-04-27 21:53 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-27 20:34 [PATCH 0/2] completion: zsh: nice stuff Felipe Contreras
2013-04-27 20:34 ` [PATCH 1/2] complete: zsh: trivial simplification Felipe Contreras
2013-04-27 20:34 ` [PATCH 2/2] complete: zsh: use zsh completion for the main cmd Felipe Contreras
2013-04-27 21:39   ` Junio C Hamano
2013-04-27 21:53     ` Felipe Contreras

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.