1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-07 11:41:16 +02:00

* 29582, 29589: Update handling of third-party Git commands

This commit is contained in:
Nikolai Weibull 2011-07-22 13:08:25 +00:00
parent 53998c2cf5
commit 6b42b83f41
3 changed files with 92 additions and 67 deletions

View file

@ -2,6 +2,14 @@
* unposted: Completion/Unix/Command/_git: Use _files, not _path_files. * unposted: Completion/Unix/Command/_git: Use _files, not _path_files.
* 29582: Completion/Unix/Command/_git: Alter the way that commands and
aliases are listed when both are requested.
* 29589: Completion/Unix/Command/_git,
Completion/Debian/Command/_git-buildpackage: Use #description instead
of #desc: for description of third-party commands. Also, refactor the
code to match the rest of the file.
2011-07-21 Nikolai Weibull <now@bitwi.se> 2011-07-21 Nikolai Weibull <now@bitwi.se>
* 29272: Completion/Unix/Command/_git: Use return values correctly * 29272: Completion/Unix/Command/_git: Use return values correctly
@ -15141,5 +15149,5 @@
***************************************************** *****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL * This is used by the shell to define $ZSH_PATCHLEVEL
* $Revision: 1.5404 $ * $Revision: 1.5405 $
***************************************************** *****************************************************

View file

@ -1,5 +1,5 @@
#compdef git-buildpackage #compdef git-buildpackage
#desc:build Debian packages from a git repository #description build Debian packages from a git repository
_arguments \ _arguments \
'--version[show program version number and exit]' \ '--version[show program version number and exit]' \

View file

