ENH: Better completion for custom add-ons via new listaddons command.

The todo_completion had the problem that it didn't consider the todo.cfg itself for the location of TODO_ACTIONS_DIR, it just tried the default location or a globally exported config value. With the injection of custom configuration now in place, we can actually delegate the listing to todo.sh itself.
The added built-in "listaddons" command is used for that; it may also be helpful for troubleshooting or to find out about available add-ons. (But the help / shorthelp commands offer more information.)

Additionally, completion is now more precise; only executable actions and no subdirs are listed now; this is also covered by the enhanced test.

The last bonus: The custom add-on actions are now only determined when there's actually completion of commands.
This commit is contained in:
Ingo Karkat
2012-02-28 14:55:27 +01:00
parent 6259cdb6da
commit bc81db2f2b
4 changed files with 75 additions and 15 deletions

View File

@@ -7,7 +7,7 @@ This test checks basic todo_completion of actions and options
' '
. ./test-lib.sh . ./test-lib.sh
readonly ACTIONS='add a addto addm append app archive command del rm depri dp do help list ls listall lsa listcon lsc listfile lf listpri lsp listproj lsprj move mv prepend prep pri p replace report shorthelp' readonly ACTIONS='add a addto addm append app archive command del rm depri dp do help list ls listaddons listall lsa listcon lsc listfile lf listpri lsp listproj lsprj move mv prepend prep pri p replace report shorthelp'
readonly OPTIONS='-@ -@@ -+ -++ -d -f -h -p -P -PP -a -n -t -v -vv -V -x' readonly OPTIONS='-@ -@@ -+ -++ -d -f -h -p -P -PP -a -n -t -v -vv -V -x'
test_todo_completion 'all arguments' 'todo.sh ' "$ACTIONS $OPTIONS" test_todo_completion 'all arguments' 'todo.sh ' "$ACTIONS $OPTIONS"

View File

@@ -7,20 +7,68 @@ This test checks todo_completion of custom actions in .todo.actions.d
' '
. ./test-lib.sh . ./test-lib.sh
readonly ACTIONS='add a addto addm append app archive command del rm depri dp do help list ls listall lsa listcon lsc listfile lf listpri lsp listproj lsprj move mv prepend prep pri p replace report shorthelp' readonly ACTIONS='add a addto addm append app archive command del rm depri dp do help list ls listaddons listall lsa listcon lsc listfile lf listpri lsp listproj lsprj move mv prepend prep pri p replace report shorthelp'
readonly OPTIONS='-@ -@@ -+ -++ -d -f -h -p -P -PP -a -n -t -v -vv -V -x' readonly OPTIONS='-@ -@@ -+ -++ -d -f -h -p -P -PP -a -n -t -v -vv -V -x'
readonly ADDONS='bar baz foobar' readonly ADDONS='bar baz foobar'
mkdir "$HOME/.todo.actions.d" makeCustomActions()
for addon in $ADDONS {
do set -e
> "$HOME/.todo.actions.d/$addon" mkdir "${1:?}"
chmod +x "$HOME/.todo.actions.d/$addon" for addon in $ADDONS
done do
addonFile="${1}/$addon"
> "$addonFile"
chmod +x "$addonFile"
done
# Also create a subdirectory, to test that it is skipped.
mkdir "${1}/subdir"
# Also create a non-executable file, to test that it is skipped.
datafile="${1:?}/datafile"
> "$datafile"
chmod -x "$datafile"
[ -x "$datafile" ] && rm "$datafile" # Some file systems may always make files executable; then, skip this check.
set +e
}
removeCustomActions()
{
set -e
rmdir "${1}/subdir"
rm "${1:?}/"*
rmdir "$1"
set +e
}
#
# Test resolution of the default TODO_ACTIONS_DIR.
#
makeCustomActions "$HOME/.todo.actions.d"
test_todo_completion 'all arguments' 'todo.sh ' "$ACTIONS $ADDONS $OPTIONS" test_todo_completion 'all arguments' 'todo.sh ' "$ACTIONS $ADDONS $OPTIONS"
test_todo_completion 'all arguments after option' 'todo.sh -a ' "$ACTIONS $ADDONS $OPTIONS" test_todo_completion 'all arguments after option' 'todo.sh -a ' "$ACTIONS $ADDONS $OPTIONS"
test_todo_completion 'all arguments beginning with b' 'todo.sh b' 'bar baz' test_todo_completion 'all arguments beginning with b' 'todo.sh b' 'bar baz'
test_todo_completion 'all arguments beginning with f after options' 'todo.sh -a -v f' 'foobar' test_todo_completion 'all arguments beginning with f after options' 'todo.sh -a -v f' 'foobar'
test_todo_completion 'nothing after addon action' 'todo.sh foobar ' '' test_todo_completion 'nothing after addon action' 'todo.sh foobar ' ''
removeCustomActions "$HOME/.todo.actions.d"
#
# Test resolution of an alternative TODO_ACTIONS_DIR.
#
mkdir "$HOME/.todo"
makeCustomActions "$HOME/.todo/actions"
test_todo_completion 'all arguments with actions from .todo/actions/' 'todo.sh ' "$ACTIONS $ADDONS $OPTIONS"
removeCustomActions "$HOME/.todo/actions"
#
# Test resolution of a configured TODO_ACTIONS_DIR.
#
makeCustomActions "$HOME/addons"
cat >> todo.cfg <<'EOF'
export TODO_ACTIONS_DIR="$HOME/addons"
EOF
test_todo_completion 'all arguments with actions from addons/' 'todo.sh ' "$ACTIONS $ADDONS $OPTIONS"
removeCustomActions "$HOME/addons"
test_done test_done

