mirror of
https://github.com/ohmybash/oh-my-bash.git
synced 2024-09-21 02:17:11 +00:00
lib/cli: Re-implement "omb" and its completion for Bash
This commit is contained in:
parent
4145d7a894
commit
e3d1ba2ea0
263
lib/cli.bash
263
lib/cli.bash
@ -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::$command "$@"
|
||||
_omb_cmd_"$@"
|
||||
}
|
||||
|
||||
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=(
|
||||
_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 _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
|
||||
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]}"
|
||||
|
||||
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: $((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}"
|
||||
|
||||
# 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 ;;
|
||||
_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
|
||||
|
68
lib/utils.sh
68
lib/utils.sh
@ -287,16 +287,30 @@ function pushover {
|
||||
## @fn _omb_util_get_shopt optnames...
|
||||
## @var[out] __shopt
|
||||
if ((_omb_bash_version >= 40100)); then
|
||||
function _omb_util_get_shopt { __shopt=$BASHOPTS; }
|
||||
function _omb_util_get_shopt() {
|
||||
if [[ $1 == -v ]]; then
|
||||
[[ $2 == __shopt ]] || local __shopt
|
||||
_omb_util_get_shopt "${@:3}"
|
||||
[[ $2 == __shopt ]] || printf -v "$2" '%s' "$__shopt"
|
||||
else
|
||||
__shopt=$BASHOPTS
|
||||
fi
|
||||
}
|
||||
else
|
||||
function _omb_util_get_shopt {
|
||||
__shopt=
|
||||
local opt
|
||||
for opt; do
|
||||
if shopt -q "$opt" &>/dev/null; then
|
||||
__shopt=${__shopt:+$__shopt:}$opt
|
||||
fi
|
||||
done
|
||||
if [[ $1 == -v ]]; then
|
||||
[[ $2 == __shopt ]] || local __shopt
|
||||
_omb_util_get_shopt "${@:3}"
|
||||
[[ $2 == __shopt ]] || printf -v "$2" '%s' "$__shopt"
|
||||
else
|
||||
__shopt=
|
||||
local opt
|
||||
for opt; do
|
||||
if shopt -q "$opt" &>/dev/null; then
|
||||
__shopt=${__shopt:+$__shopt:}$opt
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
fi
|
||||
|
||||
@ -414,6 +428,44 @@ function _omb_util_glob_expand {
|
||||
return 0
|
||||
}
|
||||
|
||||
## @fn _omb_util_split_lines array_name string
|
||||
function _omb_util_split_lines {
|
||||
local __set=$- IFS=$'\n'
|
||||
set -f
|
||||
eval "$1=(\$2)"
|
||||
[[ $__set == *f* ]] || set +f
|
||||
return 0
|
||||
}
|
||||
|
||||
## @fn _omb_util_array_remove array_name value
|
||||
function _omb_util_array_contains {
|
||||
[[ $1 == ret ]] ||
|
||||
eval "local -a ret=(\"\${$2[@]}\")"
|
||||
local value
|
||||
for value in "${ret[@]}"; do
|
||||
if [[ $value == "$2" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
## @fn _omb_util_array_remove array_name values...
|
||||
function _omb_util_array_remove {
|
||||
local __script='
|
||||
local iA yA
|
||||
for iA in ${!A[@]}; do
|
||||
for yA in "${@:2}"; do
|
||||
if [[ ${A[iA]} == "$yA" ]]; then
|
||||
unset -v '\''A[iA]'\''
|
||||
continue 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
A=("${A[@]}") # compaction
|
||||
'; eval -- "${__script//A/$1}"
|
||||
}
|
||||
|
||||
function _omb_util_alias {
|
||||
case ${OMB_DEFAULT_ALIASES:-enable} in
|
||||
(disable) return 0 ;;
|
||||
|
Loading…
Reference in New Issue
Block a user