Use bash-completion package

This commit is contained in:
Thomas Scholtes 2014-02-27 17:52:23 +01:00
parent 211d3ac1cb
commit 996a1d6c90
3 changed files with 25 additions and 76 deletions

View file

@ -60,8 +60,7 @@ _beet_dispatch() {
local cur prev
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
_get_comp_words_by_ref cur prev
# Look for the beets subcommand
local arg cmd=
@ -103,7 +102,7 @@ _beet_complete() {
completions="${flags___common} ${opts} ${flags}"
COMPREPLY+=( $(compgen -W "$completions" -- $cur) )
else
_beet_complete_filedir
_filedir
fi
}
@ -118,12 +117,12 @@ _beet_complete_global() {
;;
-l|--library|-c|--config)
# Filename completion
_beet_complete_filedir
_filedir
return
;;
-d|--directory)
# Directory completion
_beet_complete_filedir -d
_filedir -d
return
;;
esac
@ -140,63 +139,6 @@ _beet_complete_global() {
fi
}
# This function performs file and directory completion. It's better than
# simply using 'compgen -f', because it honours spaces in filenames.
# @param $1 If `-d', complete only on directories. Otherwise filter/pick only
# completions with `.$1' and the uppercase version of it as file
# extension.
#
# This function is based on code from debian's bash-completion package.
# <http://bash-completion.alioth.debian.org>
# Copyright the Bash Completion Maintainers
# <bash-completion-devel@lists.alioth.debian.org>
#
_beet_complete_filedir() {
local IFS=$'\n'
local tmp quoted_cur opt="$1"
_beet_quote_for_readline "$cur" quoted_cur
if [[ "$opt" != -d ]]; then
opt=-f
fi
while read -r tmp; do
COMPREPLY+=( "$tmp" )
done <<< "$(compgen "$opt" -- "$quoted_cur")"
}
# This function quotes the argument in a way so that readline dequoting
# results in the original argument. This is necessary for at least
# `compgen' which requires its arguments quoted/escaped:
# $ ls "a'b/"
# c
# $ compgen -f "a'b/" # Wrong, doesn't return output
# $ compgen -f "a\'b/" # Good
# a\'b/c
#
# @param $1 Argument to quote
# @param $2 Name of variable to return result to
#
# This function was copied from debian's bash-completion package.
# <http://bash-completion.alioth.debian.org>
# Copyright the Bash Completion Maintainers
# <bash-completion-devel@lists.alioth.debian.org>
#
_beet_quote_for_readline()
{
if [[ $1 == \'* ]]; then
# Leave out first character
printf -v $2 %s "${1:1}"
elif [[ -z $1 ]]; then
# Do not quote the empty string
printf -v $2 %s "$1"
else
printf -v $2 %q "$1"
fi
[[ ${!2} == \$* ]] && eval $2=${!2}
}
# Returns true if the space separated list $1 includes $2
_list_include_item() {
[[ " $1 " == *[[:space:]]$2[[:space:]]* ]]

View file

@ -1,10 +1,8 @@
#!/bin/bash
. /etc/bash_completion
initcli() {
COMP_WORDS=( "beet" "$@" )
let COMP_CWORD=${#COMP_WORDS[@]}-1
COMP_LINE="${COMP_WORDS[@]}"
let COMP_POINT=${#COMP_LINE}
_beet
}
@ -64,17 +62,20 @@ test_global_opts() {
test_global_file_opts() {
# FIXME somehow file completion only works when the completion
# function is called by the shell completion utilities. So we can't
# test it here
initcli --library '' &&
completes $(compgen -f) &&
completes $(compgen -d) &&
initcli -l '' &&
completes $(compgen -f) &&
completes $(compgen -d) &&
initcli --config '' &&
completes $(compgen -f) &&
completes $(compgen -d) &&
initcli -c '' &&
completes $(compgen -f) &&
completes $(compgen -d) &&
true
}
@ -94,20 +95,20 @@ test_fields_command() {
completes -h --help &&
initcli fields '' &&
completes $(compgen -f) &&
completes $(compgen -d) &&
true
}
test_import_files() {
initcli import '' &&
completes $(compgen -f) &&
completes $(compgen -d) &&
initcli import --copy -P '' &&
completes $(compgen -f) &&
completes $(compgen -d) &&
initcli import --log '' &&
completes $(compgen -f) &&
completes $(compgen -d) &&
true
}

View file

@ -748,12 +748,17 @@ class CompletionTest(_common.TestCase):
def test_completion(self):
test_script = os.path.join(os.path.dirname(__file__),
'test_completion.sh')
bash_completion = '/etc/bash_completion'
# Tests run in bash
shell = os.environ.get('BEETS_TEST_SHELL', '/bin/bash --norc')
tester = subprocess.Popen(shell.split(' '), stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
# Load bash_completion
with open(bash_completion, 'r') as bash_completion:
tester.stdin.writelines(bash_completion)
# Load complection script
self.io.install()
ui._raw_main(['completion'])
@ -765,8 +770,9 @@ class CompletionTest(_common.TestCase):
with open(test_script, 'r') as test_script:
tester.stdin.writelines(test_script)
(out, err) = tester.communicate()
self.assertEqual(tester.returncode, 0)
self.assertEqual(out, "completion tests passed\n")
if tester.returncode != 0 or out != "completion tests passed\n":
print(out)
self.fail('test/test_completion.sh did not execute properly')
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)