16
todo.sh
View File

@@ -57,6 +57,7 @@ shorthelp()
help help
list|ls [TERM...] list|ls [TERM...]
listall|lsa [TERM...] listall|lsa [TERM...]
listaddons
listcon|lsc listcon|lsc
listfile|lf [SRC [TERM...]] listfile|lf [SRC [TERM...]]
listpri|lsp [PRIORITIES] [TERM...] listpri|lsp [PRIORITIES] [TERM...]
@@ -219,6 +220,9 @@ help()
TERM specified, lists entire todo.txt AND done.txt TERM specified, lists entire todo.txt AND done.txt
concatenated and sorted. concatenated and sorted.
listaddons
Lists all added and overridden actions in the actions directory.
listcon listcon
lsc lsc
Lists all the task contexts that start with the @ sign in todo.txt. Lists all the task contexts that start with the @ sign in todo.txt.
@@ -1300,6 +1304,18 @@ note: PRIORITY must be anywhere from A to Z."
fi fi
;; ;;
"listaddons" )
if [ -d "$TODO_ACTIONS_DIR" ]; then
cd "$TODO_ACTIONS_DIR" || exit $?
for action in *
do
if [ -f "$action" -a -x "$action" ]; then
echo "$action"
fi
done
fi
;;
* ) * )
usage;; usage;;
esac esac

View File

@@ -11,18 +11,14 @@ _todo()
local -r OPTS="-@ -@@ -+ -++ -d -f -h -p -P -PP -a -n -t -v -vv -V -x" local -r OPTS="-@ -@@ -+ -++ -d -f -h -p -P -PP -a -n -t -v -vv -V -x"
local -r COMMANDS="\ local -r COMMANDS="\
add a addto addm append app archive command del \ add a addto addm append app archive command del \
rm depri dp do help list ls listall lsa listcon \ rm depri dp do help list ls listaddons listall lsa listcon \
lsc listfile lf listpri lsp listproj lsprj move \ lsc listfile lf listpri lsp listproj lsprj move \
mv prepend prep pri p replace report shorthelp" mv prepend prep pri p replace report shorthelp"
# Add custom commands from add-ons, if installed.
# TODO: Filter for executable flag of files found in $TODO_ACTIONS_DIR.
local allCommands="$COMMANDS $('ls' "${TODO_ACTIONS_DIR:-$HOME/.todo.actions.d}/" 2>/dev/null)"
local _todo_sh=${_todo_sh:-todo.sh} local _todo_sh=${_todo_sh:-todo.sh}
local completions local completions
if [ $COMP_CWORD -eq 1 ]; then if [ $COMP_CWORD -eq 1 ]; then
completions="$allCommands $OPTS" completions="$COMMANDS $(eval TODOTXT_VERBOSE=0 $_todo_sh command listaddons) $OPTS"
elif [[ $COMP_CWORD -gt 2 && ( \ elif [[ $COMP_CWORD -gt 2 && ( \
"${COMP_WORDS[COMP_CWORD-2]}" =~ ^(move|mv)$ || \ "${COMP_WORDS[COMP_CWORD-2]}" =~ ^(move|mv)$ || \
"${COMP_WORDS[COMP_CWORD-3]}" =~ ^(move|mv)$ ) ]]; then "${COMP_WORDS[COMP_CWORD-3]}" =~ ^(move|mv)$ ) ]]; then
@@ -34,7 +30,7 @@ _todo()
completions=$COMMANDS;; completions=$COMMANDS;;
addto|listfile|lf) addto|listfile|lf)
completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listfile);; completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listfile);;
-*) completions="$allCommands $OPTS";; -*) completions="$COMMANDS $(eval TODOTXT_VERBOSE=0 $_todo_sh command listaddons) $OPTS";;
*) case "$cur" in *) case "$cur" in
+*) completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listproj) +*) completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listproj)
COMPREPLY=( $( compgen -W "$completions" -- $cur )) COMPREPLY=( $( compgen -W "$completions" -- $cur ))