From bc81db2f2b967e04bdb634cb09692844a8a0e2fd Mon Sep 17 00:00:00 2001 From: Ingo Karkat Date: Tue, 28 Feb 2012 14:55:27 +0100 Subject: [PATCH] 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. --- tests/t6000-completion.sh | 2 +- tests/t6050-completion-addons.sh | 62 ++++++++++++++++++++++++++++---- todo.sh | 16 +++++++++ todo_completion | 10 ++---- 4 files changed, 75 insertions(+), 15 deletions(-) diff --git a/tests/t6000-completion.sh b/tests/t6000-completion.sh index da60288..9403b8b 100755 --- a/tests/t6000-completion.sh +++ b/tests/t6000-completion.sh @@ -7,7 +7,7 @@ This test checks basic todo_completion of actions and options ' . ./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' test_todo_completion 'all arguments' 'todo.sh ' "$ACTIONS $OPTIONS" diff --git a/tests/t6050-completion-addons.sh b/tests/t6050-completion-addons.sh index 376da5d..ef38819 100755 --- a/tests/t6050-completion-addons.sh +++ b/tests/t6050-completion-addons.sh @@ -7,20 +7,68 @@ This test checks todo_completion of custom actions in .todo.actions.d ' . ./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 ADDONS='bar baz foobar' -mkdir "$HOME/.todo.actions.d" -for addon in $ADDONS -do - > "$HOME/.todo.actions.d/$addon" - chmod +x "$HOME/.todo.actions.d/$addon" -done +makeCustomActions() +{ + set -e + mkdir "${1:?}" + for addon in $ADDONS + 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 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 f after options' 'todo.sh -a -v f' '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 diff --git a/todo.sh b/todo.sh index 4c2a4d9..4837120 100755 --- a/todo.sh +++ b/todo.sh @@ -57,6 +57,7 @@ shorthelp() help list|ls [TERM...] listall|lsa [TERM...] + listaddons listcon|lsc listfile|lf [SRC [TERM...]] listpri|lsp [PRIORITIES] [TERM...] @@ -219,6 +220,9 @@ help() TERM specified, lists entire todo.txt AND done.txt concatenated and sorted. + listaddons + Lists all added and overridden actions in the actions directory. + listcon lsc 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 ;; +"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;; esac diff --git a/todo_completion b/todo_completion index 4d1870e..9562f16 100644 --- a/todo_completion +++ b/todo_completion @@ -11,18 +11,14 @@ _todo() local -r OPTS="-@ -@@ -+ -++ -d -f -h -p -P -PP -a -n -t -v -vv -V -x" local -r COMMANDS="\ 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 \ 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 completions 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 && ( \ "${COMP_WORDS[COMP_CWORD-2]}" =~ ^(move|mv)$ || \ "${COMP_WORDS[COMP_CWORD-3]}" =~ ^(move|mv)$ ) ]]; then @@ -34,7 +30,7 @@ _todo() completions=$COMMANDS;; addto|listfile|lf) 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 +*) completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listproj) COMPREPLY=( $( compgen -W "$completions" -- $cur ))