Compare commits

..

35 Commits

Author SHA1 Message Date
Ingo Karkat
3b0309d9bc Replace backticks in config with $(...)
This applies e24777fa2c to todo.cfg, too, and adds a verification to the existing test.

Note: Because todo.cfg is preprocessed by test-lib, we use the original config from the working copy, not the copy inside the test fixture.
2012-04-15 10:37:41 +02:00
Ingo Karkat
b21d16878f Tests: Hard-code location of todo.sh.
As todo.sh is placed by test-lib at a fixed place, avoid the lookup through which.
2012-04-15 10:35:17 +02:00
Ingo Karkat
3e82f3ca56 Tests: Extract backtick_check(). 2012-04-15 10:33:51 +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
Gina Trapani
74858365f6 Merge pull request #73 from inkarkat/testlib-enhancements
Testlib enhancements

As the vast majority of tests uses the todo.sh output to verify its correctness, output differences should always be shown, not just in verbose mode. 

This change removes the output redirection and check for exit code from the command-under-test, so as another benefit, these "housekeeping commands" are now kept off the test log.

Also, by using a separate function for exit code assertion, this can now report both differences in output and exit code (and not suppress the former any more.)

(Note: To see any of this, you need to temporarily introduce some test failures.)

Finally, I've added color highlighting for the aggregate test report (as in test-lib), because it didn't stood out against the colored test results, so that I often missed the crucial summary.
2012-02-14 20:55:28 -08: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
Ingo Karkat
c31716af47 test-report: Use color highlighting as in test-lib.
The test aggregate results are easy to miss when running the entire test suite via "make test", as the status of the last test case is highlighted, but the aggregate results appear in an unformatted, uncolored block of text.
Copy the say_color() function from test-lib.sh. (Sorry for the duplication, I found no simple way to import or share just this piece of functionality without adding much complexity.)
Successes, errors and broken summaries will now be highlighted in the appropriate colors (unless --no-color is given or output is not to a terminal), but only if the number is more than zero.
2012-01-26 12:15:26 +01:00
Ingo Karkat
ebe9fb868b test-lib: Show full todo.sh output in verbose mode.
Now that differences in the output (and exit code) are already printed by default, we can make the verbose mode actually "verbose" by including all todo.sh output generated during the test run. This may help in reviewing the tests and for troubleshooting.
By moving the redirection to the output file to test_run_(), all testing-related embellishments have been removed from the command under test itself, resulting in much cleaner test messages.
Additionally, also capture stderr in output. todo.sh itself currently prints everything to stdout (but the die() output probably belongs to stderr), so as of now, that has no consequences, but seems to be more consistent and future-proof.
2012-01-26 09:54:30 +01:00
Ingo Karkat
189779c6de test-lib: Separate function for exit code assertion.
Remove the check for the todo.sh exit code (scripted via "=== N") from the command under test into a separate assertion test_expect_code_and_output. This allows for reporting of expected vs. actual exit code (also in the default non-verbose mode), and unexpected output from the same test is now reported, too.
2012-01-26 09:54:25 +01:00
Ingo Karkat
516f806d58 test-lib: Always print output differences, not just in verbose mode.
Differences in the expected and actual todo.sh output are critical to analyzing the error, so they should always be printed, not just when the -verbose argument is given.

