-
-
Notifications
You must be signed in to change notification settings - Fork 670
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lib/cli: Re-implement "omb" and its completion for Bash
- Loading branch information
1 parent
1f84fe8
commit c346e11
Showing
2 changed files
with
244 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,108 +1,207 @@ | ||
#!/usr/bin/env bash | ||
|
||
function omb { | ||
[[ $# -gt 0 ]] || { | ||
_omb::help | ||
return 1 | ||
} | ||
_omb_module_require lib:utils | ||
|
||
local command="$1" | ||
shift | ||
function _omb_cmd_help { | ||
echo 'Not yet implemented' | ||
} | ||
function _omb_cmd_changelog { | ||
echo 'Not yet implemented' | ||
} | ||
function _omb_cmd_plugin { | ||
echo 'Not yet implemented' | ||
} | ||
function _omb_cmd_pull { | ||
echo 'Not yet implemented' | ||
} | ||
function _omb_cmd_reload { | ||
echo 'Not yet implemented' | ||
} | ||
function _omb_cmd_theme { | ||
echo 'Not yet implemented' | ||
} | ||
function _omb_cmd_update { | ||
echo 'Not yet implemented' | ||
} | ||
function _omb_cmd_version { | ||
echo 'Not yet implemented' | ||
} | ||
|
||
function omb { | ||
if (($# == 0)); then | ||
_omb_cmd_help | ||
return 2 | ||
fi | ||
|
||
# Subcommand functions start with _ so that they don't | ||
# appear as completion entries when looking for `omb` | ||
(( $+functions[_omb::$command] )) || { | ||
_omb::help | ||
return 1 | ||
} | ||
if ! _omb_util_function_exists "_omb_cmd_$1"; then | ||
_omb_cmd_help | ||
return 2 | ||
fi | ||
|
||
_omb_cmd_"$@" | ||
} | ||
|
||
|
||
_omb::$command "$@" | ||
_omb_module_require lib:utils | ||
|
||
_omb_lib_cli__init_shopt= | ||
_omb_util_get_shopt -v _omb_lib_cli__init_shopt extglob | ||
shopt -s extglob | ||
|
||
function _comp_cmd_omb__describe { | ||
eval "set -- $1 \"\${$2[@]}\"" | ||
local type=$1; shift | ||
local word desc words iword=0 | ||
for word; do | ||
desc="($type) ${word#*:}" # unused | ||
word=${word%%:*} | ||
words[iword++]=$word | ||
done | ||
|
||
local -a filtered | ||
_omb_util_split_lines filtered "$(compgen -W '"${words[@]}"' -- "${COMP_WORDS[COMP_CWORD]}")" | ||
COMPREPLY+=("${filtered[@]}") | ||
} | ||
|
||
function _omb { | ||
local -a cmds subcmds | ||
cmds=( | ||
'changelog:Print the changelog' | ||
'help:Usage information' | ||
'plugin:Manage plugins' | ||
'pr:Manage Oh My Bash Pull Requests' | ||
'reload:Reload the current bash session' | ||
'theme:Manage themes' | ||
'update:Update Oh My Bash' | ||
'version:Show the version' | ||
) | ||
|
||
if (( CURRENT == 2 )); then | ||
_describe 'command' cmds | ||
elif (( CURRENT == 3 )); then | ||
case "$words[2]" in | ||
changelog) local -a refs | ||
refs=("${(@f)$(cd "$OSH"; command git for-each-ref --format="%(refname:short):%(subject)" refs/heads refs/tags)}") | ||
_describe 'command' refs ;; | ||
plugin) subcmds=( | ||
function _comp_cmd_omb__get_available_plugins { | ||
available_plugins=() | ||
|
||
local -a plugin_files | ||
_omb_util_glob_expand plugin_files '{"$OSH","$OSH_CUSTOM"}/plugins/*/{_*,*.plugin.{bash,sh}}' | ||
|
||
local plugin | ||
for plugin in "${plugin_files[@]##*/}"; do | ||
case $plugin in | ||
*.plugin.bash) plugin=${plugin%.plugin.bash} ;; | ||
*.plugin.sh) plugin=${plugin%.plugin.sh} ;; | ||
*) plugin=${plugin#_} ;; | ||
esac | ||
|
||
_omb_util_array_contains available_plugins "$plugin" || | ||
available_plugins+=("$plugin") | ||
done | ||
} | ||
|
||
function _comp_cmd_omb__get_available_themes { | ||
available_themes=() | ||
|
||
local -a theme_files | ||
_omb_util_glob_expand theme_files '{"$OSH","$OSH_CUSTOM"}/themes/*/{_*,*.theme.{bash,sh}}' | ||
|
||
local theme | ||
for theme in "${theme_files[@]##*/}"; do | ||
case $theme in | ||
*.theme.bash) theme=${theme%.theme.bash} ;; | ||
*.theme.sh) theme=${theme%.theme.sh} ;; | ||
*) theme=${theme#_} ;; | ||
esac | ||
|
||
_omb_util_array_contains available_themes "$theme" || | ||
available_themes+=("$theme") | ||
done | ||
} | ||
|
||
## @fn _comp_cmd_omb__get_valid_plugins type | ||
function _comp_cmd_omb__get_valid_plugins { | ||
if [[ $1 == disable ]]; then | ||
# if command is "disable", only offer already enabled plugins | ||
valid_plugins=("${plugins[@]}") | ||
else | ||
local -a available_plugins | ||
_comp_cmd_omb__get_available_plugins | ||
valid_plugins=("${available_plugins[@]}") | ||
|
||
# if command is "enable", remove already enabled plugins | ||
if [[ ${COMP_WORDS[2]} == enable ]]; then | ||
_omb_util_array_remove valid_plugins "${plugins[@]}" | ||
fi | ||
fi | ||
} | ||
|
||
function _comp_cmd_omb { | ||
local shopt | ||
_omb_util_get_shopt extglob | ||
shopt -s extglob | ||
|
||
if ((COMP_CWORD == 1)); then | ||
local -a cmds=( | ||
'changelog:Print the changelog' | ||
'help:Usage information' | ||
'plugin:Manage plugins' | ||
'pr:Manage Oh My Bash Pull Requests' | ||
'reload:Reload the current bash session' | ||
'theme:Manage themes' | ||
'update:Update Oh My Bash' | ||
'version:Show the version' | ||
) | ||
_comp_cmd_omb__describe 'command' cmds | ||
elif ((COMP_CWORD ==2)); then | ||
case "${COMP_WORDS[1]}" in | ||
changelog) | ||
local -a refs | ||
_omb_util_split_lines refs "$(command git -C "$OSH" for-each-ref --format="%(refname:short):%(subject)" refs/heads refs/tags)" | ||
_comp_cmd_omb__describe 'command' refs ;; | ||
plugin) | ||
local -a subcmds=( | ||
'disable:Disable plugin(s)' | ||
'enable:Enable plugin(s)' | ||
'info:Get plugin information' | ||
'list:List plugins' | ||
'load:Load plugin(s)' | ||
) | ||
_describe 'command' subcmds ;; | ||
pr) subcmds=('clean:Delete all Pull Request branches' 'test:Test a Pull Request') | ||
_describe 'command' subcmds ;; | ||
theme) subcmds=('list:List themes' 'set:Set a theme in your .zshrc file' 'use:Load a theme') | ||
_describe 'command' subcmds ;; | ||
_comp_cmd_omb__describe 'command' subcmds ;; | ||
pr) | ||
local -a subcmds=( | ||
'clean:Delete all Pull Request branches' | ||
'test:Test a Pull Request' | ||
) | ||
_comp_cmd_omb__describe 'command' subcmds ;; | ||
theme) | ||
local -a subcmds=( | ||
'list:List themes' | ||
'set:Set a theme in your .zshrc file' | ||
'use:Load a theme' | ||
) | ||
_comp_cmd_omb__describe 'command' subcmds ;; | ||
esac | ||
elif (( CURRENT == 4 )); then | ||
case "${words[2]}::${words[3]}" in | ||
plugin::(disable|enable|load)) | ||
local -aU valid_plugins | ||
|
||
if [[ "${words[3]}" = disable ]]; then | ||
# if command is "disable", only offer already enabled plugins | ||
valid_plugins=($plugins) | ||
else | ||
valid_plugins=("$OSH"/plugins/*/{_*,*.plugin.zsh}(.N:h:t) "$OSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(.N:h:t)) | ||
# if command is "enable", remove already enabled plugins | ||
[[ "${words[3]}" = enable ]] && valid_plugins=(${valid_plugins:|plugins}) | ||
fi | ||
|
||
_describe 'plugin' valid_plugins ;; | ||
plugin::info) | ||
local -aU plugins | ||
plugins=("$OSH"/plugins/*/{_*,*.plugin.zsh}(.N:h:t) "$OSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(.N:h:t)) | ||
_describe 'plugin' plugins ;; | ||
theme::(set|use)) | ||
local -aU themes | ||
themes=("$OSH"/themes/*.zsh-theme(.N:t:r) "$OSH_CUSTOM"/**/*.zsh-theme(.N:r:gs:"$OSH_CUSTOM"/themes/:::gs:"$OSH_CUSTOM"/:::)) | ||
_describe 'theme' themes ;; | ||
elif ((COMP_CWORD == 3)); then | ||
case "${COMP_WORDS[1]}::${COMP_WORDS[2]}" in | ||
plugin::@(disable|enable|load)) | ||
local -a valid_plugins | ||
_comp_cmd_omb__get_valid_plugins "${COMP_WORDS[2]}" | ||
_comp_cmd_omb__describe 'plugin' valid_plugins ;; | ||
plugin::info) | ||
local -a available_plugins | ||
_comp_cmd_omb__get_available_plugins | ||
_comp_cmd_omb__describe 'plugin' available_plugins ;; | ||
theme::@(set|use)) | ||
local -a available_themes | ||
_comp_cmd_omb__get_available_themes | ||
_comp_cmd_omb__describe 'theme' available_themes ;; | ||
esac | ||
elif (( CURRENT > 4 )); then | ||
case "${words[2]}::${words[3]}" in | ||
plugin::(enable|disable|load)) | ||
local -aU valid_plugins | ||
|
||
if [[ "${words[3]}" = disable ]]; then | ||
# if command is "disable", only offer already enabled plugins | ||
valid_plugins=($plugins) | ||
else | ||
valid_plugins=("$OSH"/plugins/*/{_*,*.plugin.zsh}(.N:h:t) "$OSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(.N:h:t)) | ||
# if command is "enable", remove already enabled plugins | ||
[[ "${words[3]}" = enable ]] && valid_plugins=(${valid_plugins:|plugins}) | ||
fi | ||
|
||
# Remove plugins already passed as arguments | ||
# NOTE: $(( CURRENT - 1 )) is the last plugin argument completely passed, i.e. that which | ||
# has a space after them. This is to avoid removing plugins partially passed, which makes | ||
# the completion not add a space after the completed plugin. | ||
local -a args | ||
args=(${words[4,$(( CURRENT - 1))]}) | ||
valid_plugins=(${valid_plugins:|args}) | ||
|
||
_describe 'plugin' valid_plugins ;; | ||
elif ((COMP_CWORD > 3)); then | ||
case "${COMP_WORDS[1]}::${COMP_WORDS[2]}" in | ||
plugin::@(enable|disable|load)) | ||
local -a valid_plugins | ||
_comp_cmd_omb__get_valid_plugins "${COMP_WORDS[2]}" | ||
|
||
# Remove plugins already passed as arguments | ||
# NOTE: $((COMP_CWORD - 1)) is the last plugin argument completely passed, i.e. that which | ||
# has a space after them. This is to avoid removing plugins partially passed, which makes | ||
# the completion not add a space after the completed plugin. | ||
_omb_util_array_remove valid_plugins "${COMP_WORDS[@]:3:COMP_CWORD-3}" | ||
|
||
_comp_cmd_omb__describe 'plugin' valid_plugins ;; | ||
esac | ||
fi | ||
|
||
[[ :$shopt: == *:exptglob:* ]] || shopt -u extglob | ||
return 0 | ||
} | ||
|
||
compdef _omb omb | ||
complete -F _comp_cmd_omb omb | ||
|
||
[[ :$_omb_lib_cli__init_shopt: == *:exptglob:* ]] || shopt -u extglob | ||
unset -v _omb_lib_cli__init_shopt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters