Compare commits
63 Commits
archive/co
...
v2.10.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
837ce22937 | ||
|
|
7c92f46c25 | ||
|
|
07b50a07e0 | ||
|
|
745f5d5179 | ||
|
|
236069c519 | ||
|
|
e60c14ab2b | ||
|
|
33eb234048 | ||
|
|
42e7a079f8 | ||
|
|
1f410e4066 | ||
|
|
d8ceb46364 | ||
|
|
0d139d2027 | ||
|
|
07821f9cff | ||
|
|
2faf072cf7 | ||
|
|
ce365df67c | ||
|
|
93d8e16d50 | ||
|
|
111afe6958 | ||
|
|
92f7b724e6 | ||
|
|
629a301d43 | ||
|
|
4a7dd852a6 | ||
|
|
ec9613e19e | ||
|
|
79845c8eb1 | ||
|
|
b853198c3a | ||
|
|
e1d6b91fa3 | ||
|
|
8ff79102a5 | ||
|
|
8d8ef812a2 | ||
|
|
50aea1e4f0 | ||
|
|
da683366f4 | ||
|
|
e48ad81ecc | ||
|
|
7b5c983bb6 | ||
|
|
f67f630466 | ||
|
|
fe27b10765 | ||
|
|
c0c93c8c0c | ||
|
|
137140a542 | ||
|
|
322c6b95d6 | ||
|
|
28e8a4cd8b | ||
|
|
7f1bdbf3d9 | ||
|
|
a5481990fd | ||
|
|
38d75afeff | ||
|
|
6473802644 | ||
|
|
6a3ddad787 | ||
|
|
7acb521190 | ||
|
|
f2b9734047 | ||
|
|
97035d3425 | ||
|
|
99e5e57a75 | ||
|
|
42424d5881 | ||
|
|
7ab90476f7 | ||
|
|
fac5533b96 | ||
|
|
736e69bd6c | ||
|
|
d2c44e9ffe | ||
|
|
f45bbd1a1d | ||
|
|
e0b93e48fb | ||
|
|
24d0fb003a | ||
|
|
3b0309d9bc | ||
|
|
b21d16878f | ||
|
|
3e82f3ca56 | ||
|
|
e5e31b0f75 | ||
|
|
35f9c4276c | ||
|
|
661dac0cfb | ||
|
|
d7056c5e1e | ||
|
|
92322e7064 | ||
|
|
ebe6a403c8 | ||
|
|
a6fed991e5 | ||
|
|
94f770926b |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -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
|
||||||
|
|||||||
6
.travis.yml
Normal file
6
.travis.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Note: "shell" would be more appropriate
|
||||||
|
language: python
|
||||||
|
|
||||||
|
install: make dist && sudo make install
|
||||||
|
|
||||||
|
script: make test
|
||||||
7
CONTRIBUTING.md
Normal file
7
CONTRIBUTING.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# DO NOT ENTER AN ISSUE UNTIL IT'S BEEN VERIFIED
|
||||||
|
|
||||||
|
Please do not enter feature requests or bug reports here until you have joined the mailing list and submitted it there for verification and discussion first.
|
||||||
|
|
||||||
|
http://tech.groups.yahoo.com/group/todotxt/
|
||||||
|
|
||||||
|
Then, include a link to the mailing list discussion once the issue has been verified as something that needs to be fixed/added to the core script (and not an add-on or otherwise). Thanks!
|
||||||
8
Makefile
8
Makefile
@@ -1,6 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Makefile for todo.txt
|
# Makefile for todo.txt
|
||||||
#
|
#
|
||||||
|
INSTALL_DIR=/usr/local/bin
|
||||||
|
|
||||||
# Dynamically detect/generate version file as necessary
|
# Dynamically detect/generate version file as necessary
|
||||||
# This file will define a variable called VERSION.
|
# This file will define a variable called VERSION.
|
||||||
@@ -29,7 +30,12 @@ dist: $(DISTFILES) todo.sh
|
|||||||
clean:
|
clean:
|
||||||
rm -f $(DISTNAME).tar.gz $(DISTNAME).zip
|
rm -f $(DISTNAME).tar.gz $(DISTNAME).zip
|
||||||
|
|
||||||
|
install:
|
||||||
|
install --mode=755 todo.sh $(INSTALL_DIR)
|
||||||
|
install --mode=644 todo_completion /etc/bash_completion.d/todo
|
||||||
|
mkdir -p /etc/todo
|
||||||
|
[ -e /etc/todo/config ] || \
|
||||||
|
sed "s/^\(export[ \t]*TODO_DIR=\).*/\1~\/.todo/" todo.cfg > /etc/todo/config
|
||||||
#
|
#
|
||||||
# Testing
|
# Testing
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
h1. TODO.TXT Command Line Interface
|
h1. TODO.TXT Command Line Interface !https://secure.travis-ci.org/ginatrapani/todo.txt-cli.png?branch=master(Build Status)!:http://travis-ci.org/ginatrapani/todo.txt-cli
|
||||||
|
|
||||||
A simple and extensible shell script for managing your todo.txt file.
|
A simple and extensible shell script for managing your todo.txt file.
|
||||||
|
|
||||||
@@ -23,5 +23,5 @@ h2. Quick Links
|
|||||||
* Licensed under the "GPL":http://www.gnu.org/copyleft/gpl.html
|
* Licensed under the "GPL":http://www.gnu.org/copyleft/gpl.html
|
||||||
* "Add-on Directory":https://github.com/ginatrapani/todo.txt-cli/wiki/Todo.sh-Add-on-Directory
|
* "Add-on Directory":https://github.com/ginatrapani/todo.txt-cli/wiki/Todo.sh-Add-on-Directory
|
||||||
https://github.com/ginatrapani/todo.txt-cli/wiki/Creating-and-Installing-Add-ons
|
https://github.com/ginatrapani/todo.txt-cli/wiki/Creating-and-Installing-Add-ons
|
||||||
* "Changelog":http://wiki.github.com/ginatrapani/todo.txt-cli/todosh-changelog
|
* "Changelog":https://github.com/ginatrapani/todo.txt-cli/wiki/Todo.sh-Changelog
|
||||||
* "Known Bugs":http://github.com/ginatrapani/todo.txt-cli/issues
|
* "Known Bugs":http://github.com/ginatrapani/todo.txt-cli/issues
|
||||||
|
|||||||
36
tests/actions-test-lib.sh
Normal file
36
tests/actions-test-lib.sh
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
make_action()
|
||||||
|
{
|
||||||
|
unset TODO_ACTIONS_DIR
|
||||||
|
[ -d .todo.actions.d ] || mkdir .todo.actions.d
|
||||||
|
cat > ".todo.actions.d/$1" <<EOF
|
||||||
|
#!/bin/bash
|
||||||
|
[ "\$1" = "usage" ] && {
|
||||||
|
echo " $1 ITEM#[, ITEM#, ...] [TERM...]"
|
||||||
|
echo " This custom action does $1."
|
||||||
|
echo ""
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
echo "custom action $1"
|
||||||
|
EOF
|
||||||
|
chmod +x ".todo.actions.d/$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
make_action_in_folder()
|
||||||
|
{
|
||||||
|
unset TODO_ACTIONS_DIR
|
||||||
|
[ -d .todo.actions.d ] || mkdir .todo.actions.d
|
||||||
|
mkdir .todo.actions.d/$1
|
||||||
|
cat > ".todo.actions.d/$1/$1" <<EOF
|
||||||
|
#!/bin/bash
|
||||||
|
[ "\$1" = "usage" ] && {
|
||||||
|
echo " $1 ITEM#[, ITEM#, ...] [TERM...]"
|
||||||
|
echo " This custom action does $1."
|
||||||
|
echo ""
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
echo "custom action $1 in folder $1"
|
||||||
|
EOF
|
||||||
|
chmod +x ".todo.actions.d/$1/$1"
|
||||||
|
}
|
||||||
@@ -8,6 +8,10 @@ to find it somewhere else.
|
|||||||
'
|
'
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
|
||||||
|
# Override default global config file
|
||||||
|
export TODOTXT_GLOBAL_CFG_FILE=global.cfg
|
||||||
|
|
||||||
# Remove the pre-created todo.cfg to test behavior in its absence
|
# Remove the pre-created todo.cfg to test behavior in its absence
|
||||||
rm -f todo.cfg
|
rm -f todo.cfg
|
||||||
echo "Fatal Error: Cannot read configuration file $HOME/.todo/config" > expect
|
echo "Fatal Error: Cannot read configuration file $HOME/.todo/config" > expect
|
||||||
@@ -55,6 +59,14 @@ test_expect_success 'config file (default location 3)' '
|
|||||||
rm -f .todo.cfg
|
rm -f .todo.cfg
|
||||||
'
|
'
|
||||||
|
|
||||||
|
rm -f used_config
|
||||||
|
test_expect_success 'config file (global config file)' '
|
||||||
|
cp test.cfg "$TODOTXT_GLOBAL_CFG_FILE"
|
||||||
|
todo.sh > output;
|
||||||
|
test_cmp expect output && test -f used_config &&
|
||||||
|
rm -f "$TODOTXT_GLOBAL_CFG_FILE"
|
||||||
|
'
|
||||||
|
|
||||||
rm -f used_config
|
rm -f used_config
|
||||||
test_expect_success 'config file (command line)' '
|
test_expect_success 'config file (command line)' '
|
||||||
todo.sh -d test.cfg > output;
|
todo.sh -d test.cfg > output;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -164,4 +164,12 @@ TODO: Replaced task with:
|
|||||||
1 (A) 2010-07-04 this also has a new date
|
1 (A) 2010-07-04 this also has a new date
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
echo '2009-02-13 this is just a new one' > todo.txt
|
||||||
|
test_todo_session 'replace with prepended priority and date replaces existing date' <<EOF
|
||||||
|
>>> todo.sh replace 1 '(B) 2010-07-04 this also has a new date'
|
||||||
|
1 2009-02-13 this is just a new one
|
||||||
|
TODO: Replaced task with:
|
||||||
|
1 (B) 2010-07-04 this also has a new date
|
||||||
|
EOF
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|||||||
@@ -55,6 +55,16 @@ test_todo_session 'listcon e-mail address test' <<EOF
|
|||||||
@con02
|
@con02
|
||||||
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 'listcon with project' <<EOF
|
||||||
|
>>> todo.sh listcon +landscape
|
||||||
|
@garden
|
||||||
|
EOF
|
||||||
|
|
||||||
cat > todo.txt <<EOF
|
cat > todo.txt <<EOF
|
||||||
@con01 -- Some context 1 task
|
@con01 -- Some context 1 task
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
@@ -114,4 +114,9 @@ test_todo_session 'listproj from combined open + done tasks' <<'EOF'
|
|||||||
+prj01
|
+prj01
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'listproj with GREP_OPTIONS disruption' <<'EOF'
|
||||||
|
>>> GREP_OPTIONS=-n todo.sh listproj
|
||||||
|
+prj01
|
||||||
|
EOF
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|||||||
91
tests/t1360-ls-project-context-highlighting.sh
Executable file
91
tests/t1360-ls-project-context-highlighting.sh
Executable file
@@ -0,0 +1,91 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='highlighting projects and contexts
|
||||||
|
|
||||||
|
This test checks the highlighting (with colors) of projects and contexts.
|
||||||
|
'
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
# Prioritized tasks with projects and contexts
|
||||||
|
cat > todo.txt <<EOF
|
||||||
|
(A) prioritized @con01 context
|
||||||
|
(B) prioritized +prj02 project
|
||||||
|
(C) prioritized context at EOL @con03
|
||||||
|
(D) prioritized project at EOL +prj04
|
||||||
|
+prj05 non-prioritized project at BOL
|
||||||
|
@con06 non-prioritized context at BOL
|
||||||
|
multiple @con_ @texts and +pro_ +jects
|
||||||
|
non-contexts: seti@home @ @* @(foo)
|
||||||
|
non-projects: lost+found + +! +(bar)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# config file specifying COLOR_PROJECT and COLOR_CONTEXT
|
||||||
|
#
|
||||||
|
TEST_TODO_LABEL_COLORS=todo-colors.cfg
|
||||||
|
cat todo.cfg > "$TEST_TODO_LABEL_COLORS"
|
||||||
|
|
||||||
|
echo "export COLOR_CONTEXT='\\\\033[1m'" >>"$TEST_TODO_LABEL_COLORS"
|
||||||
|
echo "export COLOR_PROJECT='\\\\033[2m'" >>"$TEST_TODO_LABEL_COLORS"
|
||||||
|
|
||||||
|
test_todo_session 'highlighting for contexts and projects' <<'EOF'
|
||||||
|
>>> todo.sh -d "$TEST_TODO_LABEL_COLORS" ls
|
||||||
|
[1;33m1 (A) prioritized [1m@con01[0m[1;33m context[0m
|
||||||
|
[0;32m2 (B) prioritized [2m+prj02[0m[0;32m project[0m
|
||||||
|
[1;34m3 (C) prioritized context at EOL [1m@con03[0m[1;34m[0m
|
||||||
|
[1;37m4 (D) prioritized project at EOL [2m+prj04[0m[1;37m[0m
|
||||||
|
5 [2m+prj05[0m non-prioritized project at BOL
|
||||||
|
6 [1m@con06[0m non-prioritized context at BOL
|
||||||
|
7 multiple [1m@con_[0m [1m@texts[0m and [2m+pro_[0m [2m+jects[0m
|
||||||
|
8 non-contexts: seti@home @ @* @(foo)
|
||||||
|
9 non-projects: lost+found + +! +(bar)
|
||||||
|
--
|
||||||
|
TODO: 9 of 9 tasks shown
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'suppressing highlighting for contexts and projects' <<'EOF'
|
||||||
|
>>> todo.sh -p -d "$TEST_TODO_LABEL_COLORS" ls
|
||||||
|
1 (A) prioritized @con01 context
|
||||||
|
2 (B) prioritized +prj02 project
|
||||||
|
3 (C) prioritized context at EOL @con03
|
||||||
|
4 (D) prioritized project at EOL +prj04
|
||||||
|
5 +prj05 non-prioritized project at BOL
|
||||||
|
6 @con06 non-prioritized context at BOL
|
||||||
|
7 multiple @con_ @texts and +pro_ +jects
|
||||||
|
8 non-contexts: seti@home @ @* @(foo)
|
||||||
|
9 non-projects: lost+found + +! +(bar)
|
||||||
|
--
|
||||||
|
TODO: 9 of 9 tasks shown
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'suppressing display of contexts' <<'EOF'
|
||||||
|
>>> todo.sh -@ -d "$TEST_TODO_LABEL_COLORS" ls
|
||||||
|
[1;33m1 (A) prioritized context[0m
|
||||||
|
[0;32m2 (B) prioritized [2m+prj02[0m[0;32m project[0m
|
||||||
|
[1;34m3 (C) prioritized context at EOL[0m
|
||||||
|
[1;37m4 (D) prioritized project at EOL [2m+prj04[0m[1;37m[0m
|
||||||
|
5 [2m+prj05[0m non-prioritized project at BOL
|
||||||
|
6 non-prioritized context at BOL
|
||||||
|
7 multiple and [2m+pro_[0m [2m+jects[0m
|
||||||
|
8 non-contexts: seti@home @
|
||||||
|
9 non-projects: lost+found + +! +(bar)
|
||||||
|
--
|
||||||
|
TODO: 9 of 9 tasks shown
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'suppressing display of projects' <<'EOF'
|
||||||
|
>>> todo.sh -+ -d "$TEST_TODO_LABEL_COLORS" ls
|
||||||
|
[1;33m1 (A) prioritized [1m@con01[0m[1;33m context[0m
|
||||||
|
[0;32m2 (B) prioritized project[0m
|
||||||
|
[1;34m3 (C) prioritized context at EOL [1m@con03[0m[1;34m[0m
|
||||||
|
[1;37m4 (D) prioritized project at EOL[0m
|
||||||
|
5 non-prioritized project at BOL
|
||||||
|
6 [1m@con06[0m non-prioritized context at BOL
|
||||||
|
7 multiple [1m@con_[0m [1m@texts[0m and
|
||||||
|
8 non-contexts: seti@home @ @* @(foo)
|
||||||
|
9 non-projects: lost+found +
|
||||||
|
--
|
||||||
|
TODO: 9 of 9 tasks shown
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_done
|
||||||
44
tests/t2100-help.sh
Executable file
44
tests/t2100-help.sh
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='help functionality
|
||||||
|
|
||||||
|
This test covers the help output.
|
||||||
|
'
|
||||||
|
. ./actions-test-lib.sh
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
# Note: To avoid having to adapt the test whenever the help documentation
|
||||||
|
# slightly changes, only check for the section headers.
|
||||||
|
test_todo_session 'help output' <<EOF
|
||||||
|
>>> todo.sh help | sed '/^ [A-Z]/!d'
|
||||||
|
Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]
|
||||||
|
Options:
|
||||||
|
Built-in Actions:
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'verbose help output' <<EOF
|
||||||
|
>>> todo.sh -v help | sed '/^ [A-Z]/!d'
|
||||||
|
Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]
|
||||||
|
Options:
|
||||||
|
Built-in Actions:
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'very verbose help output' <<EOF
|
||||||
|
>>> todo.sh -vv help | sed '/^ [A-Z]/!d'
|
||||||
|
Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]
|
||||||
|
Options:
|
||||||
|
Environment variables:
|
||||||
|
Built-in Actions:
|
||||||
|
EOF
|
||||||
|
|
||||||
|
make_action "foo"
|
||||||
|
test_todo_session 'help output with custom action' <<EOF
|
||||||
|
>>> todo.sh -v help | sed '/^ [A-Z]/!d'
|
||||||
|
Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]
|
||||||
|
Options:
|
||||||
|
Built-in Actions:
|
||||||
|
Add-on Actions:
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_done
|
||||||
66
tests/t2110-help-action.sh
Executable file
66
tests/t2110-help-action.sh
Executable file
@@ -0,0 +1,66 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
test_description='built-in actions help functionality
|
||||||
|
|
||||||
|
This test checks listing the usage help of a built-in action.
|
||||||
|
'
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
test_todo_session 'nonexisting action help' <<'EOF'
|
||||||
|
>>> todo.sh help doesnotexist
|
||||||
|
TODO: No action "doesnotexist" exists.
|
||||||
|
=== 1
|
||||||
|
|
||||||
|
>>> todo.sh help hel
|
||||||
|
TODO: No action "hel" exists.
|
||||||
|
=== 1
|
||||||
|
|
||||||
|
>>> todo.sh help h
|
||||||
|
TODO: No action "h" exists.
|
||||||
|
=== 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'single action help' <<'EOF'
|
||||||
|
>>> todo.sh help shorthelp
|
||||||
|
shorthelp
|
||||||
|
List the one-line usage of all built-in and add-on actions.
|
||||||
|
\
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'multiple actions help' <<'EOF'
|
||||||
|
>>> todo.sh help shorthelp append
|
||||||
|
shorthelp
|
||||||
|
List the one-line usage of all built-in and add-on actions.
|
||||||
|
\
|
||||||
|
append ITEM# "TEXT TO APPEND"
|
||||||
|
app ITEM# "TEXT TO APPEND"
|
||||||
|
Adds TEXT TO APPEND to the end of the task on line ITEM#.
|
||||||
|
Quotes optional.
|
||||||
|
\
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'short and long form of action help' <<'EOF'
|
||||||
|
>>> todo.sh help append
|
||||||
|
append ITEM# "TEXT TO APPEND"
|
||||||
|
app ITEM# "TEXT TO APPEND"
|
||||||
|
Adds TEXT TO APPEND to the end of the task on line ITEM#.
|
||||||
|
Quotes optional.
|
||||||
|
\
|
||||||
|
|
||||||
|
>>> todo.sh help app
|
||||||
|
app ITEM# "TEXT TO APPEND"
|
||||||
|
Adds TEXT TO APPEND to the end of the task on line ITEM#.
|
||||||
|
Quotes optional.
|
||||||
|
\
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'mixed existing and nonexisting action help' <<'EOF'
|
||||||
|
>>> todo.sh help shorthelp doesnotexist list
|
||||||
|
shorthelp
|
||||||
|
List the one-line usage of all built-in and add-on actions.
|
||||||
|
\
|
||||||
|
TODO: No action "doesnotexist" exists.
|
||||||
|
=== 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_done
|
||||||
82
tests/t2120-shorthelp.sh
Executable file
82
tests/t2120-shorthelp.sh
Executable file
@@ -0,0 +1,82 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='shorthelp functionality
|
||||||
|
|
||||||
|
This test covers the output of the -h option and the shorthelp action.
|
||||||
|
'
|
||||||
|
. ./actions-test-lib.sh
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
# Note: To avoid having to adapt the test whenever the actions change, only
|
||||||
|
# check for the section headers.
|
||||||
|
test_todo_session '-h output' <<EOF
|
||||||
|
>>> todo.sh -h | sed '/^ [A-Z]/!d'
|
||||||
|
Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]
|
||||||
|
Actions:
|
||||||
|
Actions can be added and overridden using scripts in the actions
|
||||||
|
See "help" for more details.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'shorthelp output' <<EOF
|
||||||
|
>>> todo.sh shorthelp | sed '/^ [A-Z]/!d'
|
||||||
|
Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]
|
||||||
|
Actions:
|
||||||
|
Actions can be added and overridden using scripts in the actions
|
||||||
|
See "help" for more details.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
make_action "foo"
|
||||||
|
test_todo_session 'shorthelp output with custom action' <<EOF
|
||||||
|
>>> todo.sh -v shorthelp | sed '/^ [A-Z]/!d'
|
||||||
|
Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]
|
||||||
|
Actions:
|
||||||
|
Actions can be added and overridden using scripts in the actions
|
||||||
|
Add-on Actions:
|
||||||
|
See "help" for more details.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
# Verify that custom configuration is actually processed (when the -d option
|
||||||
|
# precedes the -h option) by specifying a different actions directory and moving
|
||||||
|
# our custom action there. The help output should mention the "Add-On Actions".
|
||||||
|
set -o pipefail # So that the sed filter doesn't swallow todo.sh's exit code.
|
||||||
|
mv todo.cfg custom.cfg
|
||||||
|
mv .todo.actions.d custom.actions
|
||||||
|
echo 'export TODO_ACTIONS_DIR=$HOME/custom.actions' >> custom.cfg
|
||||||
|
|
||||||
|
# Avoid the use of global config file, if it exists
|
||||||
|
export TODOTXT_GLOBAL_CFG_FILE=global.cfg
|
||||||
|
|
||||||
|
test_todo_session '-h and fatal error without config' <<EOF
|
||||||
|
>>> todo.sh -h | sed '/^ \\{0,2\\}[A-Z]/!d'
|
||||||
|
Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]
|
||||||
|
Actions:
|
||||||
|
Actions can be added and overridden using scripts in the actions
|
||||||
|
See "help" for more details.
|
||||||
|
Fatal Error: Cannot read configuration file $HOME/.todo/config
|
||||||
|
=== 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Config option comes too late; "Add-on Actions" is *not* mentioned here.
|
||||||
|
test_todo_session '-h and fatal error with trailing custom config' <<EOF
|
||||||
|
>>> todo.sh -h -d custom.cfg | sed '/^ \\{0,2\\}[A-Z]/!d'
|
||||||
|
Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]
|
||||||
|
Actions:
|
||||||
|
Actions can be added and overridden using scripts in the actions
|
||||||
|
See "help" for more details.
|
||||||
|
Fatal Error: Cannot read configuration file $HOME/.todo/config
|
||||||
|
=== 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Config option processed; "Add-on Actions" is mentioned here.
|
||||||
|
test_todo_session '-h output with preceding custom config' <<EOF
|
||||||
|
>>> todo.sh -d custom.cfg -h | sed '/^ \\{0,2\\}[A-Z]/!d'
|
||||||
|
Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]
|
||||||
|
Actions:
|
||||||
|
Actions can be added and overridden using scripts in the actions
|
||||||
|
Add-on Actions:
|
||||||
|
See "help" for more details.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_done
|
||||||
49
tests/t2200-no-done-report-files.sh
Executable file
49
tests/t2200-no-done-report-files.sh
Executable file
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='todo.sh configuration with a sole todo.txt data file.
|
||||||
|
|
||||||
|
This test covers turning off done.txt and report.txt, and
|
||||||
|
checks that no such empty files are created.
|
||||||
|
'
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
cat > test.cfg << EOF
|
||||||
|
export TODO_DIR=.
|
||||||
|
export TODO_FILE="\$TODO_DIR/todo.txt"
|
||||||
|
export DONE_FILE=/dev/null
|
||||||
|
export REPORT_FILE=/dev/null
|
||||||
|
export TMP_FILE="\$TODO_DIR/todo.tmp"
|
||||||
|
touch used_config
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'invoke todo.sh' <<EOF
|
||||||
|
>>> todo.sh -d test.cfg add notice the daisies
|
||||||
|
1 notice the daisies
|
||||||
|
TODO: 1 added.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'the todo file has been created' '[ -e todo.txt ]'
|
||||||
|
test_expect_success 'no done file has been created' '[ ! -e done.txt ]'
|
||||||
|
test_expect_success 'no report file has been created' '[ ! -e report.txt ]'
|
||||||
|
|
||||||
|
test_todo_session 'perform archive' <<EOF
|
||||||
|
>>> todo.sh -A -d test.cfg do 1
|
||||||
|
1 x 2009-02-13 notice the daisies
|
||||||
|
TODO: 1 marked as done.
|
||||||
|
x 2009-02-13 notice the daisies
|
||||||
|
TODO: ./todo.txt archived.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'no done file has been created by the archiving' '[ ! -e done.txt ]'
|
||||||
|
|
||||||
|
test_todo_session 'perform report' <<EOF
|
||||||
|
>>> todo.sh -d test.cfg report
|
||||||
|
TODO: ./todo.txt archived.
|
||||||
|
2009-02-13T04:40:00 0 0
|
||||||
|
TODO: Report file updated.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'no report file has been created by the reporting' '[ ! -e report.txt ]'
|
||||||
|
|
||||||
|
test_done
|
||||||
@@ -14,6 +14,7 @@ notice the sunflowers +sunflowers @outside @garden +shared +landscape
|
|||||||
(C) 2012-02-28 @outside mow the lawn
|
(C) 2012-02-28 @outside mow the lawn
|
||||||
x 2012-02-21 +herbs @oriental buy spices
|
x 2012-02-21 +herbs @oriental buy spices
|
||||||
x 2012-02-28 2012-02-21 +slack @home watch tv
|
x 2012-02-28 2012-02-21 +slack @home watch tv
|
||||||
|
2012-02-28 +herbs buy cinnamon @grocer
|
||||||
EOF
|
EOF
|
||||||
test_todo_completion 'simple task' 'todo.sh list 1' '"1 # simple task"'
|
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 'remove projects and contents from task' 'todo.sh list 2' '"2 # notice the sunflowers"'
|
||||||
@@ -21,5 +22,6 @@ 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 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 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 '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
|
test_done
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ readonly ACTIONS='add a addto addm append app archive command del rm depri dp do
|
|||||||
readonly OPTIONS='-@ -@@ -+ -++ -d -f -h -p -P -PP -a -n -t -v -vv -V -x'
|
readonly OPTIONS='-@ -@@ -+ -++ -d -f -h -p -P -PP -a -n -t -v -vv -V -x'
|
||||||
|
|
||||||
readonly ADDONS='bar baz foobar'
|
readonly ADDONS='bar baz foobar'
|
||||||
|
|
||||||
|
readonly CONTAINED='xeno zoolander'
|
||||||
makeCustomActions()
|
makeCustomActions()
|
||||||
{
|
{
|
||||||
set -e
|
set -e
|
||||||
@@ -31,12 +33,28 @@ makeCustomActions()
|
|||||||
chmod -x "$datafile"
|
chmod -x "$datafile"
|
||||||
[ -x "$datafile" ] && rm "$datafile" # Some file systems may always make files executable; then, skip this check.
|
[ -x "$datafile" ] && rm "$datafile" # Some file systems may always make files executable; then, skip this check.
|
||||||
|
|
||||||
|
# Add an executable file in a folder with the same name as the file,
|
||||||
|
# in order to ensure completion
|
||||||
|
for contained in $CONTAINED
|
||||||
|
do
|
||||||
|
mkdir "${1}/$contained"
|
||||||
|
> "${1}/$contained/$contained"
|
||||||
|
chmod u+x "${1}/$contained/$contained"
|
||||||
|
done
|
||||||
|
|
||||||
set +e
|
set +e
|
||||||
}
|
}
|
||||||
removeCustomActions()
|
removeCustomActions()
|
||||||
{
|
{
|
||||||
set -e
|
set -e
|
||||||
rmdir "${1}/subdir"
|
rmdir "${1}/subdir"
|
||||||
|
|
||||||
|
for contained in $CONTAINED
|
||||||
|
do
|
||||||
|
rm "${1}/$contained/$contained"
|
||||||
|
rmdir "${1}/$contained"
|
||||||
|
done
|
||||||
|
|
||||||
rm "${1:?}/"*
|
rm "${1:?}/"*
|
||||||
rmdir "$1"
|
rmdir "$1"
|
||||||
set +e
|
set +e
|
||||||
@@ -46,8 +64,8 @@ removeCustomActions()
|
|||||||
# Test resolution of the default TODO_ACTIONS_DIR.
|
# Test resolution of the default TODO_ACTIONS_DIR.
|
||||||
#
|
#
|
||||||
makeCustomActions "$HOME/.todo.actions.d"
|
makeCustomActions "$HOME/.todo.actions.d"
|
||||||
test_todo_completion 'all arguments' 'todo.sh ' "$ACTIONS $ADDONS $OPTIONS"
|
test_todo_completion 'all arguments' 'todo.sh ' "$ACTIONS $ADDONS $CONTAINED $OPTIONS"
|
||||||
test_todo_completion 'all arguments after option' 'todo.sh -a ' "$ACTIONS $ADDONS $OPTIONS"
|
test_todo_completion 'all arguments after option' 'todo.sh -a ' "$ACTIONS $ADDONS $CONTAINED $OPTIONS"
|
||||||
test_todo_completion 'all arguments beginning with b' 'todo.sh b' 'bar baz'
|
test_todo_completion 'all arguments beginning with b' 'todo.sh b' 'bar baz'
|
||||||
test_todo_completion 'all arguments beginning with f after options' 'todo.sh -a -v f' 'foobar'
|
test_todo_completion 'all arguments beginning with f after options' 'todo.sh -a -v f' 'foobar'
|
||||||
test_todo_completion 'nothing after addon action' 'todo.sh foobar ' ''
|
test_todo_completion 'nothing after addon action' 'todo.sh foobar ' ''
|
||||||
@@ -58,7 +76,7 @@ removeCustomActions "$HOME/.todo.actions.d"
|
|||||||
#
|
#
|
||||||
mkdir "$HOME/.todo"
|
mkdir "$HOME/.todo"
|
||||||
makeCustomActions "$HOME/.todo/actions"
|
makeCustomActions "$HOME/.todo/actions"
|
||||||
test_todo_completion 'all arguments with actions from .todo/actions/' 'todo.sh ' "$ACTIONS $ADDONS $OPTIONS"
|
test_todo_completion 'all arguments with actions from .todo/actions/' 'todo.sh ' "$ACTIONS $ADDONS $CONTAINED $OPTIONS"
|
||||||
removeCustomActions "$HOME/.todo/actions"
|
removeCustomActions "$HOME/.todo/actions"
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -68,7 +86,7 @@ makeCustomActions "$HOME/addons"
|
|||||||
cat >> todo.cfg <<'EOF'
|
cat >> todo.cfg <<'EOF'
|
||||||
export TODO_ACTIONS_DIR="$HOME/addons"
|
export TODO_ACTIONS_DIR="$HOME/addons"
|
||||||
EOF
|
EOF
|
||||||
test_todo_completion 'all arguments with actions from addons/' 'todo.sh ' "$ACTIONS $ADDONS $OPTIONS"
|
test_todo_completion 'all arguments with actions from addons/' 'todo.sh ' "$ACTIONS $ADDONS $CONTAINED $OPTIONS"
|
||||||
removeCustomActions "$HOME/addons"
|
removeCustomActions "$HOME/addons"
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|||||||
20
tests/t6100-completion-help.sh
Executable file
20
tests/t6100-completion-help.sh
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='Bash help completion functionality
|
||||||
|
|
||||||
|
This test checks todo_completion of actions for usage help.
|
||||||
|
'
|
||||||
|
. ./actions-test-lib.sh
|
||||||
|
. ./test-lib.sh
|
||||||
|
make_action "zany"
|
||||||
|
make_action "aardvark"
|
||||||
|
|
||||||
|
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 ADDONS='aardvark zany'
|
||||||
|
|
||||||
|
test_todo_completion 'all actions after help' 'todo.sh help ' "$ACTIONS $ADDONS"
|
||||||
|
test_todo_completion 'all actions after command help' 'todo.sh command help ' "$ACTIONS $ADDONS"
|
||||||
|
test_todo_completion 'actions beginning with a' 'todo.sh help a' 'add a addto addm append app archive aardvark'
|
||||||
|
|
||||||
|
test_done
|
||||||
@@ -4,19 +4,9 @@ test_description='custom actions functionality
|
|||||||
|
|
||||||
This test covers the contract between todo.sh and custom actions.
|
This test covers the contract between todo.sh and custom actions.
|
||||||
'
|
'
|
||||||
|
. ./actions-test-lib.sh
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
unset TODO_ACTIONS_DIR
|
|
||||||
mkdir .todo.actions.d
|
|
||||||
make_action()
|
|
||||||
{
|
|
||||||
cat > ".todo.actions.d/$1" <<- EOF
|
|
||||||
#!/bin/bash
|
|
||||||
echo "custom action $1"
|
|
||||||
EOF
|
|
||||||
chmod +x ".todo.actions.d/$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
make_action "foo"
|
make_action "foo"
|
||||||
test_todo_session 'executable action' <<EOF
|
test_todo_session 'executable action' <<EOF
|
||||||
>>> todo.sh foo
|
>>> todo.sh foo
|
||||||
|
|||||||
84
tests/t8010-listaddons.sh
Executable file
84
tests/t8010-listaddons.sh
Executable file
@@ -0,0 +1,84 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
test_description='listaddons functionality
|
||||||
|
|
||||||
|
This test checks listing of custom actions.
|
||||||
|
'
|
||||||
|
. ./actions-test-lib.sh
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
test_todo_session 'no custom actions' <<EOF
|
||||||
|
>>> todo.sh listaddons
|
||||||
|
EOF
|
||||||
|
|
||||||
|
make_action "foo"
|
||||||
|
test_todo_session 'one custom action' <<EOF
|
||||||
|
>>> todo.sh listaddons
|
||||||
|
foo
|
||||||
|
EOF
|
||||||
|
|
||||||
|
make_action "bar"
|
||||||
|
make_action "ls"
|
||||||
|
make_action "quux"
|
||||||
|
test_todo_session 'multiple custom actions' <<EOF
|
||||||
|
>>> todo.sh listaddons
|
||||||
|
bar
|
||||||
|
foo
|
||||||
|
ls
|
||||||
|
quux
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod -x .todo.actions.d/foo
|
||||||
|
# On Cygwin, clearing the executable flag may have no effect, as the Windows ACL
|
||||||
|
# may still grant execution rights. In this case, we skip the test.
|
||||||
|
if [ -x .todo.actions.d/foo ]; then
|
||||||
|
SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }t8010.4"
|
||||||
|
fi
|
||||||
|
test_todo_session 'nonexecutable action' <<EOF
|
||||||
|
>>> todo.sh listaddons
|
||||||
|
bar
|
||||||
|
ls
|
||||||
|
quux
|
||||||
|
EOF
|
||||||
|
|
||||||
|
make_action_in_folder "chuck"
|
||||||
|
# Add a bit of cruft in the action folders in order to ensure that we only
|
||||||
|
# care about the executables with the same name as the folder in which they
|
||||||
|
# reside.
|
||||||
|
touch .todo.actions.d/chuck/mc_hammer # can't touch this
|
||||||
|
chmod u+x .todo.actions.d/chuck/mc_hammer # better run, better run run
|
||||||
|
touch .todo.actions.d/chuck/README
|
||||||
|
|
||||||
|
make_action_in_folder "norris"
|
||||||
|
|
||||||
|
test_todo_session 'custom actions in subfolders' <<EOF
|
||||||
|
>>> test -f .todo.actions.d/chuck/README
|
||||||
|
=== 0
|
||||||
|
|
||||||
|
>>> test -x .todo.actions.d/chuck/mc_hammer
|
||||||
|
=== 0
|
||||||
|
|
||||||
|
>>> todo.sh listaddons
|
||||||
|
bar
|
||||||
|
chuck
|
||||||
|
ls
|
||||||
|
norris
|
||||||
|
quux
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# nthorne: shamelessly stolen from above..
|
||||||
|
chmod -x .todo.actions.d/norris/norris
|
||||||
|
# On Cygwin, clearing the executable flag may have no effect, as the Windows ACL
|
||||||
|
# may still grant execution rights. In this case, we skip the test.
|
||||||
|
if [ -x .todo.actions.d/norris/norris ]; then
|
||||||
|
SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }t8010.8"
|
||||||
|
fi
|
||||||
|
test_todo_session 'nonexecutable action in subfolder' <<EOF
|
||||||
|
>>> todo.sh listaddons
|
||||||
|
bar
|
||||||
|
chuck
|
||||||
|
ls
|
||||||
|
quux
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_done
|
||||||
76
tests/t8020-actions-help.sh
Executable file
76
tests/t8020-actions-help.sh
Executable file
@@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
test_description='custom actions help functionality
|
||||||
|
|
||||||
|
This test checks listing the usage help of a custom action.
|
||||||
|
'
|
||||||
|
. ./actions-test-lib.sh
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
test_todo_session 'custom action help with no custom action directory' <<'EOF'
|
||||||
|
>>> todo.sh help foo
|
||||||
|
TODO: No action "foo" exists.
|
||||||
|
=== 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
make_action "foo"
|
||||||
|
make_action "bar"
|
||||||
|
make_action "ls"
|
||||||
|
make_action "quux"
|
||||||
|
|
||||||
|
test_todo_session 'custom action help' <<'EOF'
|
||||||
|
>>> todo.sh help foo
|
||||||
|
foo ITEM#[, ITEM#, ...] [TERM...]
|
||||||
|
This custom action does foo.
|
||||||
|
\
|
||||||
|
|
||||||
|
>>> todo.sh help bar
|
||||||
|
bar ITEM#[, ITEM#, ...] [TERM...]
|
||||||
|
This custom action does bar.
|
||||||
|
\
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'multiple custom actions help' <<'EOF'
|
||||||
|
>>> todo.sh help foo bar
|
||||||
|
foo ITEM#[, ITEM#, ...] [TERM...]
|
||||||
|
This custom action does foo.
|
||||||
|
\
|
||||||
|
bar ITEM#[, ITEM#, ...] [TERM...]
|
||||||
|
This custom action does bar.
|
||||||
|
\
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'nonexisting action help' <<'EOF'
|
||||||
|
>>> todo.sh help doesnotexist
|
||||||
|
TODO: No action "doesnotexist" exists.
|
||||||
|
=== 1
|
||||||
|
|
||||||
|
>>> todo.sh help foo doesnotexist bar
|
||||||
|
foo ITEM#[, ITEM#, ...] [TERM...]
|
||||||
|
This custom action does foo.
|
||||||
|
\
|
||||||
|
TODO: No action "doesnotexist" exists.
|
||||||
|
=== 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'mixed built-in and custom actions help' <<'EOF'
|
||||||
|
>>> todo.sh help foo shorthelp bar
|
||||||
|
foo ITEM#[, ITEM#, ...] [TERM...]
|
||||||
|
This custom action does foo.
|
||||||
|
\
|
||||||
|
shorthelp
|
||||||
|
List the one-line usage of all built-in and add-on actions.
|
||||||
|
\
|
||||||
|
bar ITEM#[, ITEM#, ...] [TERM...]
|
||||||
|
This custom action does bar.
|
||||||
|
\
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_todo_session 'custom override of built-in action help' <<'EOF'
|
||||||
|
>>> todo.sh help ls
|
||||||
|
ls ITEM#[, ITEM#, ...] [TERM...]
|
||||||
|
This custom action does ls.
|
||||||
|
\
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_done
|
||||||
@@ -264,25 +264,7 @@ test_expect_success () {
|
|||||||
test_expect_output () {
|
test_expect_output () {
|
||||||
test "$#" = 2 ||
|
test "$#" = 2 ||
|
||||||
error "bug in the test script: not 2 parameters to test-expect-output"
|
error "bug in the test script: not 2 parameters to test-expect-output"
|
||||||
if ! test_skip "$@"
|
test_expect_code_and_output 0 "$@"
|
||||||
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_expect_code_and_output () {
|
||||||
@@ -290,7 +272,11 @@ test_expect_code_and_output () {
|
|||||||
error "bug in the test script: not 3 parameters to test-expect-code-and-output"
|
error "bug in the test script: not 3 parameters to test-expect-code-and-output"
|
||||||
if ! test_skip "$@"
|
if ! test_skip "$@"
|
||||||
then
|
then
|
||||||
|
if [ "$1" = 0 ]; then
|
||||||
|
say >&3 "expecting success and output: $3"
|
||||||
|
else
|
||||||
say >&3 "expecting exit code $1 and output: $3"
|
say >&3 "expecting exit code $1 and output: $3"
|
||||||
|
fi
|
||||||
test_run_ "$3"
|
test_run_ "$3"
|
||||||
if [ "$?" = 0 -a "$eval_ret" = "$1" ]
|
if [ "$?" = 0 -a "$eval_ret" = "$1" ]
|
||||||
then
|
then
|
||||||
@@ -566,14 +552,16 @@ test_tick () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Generate and run a series of tests based on a transcript.
|
# Generate and run a series of tests based on a transcript.
|
||||||
# Usage: test_todo_session "description" <<EOF
|
# Usage: test_todo_session "description" <<'EOF'
|
||||||
# >>> command
|
# >>> command
|
||||||
# output1
|
# output1
|
||||||
# output2
|
# output2
|
||||||
|
#
|
||||||
# >>> command
|
# >>> command
|
||||||
# === exit status
|
# === exit status
|
||||||
# output3
|
# output3 with empty line (must be escaped here)
|
||||||
# output4
|
# \
|
||||||
|
# output5
|
||||||
# EOF
|
# EOF
|
||||||
test_todo_session () {
|
test_todo_session () {
|
||||||
test "$#" = 1 ||
|
test "$#" = 1 ||
|
||||||
@@ -582,7 +570,7 @@ test_todo_session () {
|
|||||||
cmd=""
|
cmd=""
|
||||||
status=0
|
status=0
|
||||||
> expect
|
> expect
|
||||||
while read -r line
|
while IFS= read -r line
|
||||||
do
|
do
|
||||||
case $line in
|
case $line in
|
||||||
">>> "*)
|
">>> "*)
|
||||||
@@ -606,6 +594,9 @@ test_todo_session () {
|
|||||||
> expect
|
> expect
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
\\)
|
||||||
|
echo "" >> expect
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "$line" >> expect
|
echo "$line" >> expect
|
||||||
;;
|
;;
|
||||||
|
|||||||
7
todo.cfg
7
todo.cfg
@@ -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"
|
||||||
@@ -62,6 +62,11 @@ export REPORT_FILE="$TODO_DIR/report.txt"
|
|||||||
#
|
#
|
||||||
# export COLOR_DONE=$LIGHT_GREY
|
# export COLOR_DONE=$LIGHT_GREY
|
||||||
|
|
||||||
|
# There is highlighting for projects and contexts.
|
||||||
|
#
|
||||||
|
# export COLOR_PROJECT=$RED
|
||||||
|
# export COLOR_CONTEXT=$RED
|
||||||
|
|
||||||
# === BEHAVIOR ===
|
# === BEHAVIOR ===
|
||||||
|
|
||||||
## customize list output
|
## customize list output
|
||||||
|
|||||||
188
todo.sh
188
todo.sh
@@ -54,11 +54,11 @@ shorthelp()
|
|||||||
del|rm ITEM# [TERM]
|
del|rm ITEM# [TERM]
|
||||||
depri|dp ITEM#[, ITEM#, ITEM#, ...]
|
depri|dp ITEM#[, ITEM#, ITEM#, ...]
|
||||||
do ITEM#[, ITEM#, ITEM#, ...]
|
do ITEM#[, ITEM#, ITEM#, ...]
|
||||||
help
|
help [ACTION...]
|
||||||
list|ls [TERM...]
|
list|ls [TERM...]
|
||||||
listall|lsa [TERM...]
|
listall|lsa [TERM...]
|
||||||
listaddons
|
listaddons
|
||||||
listcon|lsc
|
listcon|lsc [TERM...]
|
||||||
listfile|lf [SRC [TERM...]]
|
listfile|lf [SRC [TERM...]]
|
||||||
listpri|lsp [PRIORITIES] [TERM...]
|
listpri|lsp [PRIORITIES] [TERM...]
|
||||||
listproj|lsprj [TERM...]
|
listproj|lsprj [TERM...]
|
||||||
@@ -81,7 +81,6 @@ shorthelp()
|
|||||||
|
|
||||||
See "help" for more details.
|
See "help" for more details.
|
||||||
EndHelpFooter
|
EndHelpFooter
|
||||||
exit 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
help()
|
help()
|
||||||
@@ -154,6 +153,12 @@ help()
|
|||||||
|
|
||||||
|
|
||||||
EndVerboseHelp
|
EndVerboseHelp
|
||||||
|
actionsHelp
|
||||||
|
addonHelp
|
||||||
|
}
|
||||||
|
|
||||||
|
actionsHelp()
|
||||||
|
{
|
||||||
cat <<-EndActionsHelp
|
cat <<-EndActionsHelp
|
||||||
Built-in Actions:
|
Built-in Actions:
|
||||||
add "THING I NEED TO DO +project @context"
|
add "THING I NEED TO DO +project @context"
|
||||||
@@ -200,8 +205,9 @@ help()
|
|||||||
do ITEM#[, ITEM#, ITEM#, ...]
|
do ITEM#[, ITEM#, ITEM#, ...]
|
||||||
Marks task(s) on line ITEM# as done in todo.txt.
|
Marks task(s) on line ITEM# as done in todo.txt.
|
||||||
|
|
||||||
help
|
help [ACTION...]
|
||||||
Display this help message.
|
Display help about usage, options, built-in and add-on actions,
|
||||||
|
or just the usage help for the passed ACTION(s).
|
||||||
|
|
||||||
list [TERM...]
|
list [TERM...]
|
||||||
ls [TERM...]
|
ls [TERM...]
|
||||||
@@ -223,9 +229,10 @@ help()
|
|||||||
listaddons
|
listaddons
|
||||||
Lists all added and overridden actions in the actions directory.
|
Lists all added and overridden actions in the actions directory.
|
||||||
|
|
||||||
listcon
|
listcon [TERM...]
|
||||||
lsc
|
lsc [TERM...]
|
||||||
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.
|
||||||
|
If TERM specified, considers only tasks that contain TERM(s).
|
||||||
|
|
||||||
listfile [SRC [TERM...]]
|
listfile [SRC [TERM...]]
|
||||||
lf [SRC [TERM...]]
|
lf [SRC [TERM...]]
|
||||||
@@ -245,10 +252,11 @@ help()
|
|||||||
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).
|
||||||
|
|
||||||
listproj
|
listproj [TERM...]
|
||||||
lsprj
|
lsprj [TERM...]
|
||||||
Lists all the projects (terms that start with a + sign) in
|
Lists all the projects (terms that start with a + sign) in
|
||||||
todo.txt.
|
todo.txt.
|
||||||
|
If TERM specified, considers only tasks that contain TERM(s).
|
||||||
|
|
||||||
move ITEM# DEST [SRC]
|
move ITEM# DEST [SRC]
|
||||||
mv ITEM# DEST [SRC]
|
mv ITEM# DEST [SRC]
|
||||||
@@ -278,9 +286,6 @@ help()
|
|||||||
List the one-line usage of all built-in and add-on actions.
|
List the one-line usage of all built-in and add-on actions.
|
||||||
|
|
||||||
EndActionsHelp
|
EndActionsHelp
|
||||||
|
|
||||||
addonHelp
|
|
||||||
exit 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addonHelp()
|
addonHelp()
|
||||||
@@ -297,11 +302,50 @@ addonHelp()
|
|||||||
didPrintAddonActionsHeader=1
|
didPrintAddonActionsHeader=1
|
||||||
fi
|
fi
|
||||||
"$action" usage
|
"$action" usage
|
||||||
|
elif [ -d "$action" -a -x "$action/$(basename $action)" ]; then
|
||||||
|
if [ ! "$didPrintAddonActionsHeader" ]; then
|
||||||
|
cat <<-EndAddonActionsHeader
|
||||||
|
Add-on Actions:
|
||||||
|
EndAddonActionsHeader
|
||||||
|
didPrintAddonActionsHeader=1
|
||||||
|
fi
|
||||||
|
"$action/$(basename $action)" usage
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actionUsage()
|
||||||
|
{
|
||||||
|
for actionName
|
||||||
|
do
|
||||||
|
action="${TODO_ACTIONS_DIR}/${actionName}"
|
||||||
|
if [ -f "$action" -a -x "$action" ]; then
|
||||||
|
"$action" usage
|
||||||
|
elif [ -d "$action" -a -x "$action/$(basename $action)" ]; then
|
||||||
|
"$action/$(basename $action)" usage
|
||||||
|
else
|
||||||
|
builtinActionUsage=$(actionsHelp | sed -n -e "/^ ${actionName//\//\\/} /,/^\$/p" -e "/^ ${actionName//\//\\/}$/,/^\$/p")
|
||||||
|
if [ "$builtinActionUsage" ]; then
|
||||||
|
echo "$builtinActionUsage"
|
||||||
|
echo
|
||||||
|
else
|
||||||
|
die "TODO: No action \"${actionName}\" exists."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
dieWithHelp()
|
||||||
|
{
|
||||||
|
case "$1" in
|
||||||
|
help) help;;
|
||||||
|
shorthelp) shorthelp;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
|
||||||
|
die "$@"
|
||||||
|
}
|
||||||
die()
|
die()
|
||||||
{
|
{
|
||||||
echo "$*"
|
echo "$*"
|
||||||
@@ -389,21 +433,22 @@ replaceOrPrepend()
|
|||||||
else
|
else
|
||||||
input=$*
|
input=$*
|
||||||
fi
|
fi
|
||||||
cleaninput "for sed"
|
|
||||||
|
|
||||||
# Retrieve existing priority and prepended date
|
# Retrieve existing priority and prepended date
|
||||||
priority=$(sed -e "$item!d" -e $item's/^\((.) \)\{0,1\}\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} \)\{0,1\}.*/\1/' "$TODO_FILE")
|
local -r priAndDateExpr='^\((.) \)\{0,1\}\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} \)\{0,1\}'
|
||||||
prepdate=$(sed -e "$item!d" -e $item's/^\((.) \)\{0,1\}\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} \)\{0,1\}.*/\2/' "$TODO_FILE")
|
priority=$(sed -e "$item!d" -e "${item}s/${priAndDateExpr}.*/\\1/" "$TODO_FILE")
|
||||||
|
prepdate=$(sed -e "$item!d" -e "${item}s/${priAndDateExpr}.*/\\2/" "$TODO_FILE")
|
||||||
|
|
||||||
if [ "$prepdate" -a "$action" = "replace" ] && [ "$(echo "$input"|sed -e 's/^\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\}\)\{0,1\}.*/\1/')" ]; then
|
if [ "$prepdate" -a "$action" = "replace" ] && [ "$(echo "$input"|sed -e "s/${priAndDateExpr}.*/\\1\\2/")" ]; then
|
||||||
# If the replaced text starts with a date, it will replace the existing
|
# If the replaced text starts with a [priority +] date, it will replace
|
||||||
# date, too.
|
# the existing date, too.
|
||||||
prepdate=
|
prepdate=
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Temporarily remove any existing priority and prepended date, perform the
|
# Temporarily remove any existing priority and prepended date, perform the
|
||||||
# change (replace/prepend) and re-insert the existing priority and prepended
|
# change (replace/prepend) and re-insert the existing priority and prepended
|
||||||
# date again.
|
# date again.
|
||||||
|
cleaninput "for sed"
|
||||||
sed -i.bak -e "$item s/^${priority}${prepdate}//" -e "$item s|^.*|${priority}${prepdate}${input}${backref}|" "$TODO_FILE"
|
sed -i.bak -e "$item s/^${priority}${prepdate}//" -e "$item s|^.*|${priority}${prepdate}${input}${backref}|" "$TODO_FILE"
|
||||||
if [ $TODOTXT_VERBOSE -gt 0 ]; then
|
if [ $TODOTXT_VERBOSE -gt 0 ]; then
|
||||||
getNewtodo "$item"
|
getNewtodo "$item"
|
||||||
@@ -432,6 +477,9 @@ OVR_TODOTXT_DEFAULT_ACTION="$TODOTXT_DEFAULT_ACTION"
|
|||||||
OVR_TODOTXT_SORT_COMMAND="$TODOTXT_SORT_COMMAND"
|
OVR_TODOTXT_SORT_COMMAND="$TODOTXT_SORT_COMMAND"
|
||||||
OVR_TODOTXT_FINAL_FILTER="$TODOTXT_FINAL_FILTER"
|
OVR_TODOTXT_FINAL_FILTER="$TODOTXT_FINAL_FILTER"
|
||||||
|
|
||||||
|
# Prevent GREP_OPTIONS from malforming grep's output
|
||||||
|
GREP_OPTIONS=""
|
||||||
|
|
||||||
# == PROCESS OPTIONS ==
|
# == PROCESS OPTIONS ==
|
||||||
while getopts ":fhpcnNaAtTvVx+@Pd:" Option
|
while getopts ":fhpcnNaAtTvVx+@Pd:" Option
|
||||||
do
|
do
|
||||||
@@ -488,6 +536,7 @@ do
|
|||||||
# Cannot just invoke shorthelp() because we need the configuration
|
# Cannot just invoke shorthelp() because we need the configuration
|
||||||
# processed to locate the add-on actions directory.
|
# processed to locate the add-on actions directory.
|
||||||
set -- '-h' 'shorthelp'
|
set -- '-h' 'shorthelp'
|
||||||
|
OPTIND=2
|
||||||
;;
|
;;
|
||||||
n )
|
n )
|
||||||
OVR_TODOTXT_PRESERVE_LINE_NUMBERS=0
|
OVR_TODOTXT_PRESERVE_LINE_NUMBERS=0
|
||||||
@@ -545,6 +594,7 @@ TODOTXT_DEFAULT_ACTION=${TODOTXT_DEFAULT_ACTION:-}
|
|||||||
TODOTXT_SORT_COMMAND=${TODOTXT_SORT_COMMAND:-env LC_COLLATE=C sort -f -k2}
|
TODOTXT_SORT_COMMAND=${TODOTXT_SORT_COMMAND:-env LC_COLLATE=C sort -f -k2}
|
||||||
TODOTXT_DISABLE_FILTER=${TODOTXT_DISABLE_FILTER:-}
|
TODOTXT_DISABLE_FILTER=${TODOTXT_DISABLE_FILTER:-}
|
||||||
TODOTXT_FINAL_FILTER=${TODOTXT_FINAL_FILTER:-cat}
|
TODOTXT_FINAL_FILTER=${TODOTXT_FINAL_FILTER:-cat}
|
||||||
|
TODOTXT_GLOBAL_CFG_FILE=${TODOTXT_GLOBAL_CFG_FILE:-/etc/todo/config}
|
||||||
|
|
||||||
# Export all TODOTXT_* variables
|
# Export all TODOTXT_* variables
|
||||||
export ${!TODOTXT_@}
|
export ${!TODOTXT_@}
|
||||||
@@ -575,6 +625,10 @@ export PRI_B=$GREEN # color for B priority
|
|||||||
export PRI_C=$LIGHT_BLUE # color for C priority
|
export PRI_C=$LIGHT_BLUE # color for C priority
|
||||||
export PRI_X=$WHITE # color unless explicitly defined
|
export PRI_X=$WHITE # color unless explicitly defined
|
||||||
|
|
||||||
|
# Default project and context colors.
|
||||||
|
export COLOR_PROJECT=$NONE
|
||||||
|
export COLOR_CONTEXT=$NONE
|
||||||
|
|
||||||
# Default highlight colors.
|
# Default highlight colors.
|
||||||
export COLOR_DONE=$LIGHT_GREY # color for done (but not yet archived) tasks
|
export COLOR_DONE=$LIGHT_GREY # color for done (but not yet archived) tasks
|
||||||
|
|
||||||
@@ -611,6 +665,15 @@ export SENTENCE_DELIMITERS=',.:;'
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ -e "$TODOTXT_CFG_FILE" ] || {
|
||||||
|
CFG_FILE_ALT="$TODOTXT_GLOBAL_CFG_FILE"
|
||||||
|
|
||||||
|
if [ -e "$CFG_FILE_ALT" ]
|
||||||
|
then
|
||||||
|
TODOTXT_CFG_FILE="$CFG_FILE_ALT"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if [ -z "$TODO_ACTIONS_DIR" -o ! -d "$TODO_ACTIONS_DIR" ]
|
if [ -z "$TODO_ACTIONS_DIR" -o ! -d "$TODO_ACTIONS_DIR" ]
|
||||||
then
|
then
|
||||||
@@ -628,7 +691,7 @@ fi
|
|||||||
}
|
}
|
||||||
|
|
||||||
# === SANITY CHECKS (thanks Karl!) ===
|
# === SANITY CHECKS (thanks Karl!) ===
|
||||||
[ -r "$TODOTXT_CFG_FILE" ] || die "Fatal Error: Cannot read configuration file $TODOTXT_CFG_FILE"
|
[ -r "$TODOTXT_CFG_FILE" ] || dieWithHelp "$1" "Fatal Error: Cannot read configuration file $TODOTXT_CFG_FILE"
|
||||||
|
|
||||||
. "$TODOTXT_CFG_FILE"
|
. "$TODOTXT_CFG_FILE"
|
||||||
|
|
||||||
@@ -667,12 +730,12 @@ fi
|
|||||||
ACTION=${1:-$TODOTXT_DEFAULT_ACTION}
|
ACTION=${1:-$TODOTXT_DEFAULT_ACTION}
|
||||||
|
|
||||||
[ -z "$ACTION" ] && usage
|
[ -z "$ACTION" ] && usage
|
||||||
[ -d "$TODO_DIR" ] || die "Fatal Error: $TODO_DIR is not a directory"
|
[ -d "$TODO_DIR" ] || mkdir -p $TODO_DIR 2> /dev/null || dieWithHelp "$1" "Fatal Error: $TODO_DIR is not a directory"
|
||||||
( cd "$TODO_DIR" ) || die "Fatal Error: Unable to cd to $TODO_DIR"
|
( cd "$TODO_DIR" ) || dieWithHelp "$1" "Fatal Error: Unable to cd to $TODO_DIR"
|
||||||
|
|
||||||
[ -f "$TODO_FILE" ] || cp /dev/null "$TODO_FILE"
|
[ -f "$TODO_FILE" -o -c "$TODO_FILE" ] || > "$TODO_FILE"
|
||||||
[ -f "$DONE_FILE" ] || cp /dev/null "$DONE_FILE"
|
[ -f "$DONE_FILE" -o -c "$DONE_FILE" ] || > "$DONE_FILE"
|
||||||
[ -f "$REPORT_FILE" ] || cp /dev/null "$REPORT_FILE"
|
[ -f "$REPORT_FILE" -o -c "$REPORT_FILE" ] || > "$REPORT_FILE"
|
||||||
|
|
||||||
if [ $TODOTXT_PLAIN = 1 ]; then
|
if [ $TODOTXT_PLAIN = 1 ]; then
|
||||||
for clr in ${!PRI_@}; do
|
for clr in ${!PRI_@}; do
|
||||||
@@ -681,8 +744,13 @@ if [ $TODOTXT_PLAIN = 1 ]; then
|
|||||||
PRI_X=$NONE
|
PRI_X=$NONE
|
||||||
DEFAULT=$NONE
|
DEFAULT=$NONE
|
||||||
COLOR_DONE=$NONE
|
COLOR_DONE=$NONE
|
||||||
|
COLOR_PROJECT=$NONE
|
||||||
|
COLOR_CONTEXT=$NONE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
[[ "$HIDE_PROJECTS_SUBSTITUTION" ]] && COLOR_PROJECT="$NONE"
|
||||||
|
[[ "$HIDE_CONTEXTS_SUBSTITUTION" ]] && COLOR_CONTEXT="$NONE"
|
||||||
|
|
||||||
_addto() {
|
_addto() {
|
||||||
file="$1"
|
file="$1"
|
||||||
input="$2"
|
input="$2"
|
||||||
@@ -829,15 +897,38 @@ _format()
|
|||||||
return color
|
return color
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
clr = ""
|
||||||
if (match($0, /^[0-9]+ x /)) {
|
if (match($0, /^[0-9]+ x /)) {
|
||||||
print highlight("COLOR_DONE") $0 highlight("DEFAULT")
|
clr = highlight("COLOR_DONE")
|
||||||
} else if (match($0, /^[0-9]+ \([A-Z]\) /)) {
|
} 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 \
|
clr = (clr ? clr : highlight("PRI_X"))
|
||||||
(clr ? clr : highlight("PRI_X")) \
|
if (ENVIRON["HIDE_PRIORITY_SUBSTITUTION"] != "") {
|
||||||
(ENVIRON["HIDE_PRIORITY_SUBSTITUTION"] == "" ? $0 : substr($0, 1, RLENGTH - 4) substr($0, RSTART + RLENGTH)) \
|
$0 = substr($0, 1, RLENGTH - 4) substr($0, RSTART + RLENGTH)
|
||||||
highlight("DEFAULT")
|
}
|
||||||
} else { print }
|
}
|
||||||
|
end_clr = (clr ? highlight("DEFAULT") : "")
|
||||||
|
|
||||||
|
prj_beg = highlight("COLOR_PROJECT")
|
||||||
|
prj_end = (prj_beg ? (highlight("DEFAULT") clr) : "")
|
||||||
|
|
||||||
|
ctx_beg = highlight("COLOR_CONTEXT")
|
||||||
|
ctx_end = (ctx_beg ? (highlight("DEFAULT") clr) : "")
|
||||||
|
|
||||||
|
gsub(/[ \t][ \t]*/, "\n&\n")
|
||||||
|
len = split($0, words, /\n/)
|
||||||
|
|
||||||
|
printf "%s", clr
|
||||||
|
for (i = 1; i <= len; ++i) {
|
||||||
|
if (words[i] ~ /^[+].*[A-Za-z0-9_]$/) {
|
||||||
|
printf "%s", prj_beg words[i] prj_end
|
||||||
|
} else if (words[i] ~ /^[@].*[A-Za-z0-9_]$/) {
|
||||||
|
printf "%s", ctx_beg words[i] ctx_end
|
||||||
|
} else {
|
||||||
|
printf "%s", words[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf "%s\n", end_clr
|
||||||
}
|
}
|
||||||
''' \
|
''' \
|
||||||
| sed '''
|
| sed '''
|
||||||
@@ -858,7 +949,17 @@ _format()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
export -f cleaninput getPrefix getTodo getNewtodo shellquote filtercommand _list getPadding _format die
|
listWordsWithSigil()
|
||||||
|
{
|
||||||
|
sigil=$1
|
||||||
|
shift
|
||||||
|
|
||||||
|
FILE=$TODO_FILE
|
||||||
|
[ "$TODOTXT_SOURCEVAR" ] && eval "FILE=$TODOTXT_SOURCEVAR"
|
||||||
|
eval "$(filtercommand 'cat "${FILE[@]}"' '' "$@")" | grep -o "[^ ]*${sigil}[^ ]\\+" | grep "^$sigil" | sort -u
|
||||||
|
}
|
||||||
|
|
||||||
|
export -f cleaninput getPrefix getTodo getNewtodo shellquote filtercommand _list listWordsWithSigil getPadding _format die
|
||||||
|
|
||||||
# == HANDLE ACTION ==
|
# == HANDLE ACTION ==
|
||||||
action=$( printf "%s\n" "$ACTION" | tr 'A-Z' 'a-z' )
|
action=$( printf "%s\n" "$ACTION" | tr 'A-Z' 'a-z' )
|
||||||
@@ -873,6 +974,10 @@ then
|
|||||||
shift
|
shift
|
||||||
## Reset action to new first argument
|
## Reset action to new first argument
|
||||||
action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' )
|
action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' )
|
||||||
|
elif [ -d "$TODO_ACTIONS_DIR/$action" -a -x "$TODO_ACTIONS_DIR/$action/$action" ]
|
||||||
|
then
|
||||||
|
"$TODO_ACTIONS_DIR/$action/$action" "$@"
|
||||||
|
exit $?
|
||||||
elif [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/$action" ]
|
elif [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/$action" ]
|
||||||
then
|
then
|
||||||
"$TODO_ACTIONS_DIR/$action" "$@"
|
"$TODO_ACTIONS_DIR/$action" "$@"
|
||||||
@@ -1075,6 +1180,11 @@ case $action in
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
"help" )
|
"help" )
|
||||||
|
shift ## Was help; new $1 is first help topic / action name
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
# Don't use PAGER here; we don't expect much usage output from one / few actions.
|
||||||
|
actionUsage "$@"
|
||||||
|
else
|
||||||
if [ -t 1 ] ; then # STDOUT is a TTY
|
if [ -t 1 ] ; then # STDOUT is a TTY
|
||||||
if which "${PAGER:-less}" >/dev/null 2>&1; then
|
if which "${PAGER:-less}" >/dev/null 2>&1; then
|
||||||
# we have a working PAGER (or less as a default)
|
# we have a working PAGER (or less as a default)
|
||||||
@@ -1082,6 +1192,7 @@ case $action in
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
help # just in case something failed above, we go ahead and just spew to STDOUT
|
help # just in case something failed above, we go ahead and just spew to STDOUT
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
"shorthelp" )
|
"shorthelp" )
|
||||||
@@ -1105,7 +1216,7 @@ case $action in
|
|||||||
TOTAL=$( sed -n '$ =' "$TODO_FILE" )
|
TOTAL=$( sed -n '$ =' "$TODO_FILE" )
|
||||||
PADDING=${#TOTAL}
|
PADDING=${#TOTAL}
|
||||||
|
|
||||||
post_filter_command="awk -v TOTAL=$TOTAL -v PADDING=$PADDING '{ \$1 = sprintf(\"%\" PADDING \"d\", (\$1 > TOTAL ? 0 : \$1)); print }' "
|
post_filter_command="${post_filter_command:-}${post_filter_command:+ | }awk -v TOTAL=$TOTAL -v PADDING=$PADDING '{ \$1 = sprintf(\"%\" PADDING \"d\", (\$1 > TOTAL ? 0 : \$1)); print }' "
|
||||||
cat "$TODO_FILE" "$DONE_FILE" | TODOTXT_VERBOSE=0 _format '' "$PADDING" "$@"
|
cat "$TODO_FILE" "$DONE_FILE" | TODOTXT_VERBOSE=0 _format '' "$PADDING" "$@"
|
||||||
|
|
||||||
if [ $TODOTXT_VERBOSE -gt 0 ]; then
|
if [ $TODOTXT_VERBOSE -gt 0 ]; then
|
||||||
@@ -1133,23 +1244,20 @@ case $action in
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
"listcon" | "lsc" )
|
"listcon" | "lsc" )
|
||||||
FILE=$TODO_FILE
|
shift
|
||||||
[ "$TODOTXT_SOURCEVAR" ] && eval "FILE=$TODOTXT_SOURCEVAR"
|
listWordsWithSigil '@' "$@"
|
||||||
grep -ho '[^ ]*@[^ ]\+' "${FILE[@]}" | grep '^@' | sort -u
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
"listproj" | "lsprj" )
|
"listproj" | "lsprj" )
|
||||||
FILE=$TODO_FILE
|
|
||||||
[ "$TODOTXT_SOURCEVAR" ] && eval "FILE=$TODOTXT_SOURCEVAR"
|
|
||||||
shift
|
shift
|
||||||
eval "$(filtercommand 'cat "${FILE[@]}"' '' "$@")" | grep -o '[^ ]*+[^ ]\+' | grep '^+' | sort -u
|
listWordsWithSigil '+' "$@"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
"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 -e '^[A-Z]$' -e '^[A-Z]-[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="${post_filter_command:-}${post_filter_command:+ | }grep '^ *[0-9]\+ ([${pri}]) '"
|
||||||
_list "$TODO_FILE" "$@"
|
_list "$TODO_FILE" "$@"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@@ -1311,6 +1419,8 @@ note: PRIORITY must be anywhere from A to Z."
|
|||||||
do
|
do
|
||||||
if [ -f "$action" -a -x "$action" ]; then
|
if [ -f "$action" -a -x "$action" ]; then
|
||||||
echo "$action"
|
echo "$action"
|
||||||
|
elif [ -d "$action" -a -x "$action/$action" ]; then
|
||||||
|
echo "$action"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -14,20 +14,23 @@ _todo()
|
|||||||
rm depri dp do help list ls listaddons 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"
|
||||||
|
local -r MOVE_COMMAND_PATTERN='^(move|mv)$'
|
||||||
|
|
||||||
local _todo_sh=${_todo_sh:-todo.sh}
|
local _todo_sh=${_todo_sh:-todo.sh}
|
||||||
local completions
|
local completions
|
||||||
if [ $COMP_CWORD -eq 1 ]; then
|
if [ $COMP_CWORD -eq 1 ]; then
|
||||||
completions="$COMMANDS $(eval TODOTXT_VERBOSE=0 $_todo_sh command listaddons) $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_COMMAND_PATTERN || \
|
||||||
"${COMP_WORDS[COMP_CWORD-3]}" =~ ^(move|mv)$ ) ]]; then
|
"${COMP_WORDS[COMP_CWORD-3]}" =~ $MOVE_COMMAND_PATTERN ) ]]; 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=$(eval 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;;
|
||||||
|
help)
|
||||||
|
completions="$COMMANDS $(eval TODOTXT_VERBOSE=0 $_todo_sh command listaddons)";;
|
||||||
addto|listfile|lf)
|
addto|listfile|lf)
|
||||||
completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listfile);;
|
completions=$(eval TODOTXT_VERBOSE=0 $_todo_sh command listfile);;
|
||||||
-*) completions="$COMMANDS $(eval TODOTXT_VERBOSE=0 $_todo_sh command listaddons) $OPTS";;
|
-*) completions="$COMMANDS $(eval TODOTXT_VERBOSE=0 $_todo_sh command listaddons) $OPTS";;
|
||||||
@@ -58,8 +61,8 @@ _todo()
|
|||||||
# a safety check of the ls action output.
|
# a safety check of the ls action output.
|
||||||
local todo=$( \
|
local todo=$( \
|
||||||
eval 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]\{1,\} //' -e 's/\((.) \)[0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} /\1/' \
|
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/^\([xX] \)\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} \)\{1,2\}/\1/' \
|
||||||
-e 's/[[:space:]]*$//' \
|
-e 's/[[:space:]]*$//' \
|
||||||
-e '1q' \
|
-e '1q' \
|
||||||
)
|
)
|
||||||
@@ -85,6 +88,9 @@ 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
|
||||||
|
# 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
|
# 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:
|
# PATH, you need to add and use a wrapper completion function, like this:
|
||||||
|
|||||||
Reference in New Issue
Block a user