This refactoring moves the test_cmp call from the command under test (as seen from test-lib's perspective) into a new assertion test_expect_output, derived from test_expect_success.
2012-01-26 09:35:38 +01:00
44 changed files with 754 additions and 128 deletions

3
.gitignore vendored
View File

@@ -1,3 +1,6 @@
VERSION-FILE VERSION-FILE
tests/test-results tests/test-results
tests/trash\ directory.* 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 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: assignment to variable 'test_description', like this:
#!/bin/sh #!/bin/bash
# #
# Copyright (c) 2005 Junio C Hamano # 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 expected output. (See below for how to generate transcripts
easily.) 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] - test_tick [interval]
The test harness has an internal view of time which is 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.' \ 'git-write-tree should be able to write an empty tree.' \
'tree=$(git-write-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> - test_expect_failure <message> <script>
This is NOT the opposite of test_expect_success, but is used This is NOT the opposite of test_expect_success, but is used

View File

@@ -1,4 +1,57 @@
#!/bin/sh #!/bin/bash
[ "x$TERM" != "xdumb" ] && (
export TERM &&
[ -t 1 ] &&
tput bold >/dev/null 2>&1 &&
tput setaf 1 >/dev/null 2>&1 &&
tput sgr0 >/dev/null 2>&1
) &&
color=t
case "$1" in
--no-color)
color=; shift ;;
esac
if test -n "$color"; then
say_color () {
(
export TERM
case "$1" in
error) tput bold; tput setaf 1;; # bold red
skip) tput bold; tput setaf 2;; # bold green
pass) tput setaf 2;; # green
info) tput setaf 3;; # brown
*) test -n "$quiet" && return;;
esac
shift
printf "* %s" "$*"
tput sgr0
echo
)
}
else
say_color() {
test -z "$1" && test -n "$quiet" && return
shift
echo "* $*"
}
fi
get_color()
{
# Only use the supplied color if there are actually instances of that
# type, so that a clean test run does not distract the user by the
# appearance of the error highlighting.
if [ ${1:?} -eq 0 ]
then
echo 'info'
else
echo "${2:-info}"
fi
}
fixed=0 fixed=0
success=0 success=0
@@ -27,8 +80,8 @@ do
done <"$file" done <"$file"
done done
printf "%-8s%d\n" fixed $fixed say_color 'info' "$(printf "%-8s%d\n" fixed $fixed)"
printf "%-8s%d\n" success $success say_color "$(get_color "$success" 'pass')" "$(printf "%-8s%d\n" success $success)"
printf "%-8s%d\n" failed $failed say_color "$(get_color "$failed" 'error')" "$(printf "%-8s%d\n" failed $failed)"
printf "%-8s%d\n" broken $broken say_color "$(get_color "$broken" 'error')" "$(printf "%-8s%d\n" broken $broken)"
printf "%-8s%d\n" total $total say_color 'info' "$(printf "%-8s%d\n" total $total)"

View File

@@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
test_description='todo.sh configuration file location 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. test_description='todo.sh basic null functionality test.

View File

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

View File

@@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
test_description='no old-style backtick command substitution test_description='no old-style backtick command substitution
@@ -9,8 +9,15 @@ On failure, it will print each offending line number and line.
' '
. ./test-lib.sh . ./test-lib.sh
backtick_check()
{
sed -n -e 's/\(^\|[ \t]\)#.*//' -e '/`/{' -e '=;p' -e '}' "$@"
}
test_todo_session 'no old-style backtick command substitution' <<EOF test_todo_session 'no old-style backtick command substitution' <<EOF
>>> sed -n -e 's/\(^\|[ \t]\)#.*//' -e '/\`/{' -e '=;p' -e '}' "$(which todo.sh)" >>> backtick_check bin/todo.sh
>>> backtick_check ../../todo.cfg
EOF EOF
test_done test_done

View File

@@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
test_description='basic add and list functionality 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 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 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 test_description='test the date on addto feature

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
test_description='list priority functionality test_description='list priority functionality
' '
@@ -61,6 +61,42 @@ TODO: 0 of 5 tasks shown
TODO: 0 of 5 tasks shown TODO: 0 of 5 tasks shown
EOF EOF
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
(X) clean the house from A-Z
(C) notice the sunflowers
(X) listen to music
buy more records from artists A-Z
EOF
test_todo_session 'listpri filtering priority ranges' <<EOF
>>> todo.sh -p listpri a-c
1 (B) smell the uppercase Roses +flowers @outside
3 (C) notice the sunflowers
--
TODO: 2 of 5 tasks shown
>>> todo.sh -p listpri c-Z
3 (C) notice the sunflowers
2 (X) clean the house from A-Z
4 (X) listen to music
--
TODO: 3 of 5 tasks shown
>>> todo.sh -p listpri A-
2 (X) clean the house from A-Z
--
TODO: 1 of 5 tasks shown
>>> todo.sh -p listpri A-C A-Z
--
TODO: 0 of 5 tasks shown
>>> todo.sh -p listpri X A-Z
2 (X) clean the house from A-Z
--
TODO: 1 of 5 tasks shown
EOF
cat > todo.txt <<EOF cat > todo.txt <<EOF
(B) ccc xxx this line should be third. (B) ccc xxx this line should be third.
ccc xxx this line should be third. ccc xxx this line should be third.

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 test_description='list functionality

