1
0
Fork 0
mirror of https://github.com/zplug/zplug synced 2024-05-21 23:16:14 +02:00
This commit is contained in:
iladin 2017-01-04 19:18:49 -08:00
commit 1a5ea5a523
31 changed files with 219 additions and 196 deletions

2
.gitignore vendored
View File

@ -3,6 +3,8 @@ bin/*
!bin/zplug-env
repos/*
.cache
cache
log
.gitignore.d/*
.error_log

View File

@ -123,12 +123,7 @@ zplug "lib/clipboard", from:oh-my-zsh, if:"[[ $OSTYPE == *darwin* ]]"
zplug "jhawthorn/fzy", \
as:command, \
rename-to:fzy, \
hook-build:"
{
make
sudo make install
} &>/dev/null
"
hook-build:"make && sudo make install"
# Supports checking out a specific branch/tag/commit
zplug "b4b4r07/enhancd", at:v1
@ -144,9 +139,14 @@ zplug "b4b4r07/79ee61f7c140c63d2786", \
zplug "b4b4r07/hello_bitbucket", \
from:bitbucket, \
as:command, \
hook-build:"chmod 755 *.sh", \
use:"*.sh"
# Rename a command with the string captured with `use` tag
zplug "b4b4r07/httpstat", \
as:command, \
use:'(*).sh', \
rename-to:'$1'
# Group dependencies
# Load "emoji-cli" if "jq" is installed in this example
zplug "stedolan/jq", \
@ -198,7 +198,7 @@ Finally, use `zplug install` to install your plugins and reload `.zshrc`.
|-----------|-------------|---------|
| `install` | Install packages in parallel | (None) |
| `load` | Source installed plugins and add installed commands to `$PATH` | `--verbose` |
| `list` | List installed packages (more specifically, view the associative array `$zplugs`) | `--select` |
| `list` | List installed packages (more specifically, view the associative array `$zplugs`) | `--select`,`--installed`,`--loaded` |
| `update` | Update installed packages in parallel | `--select`,`--force` |
| `check` | Return true if all packages are installed, false otherwise | `--verbose` |
| `status` | Check if the remote repositories are up to date | `--select` |

View File

@ -2,11 +2,11 @@
# Description:
# List installed packages (more specifically, view the associative array $zplugs)
local arg filter repo tag
local is_select=false
local -i ret=0
local -a repos similar_repos
local -A copy_zplugs
local arg repo tag filter
local is_loaded=false is_installed=false is_select=false
local -aU repos
tag="${(kj:|:)_zplug_tags[@]}"
while (( $# > 0 ))
do
@ -15,6 +15,12 @@ do
--select)
is_select=true
;;
--loaded)
is_loaded=true
;;
--installed)
is_installed=true
;;
-*|--*)
__zplug::core::options::unknown "$arg"
return $status
@ -24,106 +30,74 @@ do
return 1
;;
*/*)
# Do not remove the end of the at sign
# At the end of the treatment,
# get rid of those at displaying to stdout
repos+=( "$arg" )
# Do nothing
;;
*)
return 1
# Do nothing
;;
esac
shift
done
# Initialize
{
# If assosiate array "zplugs" is empty,
# it means there are no packages that are managed by zplug
if (( $#zplugs == 0 )); then
__zplug::io::print::f \
--die \
--zplug \
--func \
"no package managed by zplug\n"
return 1
fi
if $is_select; then
__zplug::utils::shell::search_commands "$ZPLUG_FILTER" \
| read filter
if [[ -z $filter ]]; then
__zplug::io::print::die \
--die \
--zplug \
--error \
"There is no available filter in ZPLUG_FILTER\n"
return 1
fi
repos=( ${(@f)"$(echo "${(Fk)zplugs[@]}" | eval "$filter")"} )
# There is no package selected by the filter
if (( $#repos == 0 )); then
return 0
fi
fi
}
if (( $#repos > 0 )); then
copy_zplugs=()
for repo in "${repos[@]}"
do
if __zplug::base::base::zpluged "$repo"; then
# TODO:
# @ (at-sign)
# e.g. zplug list b4b4r07/enhancd
# -> b4b4r07/enhancd
# -> b4b4r07/enhancd (b4b4r07/enhancd@)
# It's already managed
copy_zplugs+=(
"$repo"
"${zplugs[$repo]}"
)
else
# It doesn't managed yet
# Try to search the package with fuzzy match
similar_repos=( ${(@f)"$(awk -v repo=$repo '$1 ~ repo' <<<${(Fk)zplugs[@]})"} )
# There is even no similar package
if (( $#similar_repos == 0 )); then
copy_zplugs+=(
"$repo"
"NO SUCH PACKAGE"
)
ret=1
fi
for repo in "${similar_repos[@]}"
do
if __zplug::base::base::zpluged "$repo"; then
copy_zplugs+=(
"$repo"
"${zplugs[$repo]}"
)
fi
done
fi
done
else
copy_zplugs=( "${(@kv)zplugs[@]}" )
# If assosiate array "zplugs" is empty,
# it means there are no packages that are managed by zplug
if (( $#zplugs == 0 )); then
__zplug::io::print::f \
--die --zplug \
"no package managed by zplug\n"
return 1
fi
dq='"'
for copy in "${(k)copy_zplugs[@]}"
do
tag="nil"
if [[ -n $copy_zplugs[$copy] ]]; then
echo "$copy_zplugs[$copy]" \
| sed 's/$/'"$dq"'/g; s/:/:'"$dq"'/g; s/, /'"$dq"', /g;' \
| read tag
if $is_loaded; then
if [[ -s $_zplug_load_log[success] ]]; then
repos=( ${(u@f)"$(<"$_zplug_load_log[success]")":gs:@:} )
else
__zplug::io::print::f \
--die --zplug \
"First, you have to run 'zplug load'\n"
__zplug::log::write::info "$_zplug_load_log[success]: not found or empty\n"
return 1
fi
printf "%s => %s\n" \
"$fg[green]${copy:gs:@::}$reset_color" \
"$tag"
done
elif $is_installed; then
# By using a file glob, it's checked whether it really exists
# A slash is added to the end, but delete it since it's unnecessary
repos=( "$ZPLUG_REPOS"/*/*(/:gs:"$ZPLUG_REPOS"/:) )
repos=( "${repos[@]%/}" )
else
repos=( "${(uk)zplugs[@]:gs:@::}" )
fi
return $ret
if $is_select; then
__zplug::utils::shell::search_commands \
"$ZPLUG_FILTER" \
| read filter
if [[ -z $filter ]]; then
__zplug::io::print::f \
--die --zplug \
"There is no available filter in ZPLUG_FILTER\n"
return 1
fi
repos=( ${(@f)"$(print -l "$repos[@]" | ${=filter})"} )
fi
if __zplug::utils::shell::is_atty; then
# Disply tag information in color
# when connected to the terminal
for repo in "$repos[@]"
do
builtin printf "$fg[green]$repo$reset_color"
builtin printf "$fg[blue] => $reset_color"
builtin printf "${zplugs[$repo]:-"$fg[red]none"}\n"
done \
| perl -pe 's/('"$tag"'):/'$fg[yellow]'$1'$reset_color':/g' \
| sed -E 's/:/:"/g;s/, /", /g;/none$/!s/$/"/g' # quotes tag
printf "$reset_color"
else
# When not connected to the termianl,
# e.g. piped with the grep command (`zplug list | grep zsh`)
# don't display tag information
for repo ("$repos[@]") echo "$repo"
fi
# Returns true if a length of repos is greater than zero
return !$#repos

View File

@ -2,7 +2,7 @@
# Description:
# Check if the remote repositories are up to date
local state arg filter repo
local state arg repo
local -A repo_pids proc_states hook_build hook_finished hook_pids status_codes
local -A tags
local -F SECONDS=0

View File

@ -3,7 +3,7 @@
# Update installed packages in parallel
local is_force=false
local repo arg filter
local repo arg
local -A repo_pids proc_states hook_build hook_finished hook_pids status_codes
local -A tags
local -F SECONDS=0

View File

@ -11,7 +11,6 @@ autoload -Uz regexp-replace
autoload -Uz add-zsh-hook
autoload -Uz colors
autoload -Uz compinit
autoload -Uz zmv
autoload -Uz zplug
colors

View File

@ -74,6 +74,7 @@ fi
printf "\n$obj:\n"
;;
*)
desc="(None)"
[[ -n $opts[$obj] ]] && desc="$opts[$obj]"
[[ -n $cmds[$obj] ]] && desc="$cmds[$obj]"
printf " %-${max}s %s\n" \

View File

@ -1,4 +1,6 @@
#!/usr/bin/env zsh
# Description:
# Self management of zplug
if ! __zplug::base::base::zpluged "zplug/zplug"; then
__zplug::io::print::f \

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# as tag
# Specify whether to register the package as plugins or commands
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# at tag
# Branch, tag, or commit to use
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# defer tag
# Defers the loading of a package
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# depth tag
# The number of commits to include in the cloned repository
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# dir tag
# Installation directory which is managed by zplug
local arg="${1:gs:@::}" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# from tag
# Specify the service from which you install
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# frozen tag
# Do not update unless explicitly specified
local arg package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# hook-build tag
# Commands to run after installation/update
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# hook-load tag
# Commands to run after loading
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# if tag
# The conditions under which to install and/or use the package
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# ignore tag
# Specify exception pattern of files that you don't want to load
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# lazy tag
# Lazy-load
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# on tag
# Dependencies
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# rename-to tag
# Specify the filename you want to rename to
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
#!/usr/bin/env zsh
# Description:
# use tag
# Specify the pattern of the files to source or add to `$PATH`
local arg="$1" package
local -a parsed_zplugs

View File

@ -1,6 +1,6 @@
__zplug::core::load::prepare()
{
unsetopt monitor
setopt nomonitor
zstyle ':zplug:core:load' 'verbose' no
__zplug::io::file::rm_touch "$_zplug_load_log[success]"
@ -13,7 +13,7 @@ __zplug::core::load::from_cache()
zstyle -s ':zplug:core:load' 'verbose' is_verbose
# Default
#setopt monitor # TODO
setopt monitor
__zplug::core::cache::update
@ -46,7 +46,7 @@ __zplug::core::load::from_cache()
__zplug::io::print::f \
--zplug \
"These repos have failed to load:\n$fg_bold[red]"
sed -e 's/^/- /g' "$_zplug_load_log[failure]"
print -l -- "- $fg[red]"${^${(u@f)"$(<"$_zplug_load_log[failure]")":gs:@:}}"$reset_color"
__zplug::io::print::f "$reset_color"
return 1
fi

View File

@ -25,6 +25,13 @@ __zplug::job::handle::flock()
local file="$args[1]" contents="$args[2]"
# TODO: Temporary fix to solve #334
if [[ ! -f $file ]]; then
__zplug::log::write::info \
"create $file because it does not exist"
touch "$file"
fi
(
until zsystem flock -t 3 "$file"
do

View File

@ -219,7 +219,9 @@ __zplug::sources::github::load_command()
#
# becomes an element where the key is "path/to/cmd" and the value is
# "dst".
if [[ $tags[use] == *\** && $tags[rename-to] == *\$* ]]; then
if [[ $tags[use] == *(*)* && $tags[rename-to] == *\$* ]]; then
# If it's captured by `use` tag and referenced by `rename-to` tag,
# it's expanded with `__zplug::utils::shell::zglob`
if (( $#rename_hash == 0 )) && [[ -n $tags[rename-to] ]]; then
rename_hash=( $(__zplug::utils::shell::zglob \
"$tags[dir]/$tags[use]" \
@ -246,7 +248,7 @@ __zplug::sources::github::load_command()
done
if (( $#rename_hash == 0 )); then
__zplug::log::write::info \
'no matches found; $rename_hash is empty'
"$repo: no matches found, rename_hash is empty"
fi
# Add parent directories to fpath if any files starting in _* exist

View File

@ -171,7 +171,7 @@ __zplug::utils::shell::pipestatus()
__zplug::utils::shell::expand_glob()
{
local pattern="$1"
local pattern="$1" file
# Modifiers to use if $pattern does not include modifiers
local default_modifiers="${2:-(N)}"
local -a matches
@ -192,17 +192,10 @@ __zplug::utils::shell::expand_glob()
) )
fi
print -l "${matches[@]}"
}
__zplug::utils::shell::zmv()
{
local from="$1" to="$2"
if (( $# != 2 )); then
return 1
fi
zmv -P echo -W "$from" "$to" 2>/dev/null
for file in "${matches[@]}"
do
[[ -e ${~file} ]] && echo ${~file}
done
}
__zplug::utils::shell::zglob()
@ -274,3 +267,14 @@ print(json.dumps(sys.stdin.read()))' \
echo "(Not available: python requires)"
fi
}
__zplug::utils::shell::is_atty()
{
if [[ -t 0 && -t 1 ]]; then
# terminal
return 0
else
# pipeline
return 1
fi
}

View File

@ -126,12 +126,7 @@ zstyle ':prezto:module:prompt' theme 'sorin'
zplug "jhawthorn/fzy", \
as:command, \
rename-to:fzy, \
hook-build:"
{
make
sudo make install
} &>/dev/null
"
hook-build:"make && sudo make install"
# リビジョンロック機能を持つ
zplug "b4b4r07/enhancd", at:v1
@ -147,9 +142,14 @@ zplug "b4b4r07/79ee61f7c140c63d2786", \
zplug "b4b4r07/hello_bitbucket", \
from:bitbucket, \
as:command, \
hook-build:"chmod 755 *.sh", \
use:"*.sh"
# `use` タグでキャプチャした文字列でリネームする
zplug "b4b4r07/httpstat", \
as:command, \
use:'(*).sh', \
rename-to:'$1'
# 依存管理
# "emoji-cli" は "jq" があるときにのみ読み込まれる
zplug "stedolan/jq", \
@ -199,7 +199,7 @@ Finally, use `zplug install` to install your plugins and reload `.zshrc`.
|-----------|-------------|---------|
| `install` | 並列インストール | (なし) |
| `load` | インストール済みプラグインを読み込み、インストール済みコマンドを `$PATH` に追加する | `--verbose` |
| `list` | インストール済みパッケージを表示する (端的に連想配列 `$zplugs` を表示する) | `--select` |
| `list` | インストール済みパッケージを表示する (端的に連想配列 `$zplugs` を表示する) | `--select`,`--installed`,`--loaded` |
| `update` | インストール済みパッケージを並列でアップデートする | `--select`,`--force` |
| `check` | 未インストールなパッケージがないなら真を返し、そうでなければ偽を返す | `--verbose` |
| `status` | パッケージが最新かどうか確認する| `--select` |

View File

@ -2,12 +2,12 @@
.\" Title: zplug-rename-to
.\" Author: [see the "Authors" section]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
.\" Date: 11/21/2016
.\" Date: 12/28/2016
.\" Manual: ZPLUG Manual
.\" Source: ZPLUG Manual
.\" Language: English
.\"
.TH "ZPLUG\-RENAME\-TO" "5" "11/21/2016" "ZPLUG Manual" "ZPLUG Manual"
.TH "ZPLUG\-RENAME\-TO" "5" "12/28/2016" "ZPLUG Manual" "ZPLUG Manual"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@ -67,11 +67,26 @@ Rename fzf\-bin to fzf:
.RS 4
.\}
.nf
$ zplug "junegunn/fzf\-bin", \e
$ zplug \'junegunn/fzf\-bin\', \e
from:gh\-r, \e
as:command, \e
rename\-to:fzf, \e
use:"*darwin*amd64*"
use:\'*darwin*amd64*\'
.fi
.if n \{\
.RE
.\}
.sp
Rename a command with the string captured with use tag
.sp
.if n \{\
.RS 4
.\}
.nf
zplug \'b4b4r07/httpstat\', \e
as:command, \e
use:\'(*)\&.sh\', \e
rename\-to:\'$1\'
.fi
.if n \{\
.RE

View File

@ -36,11 +36,20 @@ EXAMPLES
Rename fzf-bin to fzf:
------------
$ zplug "junegunn/fzf-bin", \
$ zplug 'junegunn/fzf-bin', \
from:gh-r, \
as:command, \
rename-to:fzf, \
use:"*darwin*amd64*"
use:'*darwin*amd64*'
------------
Rename a command with the string captured with `use` tag
------------
zplug 'b4b4r07/httpstat', \
as:command, \
use:'(*).sh', \
rename-to:'$1'
------------

View File

@ -7,49 +7,47 @@ local -a -U zplug_cmds
local -a _zplug_boolean_true _zplug_boolean_false
local -a cmds tags
cmds=( "$ZPLUG_ROOT"/autoload/commands/__*__(:t:gs:_:) )
tags=( "$ZPLUG_ROOT"/autoload/tags/__*__(:t:gs:_:) )
cmds=( "${(k)_zplug_commands[@]}" )
tags=( "${(k)_zplug_tags[@]}" )
_zplug_boolean_true=("true" "yes" "on" 1)
_zplug_boolean_false=("false" "no" "off" 0)
zplug_cmds=(
'check:check whether an update or install is available'
'clean:remove a package'
'clear:remove cache file'
'install:install a package in parallel'
'list:list installed packages with its tags information'
'load:load an installed package'
'status:check if remote branch is up-to-date'
'update:freshen up a installed package in parallel'
'info:information about a package'
)
# Completions of zplug commands
for p in "${(k)_zplug_commands[@]}"
do
zplug_cmds+=("$p:$_zplug_commands[$p]")
done
# Completions for user-defined commands
for p in ${^path}/zplug-*(N-.)
do
desc="$(sed -n '2p' "$p" | sed -E 's/^.*[Dd]esc(ription)?: ?//')"
desc="${desc:+"\[User-defined\] $desc"}"
zplug_cmds+=("${p:t:gs:zplug-:}:${desc:-"User-defined command"}")
desc=
desc="$(grep -E "^# Desc(ription)?: ?" "$p")"
regexp-replace desc "^.*[Dd]esc(ription)?: ?" ""
desc="[User-defined] ${desc:-"No description."}"
zplug_cmds+=("${p:t:gs:zplug-:}:$desc")
done
# Completions for user-defined functions
for p in ${(M)${(k)functions[@]}:#zplug-*}
do
f=( ${^fpath[@]}/$p(N) )
desc=
if [[ -f $f[1] ]]; then
desc="$(sed -n '2p' "$f[1]" | sed -E 's/^.*[Dd]esc(ription)?: ?//')"
desc="$(grep -E "^# Desc(ription)?: ?" "$f[1]")"
regexp-replace desc "^.*[Dd]esc(ription)?: ?" ""
fi
desc="${desc:+"\[User-defined\] $desc"}"
zplug_cmds+=("${p:gs:zplug-:}:${desc:-"User-defined command"}")
desc="[User-defined] ${desc:-"No description."}"
zplug_cmds+=("${p:gs:zplug-:}:$desc")
done
_arguments \
'(-)--help[show help message]: :->comp' \
'(-)--version[version information]: :' \
'(-)--log=[view zplug error log]: :->log' \
'(-)--rollback=[rollback particular processings]: :->rollback' \
'(-)--self-manage[self management of zplug]: :' \
'*:: :->comp' && return 0
"(-)--help[$_zplug_options[help]]: :->comp" \
"(-)--version[$_zplug_options[version]]: :" \
"(-)--log=[$_zplug_options[log]]: :->log" \
"(-)--rollback=[$_zplug_options[rollback]]: :->rollback" \
"(-)--self-manage[$_zplug_options[self-manage]]: :" \
"*:: :->comp" && return 0
if (( CURRENT == 1 )); then
_describe -t commands "zplug subcommand" zplug_cmds
@ -75,12 +73,19 @@ case "$words[1]" in
'(--verbose)--verbose[display loading files]'
ret=0
;;
status|list|update)
status|update)
_arguments \
'(--select)--select[select items with interactive filters]' \
'*:: :( "${(k)zplugs[@]}" )'
ret=0
;;
list)
_arguments \
'(--loaded --installed)--loaded[list loaded packages]' \
'(--loaded --installed)--installed[list installed packages]' \
'(--select)--select[list packages and select them]'
ret=0
;;
clean)
_arguments \
'(--force --select)--force[force the removing activity]' \
@ -99,22 +104,25 @@ case "$words[1]" in
ret=0
;;
*/*)
if ! [[ $BUFFER =~ ", $" || $BUFFER =~ ":$" ]]; then
return 0
fi
_values -S : -s , "zplug tags" \
"as[Specify whether to register as commands or to register as plugins]:as:(plugin command)" \
"use[Specify the pattern to source (for plugin) or relative path to export (for command)]:use:->use" \
"from[Specify the services you use to install]:from:(gh-r gist oh-my-zsh github bitbucket gitlab local)" \
"at[Support branch/tag installation]:at:" \
"rename-to[Specify filename you want to rename]:rename-to:" \
"dir[Installation directory (RO)]:dir:->dir" \
"if[Specify the conditions under which to source or add to \$PATH]:if:" \
"hook-build[Commands to run after installation/update]:hook-build:" \
"hook-load[Commands to run after loading]:hook-load:" \
"frozen[Do not update unless explicitly specified]:frozen:->boolean" \
"on[Dependencies (RO)]:on:->on" \
"defer[Priority of loading the plugins]:defer:->defer" \
"ignore[Specify exception pattern so as not to load the files]:ignore:" \
"lazy[Lazy loading]:lazy:->boolean" \
"depth[Clone depth]:depth:({0..10})" && ret=0
"as[$_zplug_tags[as]]:as:(plugin command theme)" \
"use[$_zplug_tags[use]]:use:->use" \
"from[$_zplug_tags[from]]:from:(gh-r gist oh-my-zsh github gitlab bitbucket local)" \
"at[$_zplug_tags[at]]:at:" \
"rename-to[$_zplug_tags[rename-to]]:rename-to:" \
"dir[$_zplug_tags[dir]]:dir:->dir" \
"if[$_zplug_tags[if]]:if:" \
"hook-build[$_zplug_tags[hook-build]]:hook-build:" \
"hook-load[$_zplug_tags[hook-load]]:hook-load:" \
"frozen[$_zplug_tags[frozen]]:frozen:->boolean" \
"on[$_zplug_tags[on]]:on:->on" \
"defer[$_zplug_tags[defer]]:defer:->defer" \
"ignore[$_zplug_tags[ignore]]:ignore:" \
"lazy[$_zplug_tags[lazy]]:lazy:->boolean" \
"depth[$_zplug_tags[depth]]:depth:({0..10})" && ret=0
case $state in
on|dir)
compadd -X "%F{green}READ ONLY%f %Bno arguments%b"
@ -146,12 +154,12 @@ case "$words[1]" in
compadd -J 'boolean/false' -X "%F{yellow}Completing%f %Bfalse word%b" $_zplug_boolean_false
;;
esac
return ret
;;
esac
case $state in
"comp")
is_help="yes"
_describe -t help_cmds "commands" cmds
_describe -t help_tags "tags" tags
;;