Compare commits

..

32 Commits

Author SHA1 Message Date
Ingo Karkat
a5481990fd completion: Add recommendation about where to put alias customization.
There was a discussion on the mailing list about upgrades and where to put it.
2012-05-08 11:10:22 +02:00
Ingo Karkat
38d75afeff BUG: completion of task number didn't remove add date.
Need to make match of preceding priority optional.
Also tighten patterns for priority and done marker by anchoring them to the front, as the leading task number has already been substituted away.
2012-05-08 10:55:00 +02:00
Gina Trapani
ebe6a403c8 Merge pull request #81 from todb-r7/master
.gitignore for local data files.
2012-03-26 11:56:04 -07:00
Tod Beardsley
a6fed991e5 Ignore user data.
If you run out of git checkouts, should probably ignore the todo.txt
data file (and friends).
2012-03-19 11:00:51 -05:00
Gina Trapani
94f770926b Merge pull request #80 from inkarkat/complete-enhancements
Complete enhancements
2012-03-01 10:26:17 -08:00
Ingo Karkat
322f3075d2 FIX: task number completion doesn't work on OS X.
The recently added tests revealed that. Because of the sed \+ bound. As in  f3fc18af6b, fall back to the \{1,\} basic regexp.
2012-02-29 09:00:35 +01:00
Ingo Karkat
bc81db2f2b 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.
2012-02-29 08:53:18 +01:00
Ingo Karkat
6259cdb6da Add test for custom add-on action completion. 2012-02-29 08:53:17 +01:00
Ingo Karkat
f76b6d5210 Add test for todo file completion. 2012-02-29 08:53:17 +01:00
Ingo Karkat
c1ad7f3560 Add more test cases for arguments and options completion. 2012-02-29 08:53:17 +01:00
Ingo Karkat
a777b266ed Add test for task number completion. 2012-02-29 08:53:17 +01:00
Ingo Karkat
ebce735d04 test-lib: Allow completions containing whitespace.
This is necessary to test the completion of task text.
2012-02-29 08:53:17 +01:00
Ingo Karkat
e5a308eb03 test-lib: Also document test_expect_code. 2012-02-29 08:53:16 +01:00
Ingo Karkat
e600a2162b ENH: completion can use different todo.sh locations and configurations.
This was previously not supported; todo_completion always used plain todo.sh from the PATH. Now it's possible to override the used executable (and configuration used through _todo_sh, set from a completion function wrapper.

Cp. http://tech.groups.yahoo.com/group/todotxt/message/4003
2012-02-29 08:53:16 +01:00
Ingo Karkat
3d0a4d0b30 test-lib: Add test_todo_custom_completion variant.
This extension of test_todo_completion additionally takes the completion function to use, so that customized completions for todo.sh aliases can be tested.
2012-02-29 08:53:16 +01:00
Gina Trapani
79f428779c Merge pull request #77 from inkarkat/complete-from-done
Complete from done
2012-02-28 13:53:54 -08:00
Ingo Karkat
c1dcd0ed78 test-lib: Also check completion exit code.
The completion may unexpectedly abort somewhere.

