Rename `t' to `justdoit' - justdoit - Simpler (but with not all the features) reimplementation todo.txt CLI
(HTM) hg clone https://bitbucket.org/iamleot/justdoit
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) changeset 67517dd04e717a75c0781b31cbd3bc7995c4897a
(DIR) parent 8d69dd7ce60a69da1cc19da11425f7f57bc670b0
(HTM) Author: Leonardo Taccari <iamleot@gmail.com>
Date: Wed, 8 May 2019 19:26:59
Rename `t' to `justdoit'
Diffstat:
justdoit.sh | 318 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
t.sh | 318 ------------------------------------------------------------
2 files changed, 318 insertions(+), 318 deletions(-)
---
diff -r 8d69dd7ce60a -r 67517dd04e71 justdoit.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/justdoit.sh Wed May 08 19:26:59 2019 +0200
@@ -0,0 +1,318 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2018 Leonardo Taccari
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+config_file=${T_CONFIG_FILE:=${HOME}/.config/t/t.conf}
+
+if [ -f "${config_file}" ]; then
+ . "${config_file}"
+fi
+
+todo_file=${T_TODO_FILE:=${HOME}/.config/t/todo.txt}
+done_file=${T_DONE_FILE:=${HOME}/.config/t/done.txt}
+
+
+#
+# Print usage message and exit
+#
+usage()
+{
+
+ echo "usage: t add|done|due|edit|help|list|listall"
+
+ exit 1
+}
+
+
+#
+# Print help message and exit
+#
+help()
+{
+
+ echo "usage: t add|done|edit|help|list|listall"
+ echo
+ echo "a|add entry"
+ echo "Add the entry \`entry' at the end of the todo.txt file."
+ echo
+ echo "d|do|done item"
+ echo "Mark an item \`item' of todo.txt file as done, moving it in done.txt"
+ echo "and removing it from todo.txt"
+ echo
+ echo "due days [pattern]"
+ echo "List all task due next number of days - and all the expired"
+ echo "ones - that matches pattern (or all of them if no pattern is"
+ echo "provided)"
+ echo
+ echo "e|ed|edit"
+ echo "Open the todo.txt with the \${EDITOR}"
+ echo
+ echo "h|help"
+ echo "Show an help message"
+ echo
+ echo "l|ls|list [pattern]"
+ echo "List all todo.txt entries that matches pattern (or all of them"
+ echo "if no pattern is provided)"
+ echo
+ echo "la|lsa|listall [pattern]"
+ echo "List all done.txt and todo.txt entries that matches pattern (or"
+ echo "all of them if no pattern is provided)"
+ echo
+
+ exit 1
+}
+
+
+#
+# Add an entry at the end of a todo.txt file
+#
+add()
+{
+ file=$1
+ entry=$2
+
+ echo "${entry}" >> "${file}"
+}
+
+
+#
+# Mark an entry item as done, adding it to the done.txt file and removing it
+# from the todo.txt file.
+#
+mark_done()
+{
+ tfile=$1
+ dfile=$2
+ item=$(($3))
+
+ if [ ${item} -ge 1 ] && [ ${item} -le $(wc -l < "${tfile}") ]; then
+ {
+ printf "x %s " "$(date +%Y-%m-%d)";
+ sed -n "${item}p" "${tfile}";
+ } >> "${dfile}"
+ sed -i.bak "${item}d" "${tfile}"
+ fi
+}
+
+
+#
+# List, show the contents of a todo.txt file
+#
+list()
+{
+ file=$1
+ search=$2
+
+ if [ "${search}" ]; then
+ filter() grep -F -- "${search}"
+ else
+ filter() cat
+ fi
+
+ cat "${file}" | prettify | filter
+}
+
+
+#
+# Prettify the output of a todo.txt
+#
+prettify()
+{
+
+ awk '
+ BEGIN {
+ FS = " "
+ }
+
+ function bold(s) {
+ return sprintf("\033[1m%s\033[0m", s);
+ }
+
+ function underline(s) {
+ return sprintf("\033[4m%s\033[0m", s);
+ }
+
+ #
+ # Parse the entry and populate all optional and non-optional fields
+ #
+ # Every line of todo.txt file should have the following format:
+ #
+ # +------------+------------+-----------------+---------------+-------------+
+ # | completion | priority | completion date | creation date | description |
+ # | (optional) | (optional) | (optional) | (optional) | |
+ # +------------+------------+-----------------+---------------+-------------+
+ #
+ # where:
+ # - completion: just a lower-case "x" to mark that a task is done
+ # - priority: a upper-case letter under parethenses (e.g. "(A)")
+ # - completion date: date of completion of the task in the %Y-%m-%d
+ # format (e.g. "2018-08-18")
+ # - creation date: date of creation of the task in the %Y-%m-%d
+ # format (e.g. "2018-08-18")
+ # - description: text of the task; can contain multiple +project_tag,
+ # @context_tag, special key/value tag (key:value)
+ #
+ {
+ completion = ""
+ priority = ""
+ completion_date = ""
+ creation_date = ""
+ description = ""
+
+ i = 1
+
+ if ($i == "x") {
+ completion = "x"
+ i++
+ }
+ if (match($i, /\([A-Z]\)/)) {
+ priority = $i
+ i++
+ }
+ if (completion && match($i, /[0-9]+-[0-9]+-[0-9]+/)) {
+ completion_date = $i
+ i++
+ }
+ if (match($i, /[0-9]+-[0-9]+-[0-9]+/)) {
+ creation_date = $i
+ i++
+ }
+
+ # Remove any non-description fields and possible leading spaces
+ for (j = 1; j < i; j++) {
+ $j = ""
+ }
+ sub(/^ +/, "")
+ description = $0
+ }
+
+ {
+ # bold all the tags
+ gsub(/@[^ ]+/, "\033[1m&\033[0m", description)
+
+ if (completion) {
+ printf("%12s %s\n", underline(completion), description)
+ } else {
+ n++
+ printf("%12s %s\n", underline(n), description)
+ }
+ }
+ '
+}
+
+
+#
+# Filter all due: key-values task of the next n. days and all "expired" ones.
+#
+due()
+{
+ days="$1"
+
+ awk -v days="${days}" '
+ function date_to_seconds(date) {
+ cmd = "date -d " date " +%s"
+ cmd | getline
+ close(cmd)
+ return $0
+ }
+
+ function seconds_to_date(seconds) {
+ cmd = "date -r " seconds " +%Y%m%d"
+ cmd | getline
+ close(cmd)
+ return $0
+ }
+
+ BEGIN {
+ n_days = int(days)
+ n_seconds = date_to_seconds(strftime("%Y%m%d")) + \
+ (n_days * 60 * 60 * 24)
+ }
+
+ match($0, /due:[0-9]+-[0-9]+-[0-9]+/) {
+ # XXX: We mess up with getline in date_to_seconds()
+ # XXX: so backup the current line.
+ s = $0
+
+ # Delete "due:" and convert the date in %Y%m%d format
+ due_date = substr(s, RSTART + 4, RLENGTH - 4)
+ gsub(/\-/, "", due_date)
+
+ if (n_seconds >= date_to_seconds(due_date)) {
+ print s
+ }
+ }
+ '
+}
+
+
+#
+# t, a todo.sh clone in POSIX shell script
+#
+main()
+{
+ subcommand=$1
+
+ case $subcommand in
+ a|add)
+ entry=$2
+ add "${todo_file}" "${entry}"
+ ;;
+ d|do|done)
+ item=$2
+ mark_done "${todo_file}" "${done_file}" "${item}"
+ ;;
+ due)
+ days=$2
+ search=$3
+ list "${todo_file}" "${search}" | due "${days}"
+ ;;
+ e|ed|edit)
+ ${EDITOR} "${todo_file}"
+ ;;
+ h|help)
+ help
+ ;;
+ l|ls|list)
+ search=$2
+ list "${todo_file}" "${search}"
+ ;;
+ la|lsa|listall)
+ search=$2
+ list "${done_file}" "${search}"
+ list "${todo_file}" "${search}"
+ ;;
+ *)
+ usage
+ ;;
+ esac
+
+ exit 0
+}
+
+main "$@"
diff -r 8d69dd7ce60a -r 67517dd04e71 t.sh
--- a/t.sh Sat Sep 15 13:17:11 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,318 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2018 Leonardo Taccari
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
-# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-#
-
-config_file=${T_CONFIG_FILE:=${HOME}/.config/t/t.conf}
-
-if [ -f "${config_file}" ]; then
- . "${config_file}"
-fi
-
-todo_file=${T_TODO_FILE:=${HOME}/.config/t/todo.txt}
-done_file=${T_DONE_FILE:=${HOME}/.config/t/done.txt}
-
-
-#
-# Print usage message and exit
-#
-usage()
-{
-
- echo "usage: t add|done|due|edit|help|list|listall"
-
- exit 1
-}
-
-
-#
-# Print help message and exit
-#
-help()
-{
-
- echo "usage: t add|done|edit|help|list|listall"
- echo
- echo "a|add entry"
- echo "Add the entry \`entry' at the end of the todo.txt file."
- echo
- echo "d|do|done item"
- echo "Mark an item \`item' of todo.txt file as done, moving it in done.txt"
- echo "and removing it from todo.txt"
- echo
- echo "due days [pattern]"
- echo "List all task due next number of days - and all the expired"
- echo "ones - that matches pattern (or all of them if no pattern is"
- echo "provided)"
- echo
- echo "e|ed|edit"
- echo "Open the todo.txt with the \${EDITOR}"
- echo
- echo "h|help"
- echo "Show an help message"
- echo
- echo "l|ls|list [pattern]"
- echo "List all todo.txt entries that matches pattern (or all of them"
- echo "if no pattern is provided)"
- echo
- echo "la|lsa|listall [pattern]"
- echo "List all done.txt and todo.txt entries that matches pattern (or"
- echo "all of them if no pattern is provided)"
- echo
-
- exit 1
-}
-
-
-#
-# Add an entry at the end of a todo.txt file
-#
-add()
-{
- file=$1
- entry=$2
-
- echo "${entry}" >> "${file}"
-}
-
-
-#
-# Mark an entry item as done, adding it to the done.txt file and removing it
-# from the todo.txt file.
-#
-mark_done()
-{
- tfile=$1
- dfile=$2
- item=$(($3))
-
- if [ ${item} -ge 1 ] && [ ${item} -le $(wc -l < "${tfile}") ]; then
- {
- printf "x %s " "$(date +%Y-%m-%d)";
- sed -n "${item}p" "${tfile}";
- } >> "${dfile}"
- sed -i.bak "${item}d" "${tfile}"
- fi
-}
-
-
-#
-# List, show the contents of a todo.txt file
-#
-list()
-{
- file=$1
- search=$2
-
- if [ "${search}" ]; then
- filter() grep -F -- "${search}"
- else
- filter() cat
- fi
-
- cat "${file}" | prettify | filter
-}
-
-
-#
-# Prettify the output of a todo.txt
-#
-prettify()
-{
-
- awk '
- BEGIN {
- FS = " "
- }
-
- function bold(s) {
- return sprintf("\033[1m%s\033[0m", s);
- }
-
- function underline(s) {
- return sprintf("\033[4m%s\033[0m", s);
- }
-
- #
- # Parse the entry and populate all optional and non-optional fields
- #
- # Every line of todo.txt file should have the following format:
- #
- # +------------+------------+-----------------+---------------+-------------+
- # | completion | priority | completion date | creation date | description |
- # | (optional) | (optional) | (optional) | (optional) | |
- # +------------+------------+-----------------+---------------+-------------+
- #
- # where:
- # - completion: just a lower-case "x" to mark that a task is done
- # - priority: a upper-case letter under parethenses (e.g. "(A)")
- # - completion date: date of completion of the task in the %Y-%m-%d
- # format (e.g. "2018-08-18")
- # - creation date: date of creation of the task in the %Y-%m-%d
- # format (e.g. "2018-08-18")
- # - description: text of the task; can contain multiple +project_tag,
- # @context_tag, special key/value tag (key:value)
- #
- {
- completion = ""
- priority = ""
- completion_date = ""
- creation_date = ""
- description = ""
-
- i = 1
-
- if ($i == "x") {
- completion = "x"
- i++
- }
- if (match($i, /\([A-Z]\)/)) {
- priority = $i
- i++
- }
- if (completion && match($i, /[0-9]+-[0-9]+-[0-9]+/)) {
- completion_date = $i
- i++
- }
- if (match($i, /[0-9]+-[0-9]+-[0-9]+/)) {
- creation_date = $i
- i++
- }
-
- # Remove any non-description fields and possible leading spaces
- for (j = 1; j < i; j++) {
- $j = ""
- }
- sub(/^ +/, "")
- description = $0
- }
-
- {
- # bold all the tags
- gsub(/@[^ ]+/, "\033[1m&\033[0m", description)
-
- if (completion) {
- printf("%12s %s\n", underline(completion), description)
- } else {
- n++
- printf("%12s %s\n", underline(n), description)
- }
- }
- '
-}
-
-
-#
-# Filter all due: key-values task of the next n. days and all "expired" ones.
-#
-due()
-{
- days="$1"
-
- awk -v days="${days}" '
- function date_to_seconds(date) {
- cmd = "date -d " date " +%s"
- cmd | getline
- close(cmd)
- return $0
- }
-
- function seconds_to_date(seconds) {
- cmd = "date -r " seconds " +%Y%m%d"
- cmd | getline
- close(cmd)
- return $0
- }
-
- BEGIN {
- n_days = int(days)
- n_seconds = date_to_seconds(strftime("%Y%m%d")) + \
- (n_days * 60 * 60 * 24)
- }
-
- match($0, /due:[0-9]+-[0-9]+-[0-9]+/) {
- # XXX: We mess up with getline in date_to_seconds()
- # XXX: so backup the current line.
- s = $0
-
- # Delete "due:" and convert the date in %Y%m%d format
- due_date = substr(s, RSTART + 4, RLENGTH - 4)
- gsub(/\-/, "", due_date)
-
- if (n_seconds >= date_to_seconds(due_date)) {
- print s
- }
- }
- '
-}
-
-
-#
-# t, a todo.sh clone in POSIX shell script
-#
-main()
-{
- subcommand=$1
-
- case $subcommand in
- a|add)
- entry=$2
- add "${todo_file}" "${entry}"
- ;;
- d|do|done)
- item=$2
- mark_done "${todo_file}" "${done_file}" "${item}"
- ;;
- due)
- days=$2
- search=$3
- list "${todo_file}" "${search}" | due "${days}"
- ;;
- e|ed|edit)
- ${EDITOR} "${todo_file}"
- ;;
- h|help)
- help
- ;;
- l|ls|list)
- search=$2
- list "${todo_file}" "${search}"
- ;;
- la|lsa|listall)
- search=$2
- list "${done_file}" "${search}"
- list "${todo_file}" "${search}"
- ;;
- *)
- usage
- ;;
- esac
-
- exit 0
-}
-
-main "$@"