@ -2,7 +2,7 @@
# Some parts of this completion's behaviour are configurable: # Some parts of this completion's behaviour are configurable:
# #
# Say, you got your own git sub-commands (git will run a program `git-foo' # Say you got your own git sub-commands (git will run a program `git-foo'
# when you run "git foo") and you want "git f<tab>" to complete that sub # when you run "git foo") and you want "git f<tab>" to complete that sub
# commands name for you. You can make that sub-command know to the completion # commands name for you. You can make that sub-command know to the completion
# via the user-command style: # via the user-command style:
@ -15,8 +15,21 @@
# #
# % zstyle ':completion:*:*:git:*' user-commands ${${(M)${(k)commands}:#git-*}/git-/} # % zstyle ':completion:*:*:git:*' user-commands ${${(M)${(k)commands}:#git-*}/git-/}
# #
# You could even create a function _git-foo() to handle specific completion # A better solution is to create a function _git-foo() to handle specific
# for that command. # completion for that command. This also allows you to add command-specific
# completion as well. Place such a function inside an autoloaded #compdef file
# and you should be all set. You can add a description to such a function by
# adding a line matching
#
# #description DESCRIPTION
#
# as the second line in the file. See
# Completion/Debian/Command/_git-buildpackage in the Zsh sources for an
# example.
#
# As this solution is so much better than the user-commands zstyle method, the
# zstyle method is now DEPRECATED. It will most likely be removed in the next
# major release of Zsh (5.0).
# #
# When _git does not know a given sub-command (say `bar'), it falls back to # When _git does not know a given sub-command (say `bar'), it falls back to
# completing file names for all arguments to that sub command. I.e.: # completing file names for all arguments to that sub command. I.e.:
@ -2114,7 +2127,7 @@ _git-config () {
__git_mergetools -S . && ret=0 __git_mergetools -S . && ret=0
;; ;;
(pager.) (pager.)
__git_aliases_and_commands && ret=0 _git_commands && ret=0
;; ;;
(pretty.) (pretty.)
__git_config_sections -a '(|)' '^pretty\..+\.[^.]+$' prettys 'pretty format string' && ret=0 __git_config_sections -a '(|)' '^pretty\..+\.[^.]+$' prettys 'pretty format string' && ret=0
@ -2930,7 +2943,7 @@ _git-help () {
'(-a --all -m --man -w --web)'{-i,--info}'[show all available commands]' \ '(-a --all -m --man -w --web)'{-i,--info}'[show all available commands]' \
'(-a --all -i --info -w --web)'{-m,--man}'[show all available commands]' \ '(-a --all -i --info -w --web)'{-m,--man}'[show all available commands]' \
'(-a --all -i --info -m --man )'{-w,--web}'[show all available commands]' \ '(-a --all -i --info -m --man )'{-w,--web}'[show all available commands]' \
': :__git_aliases_and_commands' ': :_git_commands'
} }
(( $+functions[_git-instaweb] )) || (( $+functions[_git-instaweb] )) ||
@ -4685,11 +4698,41 @@ _git_commands () {
patch-id:'compute unique ID for a patch' patch-id:'compute unique ID for a patch'
stripspace:'filter out empty lines') stripspace:'filter out empty lines')
local -a user_commands
zstyle -a :completion:$curcontext: user-commands user_commands
local -a third_party_commands
local command
for command in $_git_third_party_commands; do
(( $+commands[git-${command%%:*}] )) && third_party_commands+=$command
done
local -a aliases unique_aliases
__git_extract_aliases
local alias
for alias in $aliases; do
local name=${alias%%:*}
(( main_porcelain_commands[(I)$name:*] ||
user_commands[(I)$name:*] ||
third_party_commands[(I)$name:*] ||
ancillary_manipulator_commands[(I)$name:*] ||
ancillary_interrogator_commands[(I)$name:*] ||
interaction_commands[(I)$name:*] ||
plumbing_manipulator_commands[(I)$name:*] ||
plumbing_interrogator_commands[(I)$name:*] ||
plumbing_sync_commands[(I)$name:*] ||
plumbing_sync_helper_commands[(I)$name:*] ||
plumbing_internal_helper_commands[(I)$name:*] )) || unique_aliases+=$alias
done
integer ret=1 integer ret=1
# TODO: Is this the correct way of doing it? # TODO: Is this the correct way of doing it? Should we be using _alternative
# TODO: Should we be chaining them together with || instead? # and separate functions for each set of commands instead?
_describe -t aliases alias unique_aliases && ret=0
_describe -t main-porcelain-commands 'main porcelain command' main_porcelain_commands && ret=0 _describe -t main-porcelain-commands 'main porcelain command' main_porcelain_commands && ret=0
_describe -t user-commands 'user command' user_commands && ret=0
_describe -t third-party-commands 'third-party command' third_party_commands && ret=0
_describe -t ancillary-manipulator-commands 'ancillary manipulator command' ancillary_manipulator_commands && ret=0 _describe -t ancillary-manipulator-commands 'ancillary manipulator command' ancillary_manipulator_commands && ret=0
_describe -t ancillary-interrogator-commands 'ancillary interrogator command' ancillary_interrogator_commands && ret=0 _describe -t ancillary-interrogator-commands 'ancillary interrogator command' ancillary_interrogator_commands && ret=0
_describe -t interaction-commands 'interaction command' interaction_commands && ret=0 _describe -t interaction-commands 'interaction command' interaction_commands && ret=0
@ -4699,34 +4742,20 @@ _git_commands () {
_describe -t plumbing-sync-helper-commands 'plumbing sync helper command' plumbing_sync_helper_commands && ret=0 _describe -t plumbing-sync-helper-commands 'plumbing sync helper command' plumbing_sync_helper_commands && ret=0
_describe -t plumbing-internal-helper-commands 'plumbing internal helper command' plumbing_internal_helper_commands && ret=0 _describe -t plumbing-internal-helper-commands 'plumbing internal helper command' plumbing_internal_helper_commands && ret=0
local -a addons
local a
for a in $_git_third_party; do
(( ${+commands[git-${a%%:*}]} )) && addons+=( $a )
done
_describe -t third-party-addons 'third party addon' addons && ret=0
local -a user_commands
zstyle -a ":completion:${curcontext}:" user-commands user_commands || user_commands=()
_describe -t user-specific-commands 'user specific command' user_commands && ret=0
return ret return ret
} }
(( $+functions[__git_aliases] )) || (( $+functions[__git_aliases] )) ||
__git_aliases () { __git_aliases () {
declare -a aliases local -a aliases
__git_extract_aliases
aliases=(${^${${(0)"$(_call_program aliases "git config -z --get-regexp '^alias.'")"}#alias.}/$'\n'/:alias for \'}\')
_describe -t aliases alias aliases $* _describe -t aliases alias aliases $*
} }
(( $+functions[__git_aliases_and_commands] )) || (( $+functions[__git_extract_aliases] )) ||
__git_aliases_and_commands () { __git_extract_aliases () {
_alternative \ aliases=(${^${${(0)"$(_call_program aliases "git config -z --get-regexp '^alias.'")"}#alias.}/$'\n'/:alias for \'}\')
'aliases::__git_aliases' \
'commands::_git_commands'
} }
(( $+functions[__git_date_formats] )) || (( $+functions[__git_date_formats] )) ||
@ -6073,7 +6102,7 @@ _git() {
aliases=(${(f)${${${(f)"$(_call_program aliases git config --get-regexp '\^alias\.')"}#alias.}/ /$'\n'}/(#e)/$'\n'}) aliases=(${(f)${${${(f)"$(_call_program aliases git config --get-regexp '\^alias\.')"}#alias.}/ /$'\n'}/(#e)/$'\n'})
(( $#aliases % 2 == 0 )) && git_aliases=($aliases) (( $#aliases % 2 == 0 )) && git_aliases=($aliases)
if [[ -n ${git_aliases[$words[2]]} ]] ; then if (( $+git_aliases[$words[2]] && !$+commands[git-$words[2]] )); then
local -a tmpwords expalias local -a tmpwords expalias
expalias=(${(z)git_aliases[$words[2]]}) expalias=(${(z)git_aliases[$words[2]]})
tmpwords=(${words[1]} ${expalias}) tmpwords=(${words[1]} ${expalias})
@ -6114,14 +6143,14 @@ _git() {
case $state in case $state in
(command) (command)
__git_aliases_and_commands && ret=0 _git_commands && ret=0
;; ;;
(option-or-argument) (option-or-argument)
curcontext=${curcontext%:*:*}:git-$words[1]: curcontext=${curcontext%:*:*}:git-$words[1]:
if (( ${+functions[_git-$words[1]]} )); then if (( $+functions[_git-$words[1]] )); then
_call_function ret _git-$words[1] _call_function ret _git-$words[1]
elif zstyle -T ":completion:${curcontext}:" use-fallback; then elif zstyle -T :completion:$curcontext: use-fallback; then
_files && ret=0 _files && ret=0
else else
_message 'unknown sub-command' _message 'unknown sub-command'
@ -6135,42 +6164,30 @@ _git() {
return ret return ret
} }
# Handle add-on completions. Say you got a third party add-on `foo'. What you # Load any _git-* definitions so that they may be completed as commands.
# want to do is write your completion as `_git-foo' and this code will pick it declare -gUa _git_third_party_commands
# up. That should be a regular compsys function, which starts like this: _git_third_party_commands=()
#
# #compdef git-foo local file
# for file in ${^fpath}/_git-*~(*~|*.zwc)(.N); do
# In addition to what compinit does, this also reads the second line of the local name=${${file:t}#_git-}
# completion. If that matches "#desc:*" the part behind "#desc:" will be used if (( $+_git_third_party_commands[$name] )); then
# as the addon's description. Like this: continue
# fi
# #desc:checks git's foobar value
local addon input i desc local desc=
typeset -gUa _git_third_party integer i=1
for addon in ${^fpath}/_git-*~*~(.N); do while read input; do
if [[ -n ${(M)_git_third_party:#${${addon:t}#_git-}*} ]]; then if (( i == 2 )); then
# This makes sure only the first _git-foo in $fpath gets read. if [[ $input == '#description '* ]]; then
continue desc=:${input#\#description }
fi
break
fi fi
# Read the second line of the file. (( i++ ))
i=1 done < $file
desc=
while read input; do _git_third_party_commands+=$name$desc
if (( i == 2 )); then
desc=$input
break
fi
(( i++ ))
done < $addon
# Setup `$desc' appropriately.
if [[ $desc != '#desc:'* ]]; then
desc=
else
desc=${desc#\#desc}
fi
# Add the addon's completion.
_git_third_party+=( ${${addon:t}#_git-}$desc )
done done
_git _git