Additionally, reformat the failure messages (don't prepend a "*", this should be reserved to mark the individual test runs) and use "compreply" instead of "output", so that it's already clear from the diff output that the completion is being tested.
2012-02-23 09:14:42 +01:00
Ingo Karkat
c9d1993dc8 test-lib: Avoid empty line in diff when no completion.
There should be a trailing newline when there are completions (to avoid diff complaining about "no trailing newline", but not when there are no completions at all.
2012-02-23 09:14:42 +01:00
Ingo Karkat
451dbdda6b Merge duplicate test files for listproj.
t1260-listprj.sh was accidentally created; the tests should be in t1320-listproj.sh.
2012-02-23 09:14:42 +01:00
Ingo Karkat
060e81aa05 ENH: completion offers projects and contexts from done.txt.
This is useful when there are no open projects/contexts any more, but one wants to re-use an existing name.
2012-02-23 09:14:42 +01:00
Ingo Karkat
296bad334d Add tests for project and context completion. 2012-02-23 09:14:42 +01:00
Ingo Karkat
3b90d09b27 Add testing of todo_completion.
Before adding any more features to todo_completion, I feel like I need test coverage, so this is a first stab at testing the completion results, via a new test function test_todo_completion.
Some basic tests showcase the capabilities.

Note: test-lib.sh now uses arrays, therefore all tests must use /bin/bash, not /bin/sh to avoid errors when sourcing test-lib. For consistency with todo.sh, we should have used Bash everywhere, anyway. Also note that t2000-multiline.sh needs some more quoting to avoid "Bash: ambiguous redirect" errors.
2012-02-23 09:14:41 +01:00
Ingo Karkat
46afb7f46a ENH: TODOTXT_SOURCEVAR enables different source file for listproj. 2012-02-23 09:14:41 +01:00
Ingo Karkat
9e13dfd290 ENH: TODOTXT_SOURCEVAR enables different source file for listcon.
To be used by todo_completion (to offer candidates from done.txt when there are no matches in todo.txt), and maybe by custom addons.
2012-02-23 09:14:41 +01:00
Gina Trapani
fbee428e75 Merge pull request #76 from inkarkat/reintroduce-mawk-support
Revert to safer POSIX AWK regexp.
2012-02-21 11:44:37 -08:00
Ingo Karkat
3b960a2e3c Revert to safer POSIX AWK regexp.
AWK from Ubuntu 8.04 (mawk) doesn't support [[:space:]]; so for backwards compatibility use a plain ASCII space instead.
2012-02-21 09:18:39 +01:00
Gina Trapani
ad1ca6c2c9 Merge pull request #75 from inkarkat/rid-tmp-file
Split up _list() and get rid of $TMP_FILE and cleanup().
2012-02-14 21:59:10 -08:00
Gina Trapani
36e018fd86 Merge pull request #74 from inkarkat/listpri-pri-range
ENH: Allow listpri filtering with priority ranges.
2012-02-14 21:58:26 -08:00
Ingo Karkat
be0a0265d1 Also get rid of TMP_FILE in todo.cfg.
There's a slight chance that some add-on has used this (undocumented, unofficial) configuration value for its own purposes (and maybe also relied on the unexposed cleanup() infrastructure), but detecting and fixing that problem (by moving the cleanup into the add-on itself) is pretty straightforward.
2012-01-26 16:21:46 +01:00
Ingo Karkat
cf7f7531be Break up _list(), get rid of TMP_FILE.
Extract a new function _format() (and getPadding(), both also exported for add-ons) from _list(), which includes the main formatting and filtering pipeline, without the file handling and verbose summary. This can receive the todo file via stdin, so the listall action is able to format the concatenated files without going through a temporary file.

Eventually, after further refactorings, _format() could be used for actual formatted verbose messages in all commands; currently, the raw, unformatted task is printed.
2012-01-26 16:18:30 +01:00
Ingo Karkat
28ec5a06f2 Get rid of cleanup, only use TMP_FILE in listall.
After the recent refactorings, the temporary file is only needed for the listall action. Therefore, the creation-checks and eventual cleanup can be restricted to the listall action, which should slightly speed up the overall script execution.
2012-01-26 14:48:29 +01:00
Ingo Karkat
dfec12e2a4 ENH: Allow listpri filtering with priority ranges.
So far, the listpri action only supports a single priority. Allowing priority ranges (e.g. todo.sh listpri A-C @work) is a simple but useful enhancement.

Note: The syntax extension only clashes with the [TERM] filtering in a few corner cases, and this can be worked around (e.g. "todo.sh listpri A-Z A-Z" lists all prioritized tasks containing the text A-Z).
2012-01-26 13:17:31 +01:00
42 changed files with 590 additions and 109 deletions

3
.gitignore vendored
View File

@@ -1,3 +1,6 @@
VERSION-FILE
tests/test-results
tests/trash\ directory.*
done.txt
report.txt
todo.txt

View File

@@ -125,10 +125,10 @@ Writing Tests
-------------
The test script is written as a shell script. It should start
with the standard "#!/bin/sh" with copyright notices, and an
with the standard "#!/bin/bash" with copyright notices, and an
assignment to variable 'test_description', like this:
#!/bin/sh
#!/bin/bash
#
# Copyright (c) 2005 Junio C Hamano
#
@@ -186,6 +186,24 @@ library for your script to use.
expected output. (See below for how to generate transcripts
easily.)
- test_todo_completion <message> <cmdline> <completions>
This takes three strings as parameter. Based on <cmdline>,
the todo_completion script is triggered in the current test
environment and completions are compared with <completions>,
which should be a space-separated list. If any completion
contains whitespace, quote it; the entire <completions>
argument is eval()'ed.
Include a trailing space in <cmdline> when you want to check
new argument completion; otherwise, completion is triggered
with the context of the last argument. <message> should state
what it is testing.
- test_todo_custom_completion <completefunc> <message> <cmdline> <completions>
Same as above, but in addition allows to specify a custom
completion function.
- test_tick [interval]
The test harness has an internal view of time which is
@@ -205,6 +223,13 @@ library for your script to use.
'git-write-tree should be able to write an empty tree.' \
'tree=$(git-write-tree)'
- test_expect_code <code> <message> <script>
This takes an exit status and two strings as parameter, and
evaluates the <script>. If it yields <code>, test is
considered successful. <message> should state what it is
testing.
- test_expect_failure <message> <script>
This is NOT the opposite of test_expect_success, but is used

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='todo.sh configuration file location

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='todo.sh basic null functionality test.

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='todo.sh actions.d

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='no old-style backtick command substitution

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='basic add and list functionality

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='test the date on add feature

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='basic addto and list functionality

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='test the date on addto feature

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='basic replace functionality

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='basic priority functionality
'

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='list priority functionality
'

View File

@@ -1,42 +0,0 @@
#!/bin/sh
test_description='list project functionality
'
. ./test-lib.sh
cat > todo.txt <<EOF
(B) smell the uppercase Roses +roses @outside +shared
(C) notice the sunflowers +sunflowers @garden +shared +landscape
stop
EOF
test_todo_session 'basic listproj' <<EOF
>>> todo.sh listproj
+landscape
+roses
+shared
+sunflowers
EOF
test_todo_session 'listproj with context' <<EOF
>>> todo.sh listproj @garden
+landscape
+shared
+sunflowers
EOF
TEST_TODO_CUSTOM=todo-custom.cfg
cat todo.cfg > "$TEST_TODO_CUSTOM"
cat >> "$TEST_TODO_CUSTOM" <<'EOF'
export DEFAULT='</color>'
export PRI_B='<color type=green>'
export PRI_C='<color type=blue>'
export TODOTXT_FINAL_FILTER='grep -i roses'
EOF
test_todo_session 'listproj with context special cases' <<EOF
>>> todo.sh -+ -d "$TEST_TODO_CUSTOM" listproj @garden
+landscape
+shared
+sunflowers
EOF
test_done

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
test_description='list functionality

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
test_description='listcon functionality
@@ -55,4 +55,23 @@ test_todo_session 'listcon e-mail address test' <<EOF
@con02
EOF
cat > todo.txt <<EOF
@con01 -- Some context 1 task
EOF
cat > done.txt <<EOF
x 2012-02-21 @done01 -- Some context 1 done task
x 2012-02-21 @done02 -- Some context 2 done task
EOF
test_todo_session 'listcon from done tasks' <<'EOF'
>>> TODOTXT_SOURCEVAR=\$DONE_FILE todo.sh listcon
@done01
@done02
EOF
test_todo_session 'listcon from combined open + done tasks' <<'EOF'
>>> TODOTXT_SOURCEVAR='("$TODO_FILE" "$DONE_FILE")' todo.sh listcon
@con01
@done01
@done02
EOF
test_done

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
test_description='listproj functionality
@@ -55,4 +55,63 @@ test_todo_session 'listproj embedded + test' <<EOF
+prj02
EOF
cat > todo.txt <<EOF
(B) smell the uppercase Roses +roses @outside +shared
(C) notice the sunflowers +sunflowers @garden +shared +landscape
stop
EOF
test_todo_session 'basic listproj' <<EOF
>>> todo.sh listproj
+landscape
+roses
+shared
+sunflowers
EOF
test_todo_session 'listproj with context' <<EOF
>>> todo.sh listproj @garden
+landscape
+shared
+sunflowers
EOF
TEST_TODO_CUSTOM=todo-custom.cfg
cat todo.cfg > "$TEST_TODO_CUSTOM"
cat >> "$TEST_TODO_CUSTOM" <<'EOF'
export DEFAULT='</color>'
export PRI_B='<color type=green>'
export PRI_C='<color type=blue>'
export TODOTXT_FINAL_FILTER='grep -i roses'
EOF
test_todo_session 'listproj with context special cases' <<EOF
>>> todo.sh -+ -d "$TEST_TODO_CUSTOM" listproj @garden
+landscape
+shared
+sunflowers
EOF
cat > todo.txt <<EOF
+prj01 -- Some project 1 task
EOF
cat > done.txt <<EOF
x 2012-02-21 +done01 -- Special project 1 done task
x 2012-02-21 +done02 -- Some project 2 done task
EOF
test_todo_session 'listproj from done tasks' <<'EOF'
>>> TODOTXT_SOURCEVAR=\$DONE_FILE todo.sh listproj
+done01
+done02
EOF
test_todo_session 'listproj from done tasks with filtering' <<'EOF'
>>> TODOTXT_SOURCEVAR=\$DONE_FILE todo.sh listproj Special
+done01
EOF
test_todo_session 'listproj from combined open + done tasks' <<'EOF'
>>> TODOTXT_SOURCEVAR='("$TODO_FILE" "$DONE_FILE")' todo.sh listproj
+done01
+done02
+prj01
EOF
test_done

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
test_description='list highlighting

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='listall functionality
'

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='basic prepend functionality
'

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='do functionality
'

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='basic append functionality

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='basic depriority functionality
'

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='basic del functionality
'

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='archive functionality

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='deduplicate functionality

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='report functionality

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='Multi-line functionality'
@@ -8,18 +8,18 @@ test_description='Multi-line functionality'
# Create the expected file
echo "1 smell the cheese
TODO: Replaced task with:
1 eat apples eat oranges drink milk">$HOME/expect.multi
1 eat apples eat oranges drink milk">"$HOME/expect.multi"
test_expect_success 'multiline squash item replace' '
(
# Prepare single line todo file
cat /dev/null > $HOME/todo.txt
cat /dev/null > "$HOME/todo.txt"
"$HOME/bin/todo.sh" add smell the cheese
# Run replace
"$HOME/bin/todo.sh" replace 1 "eat apples
eat oranges
drink milk" > $HOME/output.multi
drink milk" > "$HOME/output.multi"
# Test output against expected
diff "$HOME/output.multi" "$HOME/expect.multi"
@@ -34,18 +34,18 @@ fi
## Add test
# Create the expected file
echo "2 eat apples eat oranges drink milk
TODO: 2 added.">$HOME/expect.multi
TODO: 2 added.">"$HOME/expect.multi"
test_expect_success 'multiline squash item add' '
(
# Prepare single line todo file
cat /dev/null > $HOME/todo.txt
cat /dev/null > "$HOME/todo.txt"
"$HOME/bin/todo.sh" add smell the cheese
# Run add
"$HOME/bin/todo.sh" add "eat apples
eat oranges
drink milk" > $HOME/output.multi
drink milk" > "$HOME/output.multi"
# Test output against expected
diff "$HOME/output.multi" "$HOME/expect.multi"
@@ -59,18 +59,18 @@ fi
## Append test
# Create the expected file
echo "1 smell the cheese eat apples eat oranges drink milk">$HOME/expect.multi
echo "1 smell the cheese eat apples eat oranges drink milk">"$HOME/expect.multi"
test_expect_success 'multiline squash item append' '
(
# Prepare single line todo file
cat /dev/null > $HOME/todo.txt
cat /dev/null > "$HOME/todo.txt"
"$HOME/bin/todo.sh" add smell the cheese
# Run append
"$HOME/bin/todo.sh" append 1 "eat apples
eat oranges
drink milk" > $HOME/output.multi
drink milk" > "$HOME/output.multi"
# Test output against expected
diff "$HOME/output.multi" "$HOME/expect.multi"
@@ -84,18 +84,18 @@ fi
## Prepend test
# Create the expected file
echo "1 eat apples eat oranges drink milk smell the cheese">$HOME/expect.multi
echo "1 eat apples eat oranges drink milk smell the cheese">"$HOME/expect.multi"
test_expect_success 'multiline squash item prepend' '
(
# Prepare single line todo file
cat /dev/null > $HOME/todo.txt
cat /dev/null > "$HOME/todo.txt"
"$HOME/bin/todo.sh" add smell the cheese
# Run prepend
"$HOME/bin/todo.sh" prepend 1 "eat apples
eat oranges
drink milk" > $HOME/output.multi
drink milk" > "$HOME/output.multi"
# Test output against expected
diff "$HOME/output.multi" "$HOME/expect.multi"
@@ -110,18 +110,18 @@ fi
## Multiple line addition
# Create the expected file
echo "2 eat apples
TODO: 2 added." > $HOME/expect.multi
TODO: 2 added." > "$HOME/expect.multi"
echo "3 eat oranges
TODO: 3 added." >>$HOME/expect.multi
TODO: 3 added." >>"$HOME/expect.multi"
echo "4 drink milk
TODO: 4 added." >> $HOME/expect.multi
TODO: 4 added." >>"$HOME/expect.multi"
test_expect_success 'actual multiline add' '
(
# Run addm
"$HOME/bin/todo.sh" addm "eat apples
eat oranges
drink milk" > $HOME/output.multi
drink milk" > "$HOME/output.multi"
# Test output against expected
diff "$HOME/output.multi" "$HOME/expect.multi"

22
tests/t6000-completion.sh Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/bash
#
test_description='Bash completion functionality
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 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"
test_todo_completion 'arguments beginning with a' 'todo.sh a' 'add a addto addm append app archive'
test_todo_completion 'all options' 'todo.sh -' "$OPTIONS"
test_todo_completion 'all actions after command action' 'todo.sh command ' "$ACTIONS"
test_todo_completion 'all arguments after option' 'todo.sh -a ' "$ACTIONS $OPTIONS"
test_todo_completion 'all arguments after options' 'todo.sh -a -p ' "$ACTIONS $OPTIONS"
test_todo_completion 'all options after options' 'todo.sh -a -p -' "$OPTIONS"
test_todo_completion 'nothing after action' 'todo.sh archive ' ''
test_done

View File

@@ -0,0 +1,27 @@
#!/bin/bash
#
test_description='Bash context completion functionality
This test checks todo_completion of contexts
'
. ./test-lib.sh
cat > todo.txt <<EOF
(B) smell the +roses @outside @outdoor +shared
notice the sunflowers +sunflowers @outside @garden +shared +landscape
stop
EOF
cat > done.txt <<EOF
x 2012-02-21 +herbs @oriental buy spices
x 2012-02-21 +slack @home watch tv
EOF
test_todo_completion 'all contexts' 'todo.sh list @' '@garden @outdoor @outside'
test_todo_completion 'contexts beginning with o' 'todo.sh list @o' '@outdoor @outside'
test_todo_completion 'contexts beginning with outs' 'todo.sh list @outs' '@outside'
test_todo_completion 'contexts beginning with x' 'todo.sh list @x' ''
test_todo_completion 'contexts from done tasks beginning with h' 'todo.sh list @h' '@home'
test_todo_completion 'contexts from done tasks beginning with or' 'todo.sh list @or' '@oriental'
test_done

View File

@@ -0,0 +1,27 @@
#!/bin/bash
#
test_description='Bash project completion functionality
This test checks todo_completion of projects
'
. ./test-lib.sh
cat > todo.txt <<EOF
(B) smell the +roses @outside @outdoor +shared
notice the sunflowers +sunflowers @outside @garden +shared +landscape
stop
EOF
cat > done.txt <<EOF
x 2012-02-21 +herbs @oriental buy spices
x 2012-02-21 +slack @home watch tv
EOF
test_todo_completion 'all projects' 'todo.sh list +' '+landscape +roses +shared +sunflowers'
test_todo_completion 'projects beginning with s' 'todo.sh list +s' '+shared +sunflowers'
test_todo_completion 'projects beginning with ro' 'todo.sh list +ro' '+roses'
test_todo_completion 'projects beginning with x' 'todo.sh list +x' ''
test_todo_completion 'projects from done tasks beginning with h' 'todo.sh list +h' '+herbs'
test_todo_completion 'projects from done tasks beginning with sl' 'todo.sh list +sl' '+slack'
test_done

27
tests/t6030-completion-tasks.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/bin/bash
#
test_description='Bash task number completion functionality
This test checks todo_completion of a task number into the abbreviated task text.
'
. ./test-lib.sh
cat > todo.txt <<EOF
simple task
notice the sunflowers +sunflowers @outside @garden +shared +landscape
(B) smell the +roses flower @outside @outdoor +shared
(C) 2012-02-28 @outside mow the lawn
x 2012-02-21 +herbs @oriental buy spices
x 2012-02-28 2012-02-21 +slack @home watch tv
2012-02-28 +herbs buy cinnamon @grocer
EOF
test_todo_completion 'simple task' 'todo.sh list 1' '"1 # simple task"'
test_todo_completion 'remove projects and contents from task' 'todo.sh list 2' '"2 # notice the sunflowers"'
test_todo_completion 'keep priority' 'todo.sh list 3' '"3 # (B) smell the flower"'
test_todo_completion 'keep priority and remove timestamp' 'todo.sh list 4' '"4 # (C) mow the lawn"'
test_todo_completion 'keep done marker and remove done date' 'todo.sh list 5' '"5 # x buy spices"'
test_todo_completion 'keep done marker and remove timestamp and done date' 'todo.sh list 6' '"6 # x watch tv"'
test_todo_completion 'remove add date' 'todo.sh list 7' '"7 # buy cinnamon"'
test_done

21
tests/t6040-completion-files.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
#
test_description='Bash todo file completion functionality
This test checks todo_completion of files in TODO_DIR.
'
. ./test-lib.sh
> dummy.txt
readonly FILES='done.txt dummy.txt report.txt todo.txt'
test_todo_completion 'all files after addto' 'todo.sh addto ' "$FILES"
test_todo_completion 'files beginning with d after addto' 'todo.sh addto d' 'done.txt dummy.txt'
test_todo_completion 'all files after listfile' 'todo.sh listfile ' "$FILES"
test_todo_completion 'all files after lf' 'todo.sh -v lf ' "$FILES"
test_todo_completion 'nothing after move' 'todo.sh move ' ''
test_todo_completion 'all files after move ITEM#' 'todo.sh move 1 ' "$FILES"
test_todo_completion 'all files after mv ITEM#' 'todo.sh mv 1 ' "$FILES"
test_todo_completion 'all files after move ITEM# DEST' 'todo.sh move 1 todo.sh ' "$FILES"
test_done

View File

@@ -0,0 +1,74 @@
#!/bin/bash
#
test_description='Bash add-on action completion functionality
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 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'
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

45
tests/t6080-completion-path.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/bash
#
test_description='Bash completion with different path functionality
This test checks that todo_completion can use a different path to todo.sh when
it is not accessible through PATH.
'
. ./test-lib.sh
cat > todo.txt <<EOF
(B) smell the +roses @outside @outdoor +shared
notice the sunflowers +sunflowers @outside @garden +shared +landscape
stop
EOF
mv bin/todo.sh bin/todo2.sh
test_expect_success 'todo2.sh executable' 'todo2.sh list'
# Define a second completion function that injects the different executable. In
# real use, this would be installed via
# complete -F _todo2 todo2.sh
_todo2()
{
local _todo_sh='todo2.sh'
_todo "$@"
}
test_todo_custom_completion _todo2 'all todo2 contexts' 'todo2 list @' '@garden @outdoor @outside'
# Remove the test environment's bin directory from the PATH, so that our test
# executable must be launched with an explicit path.
PATH=${PATH##"${PWD}/bin:"}
test_expect_code 127 'todo2.sh executable not in PATH' 'todo2.sh'
_todo2path()
{
local _todo_sh='./bin/todo2.sh'
_todo "$@"
}
test_todo_custom_completion _todo2path 'all todo2 contexts' 'todo2 list @' '@garden @outdoor @outside'
test_done

View File

@@ -0,0 +1,62 @@
#!/bin/bash
#
test_description='Bash completion with different aliases functionality
This test checks that todo_completion can use a different configuration
when another todo.sh alias is defined that uses that configuration.
'
. ./test-lib.sh
cat > todo.txt <<EOF
(B) smell the +roses @outside @outdoor +shared
notice the sunflowers +sunflowers @outside @garden +shared +landscape
stop
EOF
cat > todo2.txt <<EOF
+herbs @oriental buy spices
+slack @home watch tv
EOF
cp todo.cfg todo2.cfg
cat >> todo2.cfg <<'EOF'
export TODO_FILE="$TODO_DIR/todo2.txt"
EOF
# Note: We cannot use aliases within the test framework, but functions are
# equivalent and work fine.
todo1()
{
todo.sh "$@"
}
todo2()
{
todo.sh -d "$HOME/todo2.cfg" "$@"
}
# Ensure that the test fixture works as planned.
test_todo_session 'todo 1 and 2 contexts' <<EOF
>>> todo1 listcon
@garden
@outdoor
@outside
>>> todo2 listcon
@home
@oriental
EOF
# Define a second completion function that injects the different configuration
# file. In real use, this would be installed via
# complete -F _todo2 todo2
_todo2()
{
local _todo_sh='todo.sh -d "$HOME/todo2.cfg"'
_todo "$@"
}
test_todo_completion 'all todo1 contexts' 'todo1 list @' '@garden @outdoor @outside'
test_todo_custom_completion _todo2 'all todo2 contexts' 'todo2 list @' '@home @oriental'
test_done

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='custom actions functionality

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='basic tests imported from previous framework
'

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
# Copyright (c) 2005 Junio C Hamano
#
@@ -305,7 +305,7 @@ $cmp_output"
else
cmp_output=$(test_cmp expect output)
test_failure_ "$2" "$3" "
* expected exit code $1, actual ${eval_ret}${cmp_output:+
expected exit code $1, actual ${eval_ret}${cmp_output:+
}${cmp_output}"
fi
fi
@@ -324,7 +324,7 @@ test_expect_code () {
test_ok_ "$2"
else
test_failure_ "$2" "$3" "
* expected exit code $1, actual ${eval_ret}"
expected exit code $1, actual ${eval_ret}"
fi
fi
echo >&3 ""
@@ -632,6 +632,66 @@ EOF
exit 0
}
test_todo_custom_completion () {
test "$#" = 4 ||
error "bug in the test script: not 4 parameters to test_todo_custom_completion"
completeFunc=$1
shift
if ! test_skip "$@"
then
description=$1
expected=$3
if [ "${2: -1}" = ' ' ]
then
offset=0
say >&3 "expecting completions after: '$2'"
else
offset=1
say >&3 "expecting context completions for: '$2'"
fi
SAVEIFS=$IFS
IFS=' ' set -- $2
COMP_WORDS=("$@")
COMP_CWORD=$(($# - $offset))
IFS=' ' eval "set -- $expected"
EXPECT=("$@")
source "$TEST_DIRECTORY/../todo_completion"
$completeFunc
ret=$?
if [ "$ret" = 0 ]
then
IFS=$'\n'
printf "%s${EXPECT:+\\n}" "${EXPECT[*]}" > expect
printf "%s${COMPREPLY:+\\n}" "${COMPREPLY[*]}" > compreply
IFS=$SAVEIFS
if [ ${#COMPREPLY[@]} -eq ${#EXPECT[@]} ]
then
if [ "${COMPREPLY[*]}" = "${EXPECT[*]}" ]
then
test_ok_ "$description"
else
test_failure_ "$description" "$(test_cmp expect compreply)"
fi
else
test_failure_ "$description" "expected ${#EXPECT[@]} completion(s), got ${#COMPREPLY[@]}:
$(test_cmp expect compreply)"
fi
else
test_failure_ "$description" "expected completions, actual exit code $ret"
fi
fi
echo >&3 ""
}
test_todo_completion () {
test "$#" = 3 ||
error "bug in the test script: not 3 parameters to test_todo_completion"
test_todo_custom_completion _todo "$@"
}
test_init_todo "$test"
# Use -P to resolve symlinks in our working directory so that the pwd
# in subprocesses equals our $PWD (for pathname comparisons).

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
test_description='Providing an interactive shell in the proper environment'
. ./test-lib.sh

29
todo.sh
View File

@@ -57,6 +57,7 @@ shorthelp()
help
list|ls [TERM...]
listall|lsa [TERM...]
listaddons
listcon|lsc
listfile|lf [SRC [TERM...]]
listpri|lsp [PRIORITIES] [TERM...]
@@ -136,7 +137,7 @@ help()
EndOptionsHelp
[ $TODOTXT_VERBOSE -gt 1 ] && cat <<-EndVerboseHelp
[ $TODOTXT_VERBOSE -gt 1 ] && cat <<-'EndVerboseHelp'
Environment variables:
TODOTXT_AUTO_ARCHIVE is same as option -a (0)/-A (1)
TODOTXT_CFG_FILE=CONFIG_FILE is same as option -d CONFIG_FILE
@@ -149,6 +150,7 @@ help()
TODOTXT_DEFAULT_ACTION="" run this when called with no arguments
TODOTXT_SORT_COMMAND="sort ..." customize list output
TODOTXT_FINAL_FILTER="sed ..." customize list after color, P@+ hiding
TODOTXT_SOURCEVAR=\$DONE_FILE use another source for listcon, listproj
EndVerboseHelp
@@ -218,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.
@@ -826,7 +831,7 @@ _format()
{
if (match($0, /^[0-9]+ x /)) {
print highlight("COLOR_DONE") $0 highlight("DEFAULT")
} else if (match($0, /^[0-9]+ \([A-Z]\)[[:space:]]/)) {
} else if (match($0, /^[0-9]+ \([A-Z]\) /)) {
clr = highlight("PRI_" substr($0, RSTART + RLENGTH - 3, 1))
print \
(clr ? clr : highlight("PRI_X")) \
@@ -1128,12 +1133,16 @@ case $action in
;;
"listcon" | "lsc" )
grep -o '[^ ]*@[^ ]\+' "$TODO_FILE" | grep '^@' | sort -u
FILE=$TODO_FILE
[ "$TODOTXT_SOURCEVAR" ] && eval "FILE=$TODOTXT_SOURCEVAR"
grep -ho '[^ ]*@[^ ]\+' "${FILE[@]}" | grep '^@' | sort -u
;;
"listproj" | "lsprj" )
FILE=$TODO_FILE
[ "$TODOTXT_SOURCEVAR" ] && eval "FILE=$TODOTXT_SOURCEVAR"
shift
eval "$(filtercommand 'cat "$TODO_FILE"' '' "$@")" | grep -o '[^ ]*+[^ ]\+' | grep '^+' | sort -u
eval "$(filtercommand 'cat "${FILE[@]}"' '' "$@")" | grep -o '[^ ]*+[^ ]\+' | grep '^+' | sort -u
;;
"listpri" | "lsp" )
@@ -1295,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

View File

@@ -11,32 +11,39 @@ _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
# "move ITEM# DEST [SRC]" has file arguments on positions 2 and 3.
completions=$(TODOTXT_VERBOSE=0 todo.sh command listfile)
completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listfile)
else
case "$prev" in
command)
completions=$COMMANDS;;
addto|listfile|lf)
completions=$(TODOTXT_VERBOSE=0 todo.sh command listfile);;
-*) completions="$allCommands $OPTS";;
completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listfile);;
-*) completions="$COMMANDS $(eval TODOTXT_VERBOSE=0 $_todo_sh command listaddons) $OPTS";;
*) case "$cur" in
+*) completions=$(TODOTXT_VERBOSE=0 todo.sh command listproj);;
@*) completions=$(TODOTXT_VERBOSE=0 todo.sh command listcon);;
+*) completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listproj)
COMPREPLY=( $( compgen -W "$completions" -- $cur ))
[ ${#COMPREPLY[@]} -gt 0 ] && return 0
# Fall back to projects extracted from done tasks.
completions=$(eval 'TODOTXT_VERBOSE=0 TODOTXT_SOURCEVAR=\$DONE_FILE' $_todo_sh command listproj)
;;
@*) completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listcon)
COMPREPLY=( $( compgen -W "$completions" -- $cur ))
[ ${#COMPREPLY[@]} -gt 0 ] && return 0
# Fall back to contexts extracted from done tasks.
completions=$(eval 'TODOTXT_VERBOSE=0 TODOTXT_SOURCEVAR=\$DONE_FILE' $_todo_sh command listcon)
;;
*) if [[ "$cur" =~ ^[0-9]+$ ]]; then
# Remove the (padded) task number; we prepend the
# user-provided $cur instead.
@@ -50,9 +57,9 @@ _todo()
# Finally, limit the output to a single line just as
# a safety check of the ls action output.
local todo=$( \
TODOTXT_VERBOSE=0 todo.sh -@ -+ -p -x command ls "^ *${cur} " | \
sed -e 's/^ *[0-9]\+ //' -e 's/\((.) \)[0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} /\1/' \
-e 's/\([xX] \)\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} \)\{1,2\}/\1/' \
eval TODOTXT_VERBOSE=0 $_todo_sh '-@ -+ -p -x command ls "^ *${cur} "' | \
sed -e 's/^ *[0-9]\{1,\} //' -e 's/^\((.) \)\{0,1\}[0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} /\1/' \
-e 's/^\([xX] \)\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} \)\{1,2\}/\1/' \
-e 's/[[:space:]]*$//' \
-e '1q' \
)
@@ -74,6 +81,30 @@ _todo()
return 0
}
complete -F _todo todo.sh
# If you define an alias (e.g. "t") to todo.sh, you need to explicitly enable
# completion for it, too:
#complete -F _todo t
# It is recommended to put this line next to your alias definition in your
# ~/.bashrc (or wherever else you're defining your alias). If you simply
# uncomment it here, you will need to redo this on every todo.txt update!
# If you have renamed the todo.sh executable, or if it is not accessible through
# PATH, you need to add and use a wrapper completion function, like this:
#_todoElsewhere()
#{
# local _todo_sh='/path/to/todo2.sh'
# _todo "$@"
#}
#complete -F _todoElsewhere /path/to/todo2.sh
# If you use aliases to use different configuration(s), you need to add and use
# a wrapper completion function for each configuration if you want to complete
# fron the actual configured task locations:
#alias todo2='todo.sh -d "$HOME/todo2.cfg"'
#_todo2()
#{
# local _todo_sh='todo.sh -d "$HOME/todo2.cfg"'
# _todo "$@"
#}
#complete -F _todo2 todo2