View File

@@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
# #
test_description='listcon functionality test_description='listcon functionality
@@ -55,4 +55,23 @@ test_todo_session 'listcon e-mail address test' <<EOF
@con02 @con02
EOF 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 test_done

View File

@@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
# #
test_description='listproj functionality test_description='listproj functionality
@@ -55,4 +55,63 @@ test_todo_session 'listproj embedded + test' <<EOF
+prj02 +prj02
EOF 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 test_done

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

@@ -0,0 +1,25 @@
#!/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
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_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 test_description='custom actions functionality

View File

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

View File

@@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
# #
# Copyright (c) 2005 Junio C Hamano # Copyright (c) 2005 Junio C Hamano
# #
@@ -180,7 +180,7 @@ test_failure_ () {
test_failure=$(($test_failure + 1)) test_failure=$(($test_failure + 1))
say_color error "FAIL $test_count: $1" say_color error "FAIL $test_count: $1"
shift shift
echo "$@" | sed -e 's/^/ /' echo "$@"
test "$immediate" = "" || { trap - EXIT; exit 1; } test "$immediate" = "" || { trap - EXIT; exit 1; }
} }
@@ -199,8 +199,9 @@ test_debug () {
} }
test_run_ () { test_run_ () {
eval >&3 2>&4 "$1" eval > output 2>&1 "$1"
eval_ret="$?" eval_ret="$?"
cat >&3 output
return 0 return 0
} }
@@ -260,6 +261,57 @@ test_expect_success () {
echo >&3 "" echo >&3 ""
} }
test_expect_output () {
test "$#" = 2 ||
error "bug in the test script: not 2 parameters to test-expect-output"
if ! test_skip "$@"
then
say >&3 "expecting success and output: $2"
test_run_ "$2"
if [ "$?" = 0 -a "$eval_ret" = 0 ]
then
cmp_output=$(test_cmp expect output)
if [ "$?" = 0 ]
then
test_ok_ "$1"
else
test_failure_ "$@" "
$cmp_output"
fi
else
test_failure_ "$@"
fi
fi
echo >&3 ""
}
test_expect_code_and_output () {
test "$#" = 3 ||
error "bug in the test script: not 3 parameters to test-expect-code-and-output"
if ! test_skip "$@"
then
say >&3 "expecting exit code $1 and output: $3"
test_run_ "$3"
if [ "$?" = 0 -a "$eval_ret" = "$1" ]
then
cmp_output=$(test_cmp expect output)
if [ "$?" = 0 ]
then
test_ok_ "$2"
else
test_failure_ "$2" "$3" "
$cmp_output"
fi
else
cmp_output=$(test_cmp expect output)
test_failure_ "$2" "$3" "
expected exit code $1, actual ${eval_ret}${cmp_output:+
}${cmp_output}"
fi
fi
echo >&3 ""
}
test_expect_code () { test_expect_code () {
test "$#" = 3 || test "$#" = 3 ||
error "bug in the test script: not 3 parameters to test-expect-code" error "bug in the test script: not 3 parameters to test-expect-code"
@@ -271,7 +323,8 @@ test_expect_code () {
then then
test_ok_ "$2" test_ok_ "$2"
else else
test_failure_ "$@" test_failure_ "$2" "$3" "
expected exit code $1, actual ${eval_ret}"
fi fi
fi fi
echo >&3 "" echo >&3 ""
@@ -542,9 +595,9 @@ test_todo_session () {
"") "")
if [ ! -z "$cmd" ]; then if [ ! -z "$cmd" ]; then
if [ $status = 0 ]; then if [ $status = 0 ]; then
test_expect_success "$1 $subnum" "$cmd > output && test_cmp expect output" test_expect_output "$1 $subnum" "$cmd"
else else
test_expect_success "$1 $subnum" "$cmd > output ; test \$? = $status && test_cmp expect output" test_expect_code_and_output "$status" "$1 $subnum" "$cmd"
fi fi
subnum=$(($subnum + 1)) subnum=$(($subnum + 1))
@@ -560,9 +613,9 @@ test_todo_session () {
done done
if [ ! -z "$cmd" ]; then if [ ! -z "$cmd" ]; then
if [ $status = 0 ]; then if [ $status = 0 ]; then
test_expect_success "$1 $subnum" "$cmd > output && test_cmp expect output" test_expect_output "$1 $subnum" "$cmd"
else else
test_expect_success "$1 $subnum" "$cmd > output ; test \$? = $status && test_cmp expect output" test_expect_code_and_output "$status" "$1 $subnum" "$cmd"
fi fi
fi fi
} }
@@ -579,6 +632,66 @@ EOF
exit 0 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" test_init_todo "$test"
# Use -P to resolve symlinks in our working directory so that the pwd # Use -P to resolve symlinks in our working directory so that the pwd
# in subprocesses equals our $PWD (for pathname comparisons). # 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_description='Providing an interactive shell in the proper environment'
. ./test-lib.sh . ./test-lib.sh

View File

@@ -2,7 +2,7 @@
# Your todo.txt directory # Your todo.txt directory
#export TODO_DIR="/Users/gina/Documents/todo" #export TODO_DIR="/Users/gina/Documents/todo"
export TODO_DIR=`dirname "$0"` export TODO_DIR=$(dirname "$0")
# Your todo/done/report.txt locations # Your todo/done/report.txt locations
export TODO_FILE="$TODO_DIR/todo.txt" export TODO_FILE="$TODO_DIR/todo.txt"

44
todo.sh
View File

@@ -57,9 +57,10 @@ 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 [PRIORITY] [TERM...] listpri|lsp [PRIORITIES] [TERM...]
listproj|lsprj [TERM...] listproj|lsprj [TERM...]
move|mv ITEM# DEST [SRC] move|mv ITEM# DEST [SRC]
prepend|prep ITEM# "TEXT TO PREPEND" prepend|prep ITEM# "TEXT TO PREPEND"
@@ -136,7 +137,7 @@ help()
EndOptionsHelp EndOptionsHelp
[ $TODOTXT_VERBOSE -gt 1 ] && cat <<-EndVerboseHelp [ $TODOTXT_VERBOSE -gt 1 ] && cat <<-'EndVerboseHelp'
Environment variables: Environment variables:
TODOTXT_AUTO_ARCHIVE is same as option -a (0)/-A (1) TODOTXT_AUTO_ARCHIVE is same as option -a (0)/-A (1)
TODOTXT_CFG_FILE=CONFIG_FILE is same as option -d CONFIG_FILE 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_DEFAULT_ACTION="" run this when called with no arguments
TODOTXT_SORT_COMMAND="sort ..." customize list output TODOTXT_SORT_COMMAND="sort ..." customize list output
TODOTXT_FINAL_FILTER="sed ..." customize list after color, P@+ hiding TODOTXT_FINAL_FILTER="sed ..." customize list after color, P@+ hiding
TODOTXT_SOURCEVAR=\$DONE_FILE use another source for listcon, listproj
EndVerboseHelp EndVerboseHelp
@@ -218,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.
@@ -231,10 +236,11 @@ help()
Without any arguments, the names of all text files in the todo.txt Without any arguments, the names of all text files in the todo.txt
directory are listed. directory are listed.
listpri [PRIORITY] [TERM...] listpri [PRIORITIES] [TERM...]
lsp [PRIORITY] [TERM...] lsp [PRIORITIES] [TERM...]
Displays all tasks prioritized PRIORITY. Displays all tasks prioritized PRIORITIES.
If no PRIORITY specified, lists all prioritized tasks. PRIORITIES can be a single one (A) or a range (A-C).
If no PRIORITIES specified, lists all prioritized tasks.
If TERM specified, lists only prioritized tasks that contain TERM(s). If TERM specified, lists only prioritized tasks that contain TERM(s).
Hides all tasks that contain TERM(s) preceded by a minus sign Hides all tasks that contain TERM(s) preceded by a minus sign
(i.e. -TERM). (i.e. -TERM).
@@ -825,7 +831,7 @@ _format()
{ {
if (match($0, /^[0-9]+ x /)) { if (match($0, /^[0-9]+ x /)) {
print highlight("COLOR_DONE") $0 highlight("DEFAULT") 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)) clr = highlight("PRI_" substr($0, RSTART + RLENGTH - 3, 1))
print \ print \
(clr ? clr : highlight("PRI_X")) \ (clr ? clr : highlight("PRI_X")) \
@@ -1127,19 +1133,23 @@ case $action in
;; ;;
"listcon" | "lsc" ) "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" ) "listproj" | "lsprj" )
FILE=$TODO_FILE
[ "$TODOTXT_SOURCEVAR" ] && eval "FILE=$TODOTXT_SOURCEVAR"
shift shift
eval "$(filtercommand 'cat "$TODO_FILE"' '' "$@")" | grep -o '[^ ]*+[^ ]\+' | grep '^+' | sort -u eval "$(filtercommand 'cat "${FILE[@]}"' '' "$@")" | grep -o '[^ ]*+[^ ]\+' | grep '^+' | sort -u
;; ;;
"listpri" | "lsp" ) "listpri" | "lsp" )
shift ## was "listpri", new $1 is priority to list or first TERM shift ## was "listpri", new $1 is priority to list or first TERM
pri=$(printf "%s\n" "$1" | tr 'a-z' 'A-Z' | grep '^[A-Z]$') && shift || pri="[A-Z]" pri=$(printf "%s\n" "$1" | tr 'a-z' 'A-Z' | grep -e '^[A-Z]$' -e '^[A-Z]-[A-Z]$') && shift || pri="A-Z"
post_filter_command="grep '^ *[0-9]\+ (${pri}) '" post_filter_command="grep '^ *[0-9]\+ ([${pri}]) '"
_list "$TODO_FILE" "$@" _list "$TODO_FILE" "$@"
;; ;;
@@ -1294,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,32 +11,39 @@ _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. local _todo_sh=${_todo_sh:-todo.sh}
# 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 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
# "move ITEM# DEST [SRC]" has file arguments on positions 2 and 3. # "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 else
case "$prev" in case "$prev" in
command) command)
completions=$COMMANDS;; completions=$COMMANDS;;
addto|listfile|lf) addto|listfile|lf)
completions=$(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=$(TODOTXT_VERBOSE=0 todo.sh command listproj);; +*) completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listproj)
@*) completions=$(TODOTXT_VERBOSE=0 todo.sh command listcon);; 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 *) if [[ "$cur" =~ ^[0-9]+$ ]]; then
# Remove the (padded) task number; we prepend the # Remove the (padded) task number; we prepend the
# user-provided $cur instead. # user-provided $cur instead.
@@ -50,8 +57,8 @@ _todo()
# Finally, limit the output to a single line just as # Finally, limit the output to a single line just as
# a safety check of the ls action output. # a safety check of the ls action output.
local todo=$( \ local todo=$( \
TODOTXT_VERBOSE=0 todo.sh -@ -+ -p -x command ls "^ *${cur} " | \ eval 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/' \ sed -e 's/^ *[0-9]\{1,\} //' -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/' \ -e 's/\([xX] \)\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} \)\{1,2\}/\1/' \
-e 's/[[:space:]]*$//' \ -e 's/[[:space:]]*$//' \
-e '1q' \ -e '1q' \
@@ -74,6 +81,27 @@ _todo()
return 0 return 0
} }
complete -F _todo todo.sh complete -F _todo todo.sh
# If you define an alias (e.g. "t") to todo.sh, you need to explicitly enable # If you define an alias (e.g. "t") to todo.sh, you need to explicitly enable
# completion for it, too: # completion for it, too:
#complete -F _todo t #complete -F _todo t
# 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