mirror of
https://github.com/beetbox/beets.git
synced 2026-01-07 16:34:45 +01:00
Add completion support for bash 3.2
Bash 3.2 does not have associative arrays, so we hack around that by using generic varibale names like `opts__$cmd`. We also don't support the "?" alias anymore.
This commit is contained in:
parent
c5d3483fc3
commit
e8e0682aae
4 changed files with 31 additions and 30 deletions
|
|
@ -33,7 +33,6 @@ def completion_script(commands):
|
|||
}
|
||||
|
||||
# Help subcommand
|
||||
aliases['?'] = 'help'
|
||||
command_names.append('help')
|
||||
|
||||
# Add flags common to all commands
|
||||
|
|
@ -42,17 +41,19 @@ def completion_script(commands):
|
|||
}
|
||||
|
||||
# Start generating the script
|
||||
yield "_beet_setup() {\n"
|
||||
yield " commands='%s'\n" % ' '.join(command_names)
|
||||
yield '\n'
|
||||
yield "_beet() {\n"
|
||||
yield " local commands='%s'\n" % ' '.join(command_names)
|
||||
yield "\n"
|
||||
|
||||
yield " local aliases='%s'\n" % ' '.join(aliases.keys())
|
||||
for alias, cmd in aliases.items():
|
||||
yield(" aliases['%s']='%s'\n" % (alias, cmd))
|
||||
yield " local alias__%s=%s\n" % (alias, cmd)
|
||||
yield '\n'
|
||||
|
||||
for cmd, opts in options.items():
|
||||
for option_type, option_list in opts.items():
|
||||
if option_list:
|
||||
option_list = ' '.join(option_list)
|
||||
yield " %s[%s]='%s'\n" % (option_type, cmd, option_list)
|
||||
yield " local %s__%s='%s'\n" % (option_type, cmd, option_list)
|
||||
yield ' _beet_dispatch\n'
|
||||
yield '}\n'
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
# Note that completion only works for builtin commands and *not* for
|
||||
# commands provided by plugins.
|
||||
#
|
||||
# Currently, only Bash 4.1 and newer is supported.
|
||||
# Currently, only Bash 3.2 and newer is supported.
|
||||
#
|
||||
# TODO
|
||||
# ----
|
||||
|
|
@ -50,25 +50,22 @@
|
|||
# * Support long options with `=`, e.g. `--config=file`. Debian's bash
|
||||
# completion package can handle this.
|
||||
#
|
||||
# * Support for Bash 3.2
|
||||
#
|
||||
|
||||
|
||||
# Main entry point for completion
|
||||
_beet() {
|
||||
local cur prev commands
|
||||
local -A flags opts aliases
|
||||
# Determines the beets subcommand and dispatches the completion
|
||||
# accordingly.
|
||||
_beet_dispatch() {
|
||||
local cur prev
|
||||
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
_beet_setup
|
||||
|
||||
# Look for the beets subcommand
|
||||
local arg cmd=
|
||||
for (( i=1; i < COMP_CWORD; i++ )); do
|
||||
arg="${COMP_WORDS[i]}"
|
||||
if _list_include_item "${opts[_global]}" $arg; then
|
||||
if _list_include_item "${opts___global}" $arg; then
|
||||
((i++))
|
||||
elif [[ "$arg" != -* ]]; then
|
||||
cmd="$arg"
|
||||
|
|
@ -77,8 +74,8 @@ _beet() {
|
|||
done
|
||||
|
||||
# Replace command shortcuts
|
||||
if [[ -n $cmd && -n ${aliases[$cmd]} ]]; then
|
||||
cmd=${aliases[$cmd]}
|
||||
if [[ -n $cmd ]] && _list_include_item "$aliases" "$cmd"; then
|
||||
eval "cmd=\$alias__$cmd"
|
||||
fi
|
||||
|
||||
case $cmd in
|
||||
|
|
@ -93,13 +90,15 @@ _beet() {
|
|||
;;
|
||||
esac
|
||||
}
|
||||
complete -o filenames -F _beet beet
|
||||
|
||||
|
||||
# Adds option and file completion to COMPREPLY for the subcommand $1
|
||||
_beet_complete() {
|
||||
if [[ $cur == -* ]]; then
|
||||
local completions="${flags[_common]} ${opts[$1]} ${flags[$1]}"
|
||||
local opts flags completions
|
||||
eval "opts=\$opts__$1"
|
||||
eval "flags=\$flags__$1"
|
||||
completions="${flags___common} ${opts} ${flags}"
|
||||
COMPREPLY+=( $(compgen -W "$completions" -- $cur) )
|
||||
else
|
||||
COMPREPLY+=( $(compgen -f -- $cur) )
|
||||
|
|
@ -107,7 +106,7 @@ _beet_complete() {
|
|||
}
|
||||
|
||||
|
||||
# Add global options and commands to the completion
|
||||
# Add global options and subcommands to the completion
|
||||
_beet_complete_global() {
|
||||
case $prev in
|
||||
-h|--help)
|
||||
|
|
@ -128,10 +127,12 @@ _beet_complete_global() {
|
|||
esac
|
||||
|
||||
if [[ $cur == -* ]]; then
|
||||
local completions="${opts[_global]} ${flags[_global]}"
|
||||
local completions="$opts___global $flags___global"
|
||||
COMPREPLY+=( $(compgen -W "$completions" -- $cur) )
|
||||
elif [[ -n $cur && -n "${aliases[$cur]}" ]]; then
|
||||
COMPREPLY+=( ${aliases[$cur]} )
|
||||
elif [[ -n $cur ]] && _list_include_item "$aliases" "$cur"; then
|
||||
local cmd
|
||||
eval "cmd=\$alias__$cur"
|
||||
COMPREPLY+=( $cmd )
|
||||
else
|
||||
COMPREPLY+=( $(compgen -W "$commands" -- $cur) )
|
||||
fi
|
||||
|
|
@ -139,8 +140,9 @@ _beet_complete_global() {
|
|||
|
||||
# Returns true if the space separated list $1 includes $2
|
||||
_list_include_item() {
|
||||
[[ $1 =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]
|
||||
[[ " $1 " == *[[:space:]]$2[[:space:]]* ]]
|
||||
}
|
||||
|
||||
# This is where beets dynamically adds the _beet_setup function. This
|
||||
# This is where beets dynamically adds the _beet function. This
|
||||
# function sets the variables $flags, $opts, $commands, and $aliases.
|
||||
complete -o filenames -F _beet beet
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ initcli() {
|
|||
|
||||
completes() {
|
||||
for word in "$@"; do
|
||||
[[ ${COMPREPLY[@]} =~ "$word" ]] || return 1
|
||||
[[ " ${COMPREPLY[@]} " == *[[:space:]]$word[[:space:]]* ]] || return 1
|
||||
done
|
||||
}
|
||||
|
||||
|
|
@ -133,9 +133,6 @@ test_list_options() {
|
|||
test_help_command() {
|
||||
initcli help '' &&
|
||||
completes $COMMANDS &&
|
||||
|
||||
initcli '?' '' &&
|
||||
completes $COMMANDS &&
|
||||
true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -750,7 +750,8 @@ class CompletionTest(_common.TestCase):
|
|||
'test_completion.sh')
|
||||
|
||||
# Tests run in bash
|
||||
tester = subprocess.Popen('/bin/bash', stdin=subprocess.PIPE,
|
||||
shell = os.environ.get('BEETS_TEST_SHELL', '/bin/bash')
|
||||
tester = subprocess.Popen(shell, stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
# Load complection script
|
||||
|
|
|
|||
Loading…
Reference in a new issue