diff --git a/plugins/ta/LICENSE b/plugins/ta/LICENSE new file mode 100644 index 0000000..18d9835 --- /dev/null +++ b/plugins/ta/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Jorge Bucaran + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/ta/README.md b/plugins/ta/README.md new file mode 100644 index 0000000..2fc3156 --- /dev/null +++ b/plugins/ta/README.md @@ -0,0 +1,265 @@ + +

+:ledger: ta +| +Features +| +Rationale +| +Install +| +Synopsis +| +Issues +| +? +

+ +

+ +

+ + + +___ta___ is a CLI-based _to-done_ task manager. The advantage over _to-do_ lists are: + +1. You __don't__ change your routine or habits. + +2. You __don't__ need to follow a predictable workflow. + +3. You focus on completing stuff first. Log. Repeat. + +4. Tasks are [inmutable](#undoing-tasks). Like time travel. + +See [rationale](#rationale) for a more lengthy discussion. + +## Features + +

+ + + + + + + + + + + + + + + + + + + + + + + +
1. Adding Tasks2. Undoing Tasks3. Searching Tasks
4. Regex5. Navigating Tasks6. Recent Task Marker
+ +

+:arrow_up: Top

+

+ +
+ + +### Adding Tasks + + * `ta "called #mom"` + * `ta "pushed ta to #gh #projects"` + +### Undoing Tasks + +Tasks in _ta_ are, by definition, inmutable. It's like time travel. You are not allowed. + +It _is_ possible, however, to undo _only_ the most recent task: + + * `ta -u` or `ta --undo` + +> __Note__: _ta_ is a productivity tool to help you improve your workflow, but it's not a task scheduler. If you are looking for a traditional _to-do_ manager I recommend looking at [Swatto/td](https://github.com/Swatto/td). + +### Searching Tasks + +Use `-s --search ` to search for tasks tagged by ``. + + * `ta -s spanish+jul` + + List _#spanish_ tasks in July. + + * `ta -s work+opensource` + + List _#work_ __and__ _#opensource_ tasks. + + * `ta --search family+friends -n5` + + List _#family_ __and__ _#friends_ tasks. _5 max._ + +Use `--regex -s ` or `-rs ` to search by an arbitrary regular expression. + + * `ta -rs "workout|cardio|gym"` + + List __all__ _#workout_, _#cardio_ __or__ _#gym_ tasks + +### Navigating Tasks + +Simply type `ta` to display all tasks. The task at the top is the most recent one. + +The list dump is piped into [`less`](http://linux.die.net/man/1/less) so you can easily navigate up and down, run inline searches, etc. + +[See here](http://bit.ly/17qd1KM) for a full list of options. + +

+ +

+ +You can also limit the number of tasks using the `-n --number ` option. + +### Recent Tasks + +If you complete any task within ten minutes of the previously added task, the `*` marker will turn red. It's up to you to interpret that as either a good or a bad sign. + +

+:arrow_up: Top

+ +## Rationale + + In a todo-like system, each task is a promise scheduled to be fulfilled + in the future. In practice, promises can be hard to keep and prioritize. + + GTD-like methods offer good strategies to help with this, but they often + require breaking die-to-hard habits and can be too complicated for users. + + Information flux is unpredictable, and dividing how this information is + collected and processed in often overlapping stages is challenging. + + A to-done approach is not incompatible with traditional todo-lists, but + it was created in a world where todo lists are not prominent. + + The premise is, as information flow crosses over the singularity threshold, + data-collection and sorting becomes impossible and unwieldy. The contract + is to spend _less_ time prioritizing and concentrate in completing only _one_ + task at a time. Only completed tasks can be logged into the system. + + Overall happiness and motivation increase will be directly proportional + to the number of completed tasks. + +

+:arrow_up: Top

+ +## Install + +### Fish + +#### _Oh-my-fish_ +Add the `ta` plugin to `$fish_plugins` via `~/.config/fish` or from your prompt: +```fish +set -g fish_plugins $fish_plugins ta +``` + +#### _Standalone_ + +Trust me and run: +```fish +curl -L http://git.io/install-ta | fish +ta "just installed #ta #right-move" +``` +or if you are so inclined have a look at [`tools/install`](tools/install) + +You can also specify the installation path: + +```fish +curl -L http://git.io/install-ta | env INSTALL_PATH="to/your/path/" fish +ta "just installed #ta #right-move" +``` + +#### Uninstall + +```fish +fish $ta_path/tools/uninstall +``` + +

+:arrow_up: Top

+ +## Synopsis + +``` +ta [] + [-u --undo] + [-s --search ] + [-r --regex] + [-n --number ] + [-h --help] + [--version] +``` + +### ta _task_ + +Add a completed task. Append a :hash: to keywords to apply tags. + +Simply run `ta` without arguments to list all completed tasks. + +### -s --search _key_[, ...] +Search tasks tagged by _key_. + +Use `+` to search tasks with all the specified tags. + +Use the `-r` option and concatenate keys with `|` to search for all tasks with any of the specified tags. + +#### Special Tags + +The following tags are never displayed in results, but available to use in search queries: + +* Weekdays: `mon...sun` +* Month: `jan...dec` +* Day: `1st, 2nd, 3rd, 4th...31st` +* Time: `12am...12pm` + +> __Note__: These tags are added automatically to each task depending on the current time and date. + +### -r --regex +Use together with `-s` and evaluate _key_ as a regular expression. + +### -n --number _N_ + +Truncate number of results to _N_. + +### -u --undo + +Delete most recent task. + +> __Note__: Using this option locks the ability to undo until a new task is committed protecting users from engaging in useless housekeeping habits. + +### -h --help + +Show usage help. + +### --version + +Show version information and trivia info. + +

+:arrow_up: Top

+ +## Issues + +I welcome your [feedback, comments, opinions, bug reports](https://github.com/bucaran/ta/issues) and/or [PR](https://github.com/bucaran/ta/issues)s. Thanks. + + +## About + + If you are curious, ___ta___ or rather __た__, is a conjugation / deflection used in + Japanese to indicate the completion of an action ([perfective aspect](http://en.wikipedia.org/wiki/Perfective_aspect)), roughly corresponding + to the past tense in western languages. + +

+:arrow_up: Top

+ +## License + +[MIT](http://opensource.org/licenses/MIT) :heart: [Jorge Bucaran](https://github.com/bucaran) diff --git a/plugins/ta/cli/ta.cli.clear.fish b/plugins/ta/cli/ta.cli.clear.fish new file mode 100644 index 0000000..680a053 --- /dev/null +++ b/plugins/ta/cli/ta.cli.clear.fish @@ -0,0 +1,20 @@ +function ta.cli.clear + set -l bright_color (set_color FF1493) + set -l normal_color (set_color normal) + + set -l question "[$bright_color"Y"$normal_color/n]" + + if not test -e $__ta_file_data + echo "Nothing to clear." + return $__ta_error_no_tasks + end + + echo -n "Delete all data? $question: " + + head -n 1 | read answer + switch $answer + case Y yes + rm $__ta_file_data + echo "Done" + end +end diff --git a/plugins/ta/cli/ta.cli.commit.fish b/plugins/ta/cli/ta.cli.commit.fish new file mode 100644 index 0000000..8ad982c --- /dev/null +++ b/plugins/ta/cli/ta.cli.commit.fish @@ -0,0 +1,20 @@ +function ta.cli.commit -a task + # We delay the elapsed counter until the first task is committed. + set -q __ta_elapsed + or set -g __ta_elapsed (date "+%s") + + set -l now (date "+%s") + set __ta_delta (math $now - $__ta_elapsed) + set __ta_elapsed $now + + set -l meta (ta.util.tags.get.meta) + # Trim extra whitespace and save file. + echo -se (echo "$task" \ + | tr -s '[:space:]' ' ')\t"$meta" >> $__ta_file_data + + if test $status -eq 0 + ta.cli.search "" | head -n2 + # Unlock undo stack. + set __ta_undo_lock false + end +end diff --git a/plugins/ta/cli/ta.cli.help.fish b/plugins/ta/cli/ta.cli.help.fish new file mode 100644 index 0000000..52c45e6 --- /dev/null +++ b/plugins/ta/cli/ta.cli.help.fish @@ -0,0 +1,13 @@ +function ta.cli.help + echo " + USAGE + ta [] + [-u --undo] + [-s --search ] + [-r --regex] + [-n --number ] + [-h --help] + [--clear] + [--version] +" +end diff --git a/plugins/ta/cli/ta.cli.search.fish b/plugins/ta/cli/ta.cli.search.fish new file mode 100644 index 0000000..7621373 --- /dev/null +++ b/plugins/ta/cli/ta.cli.search.fish @@ -0,0 +1,82 @@ +function ta.cli.search -a keys number + if not test -e $__ta_file_data + echo "There are no tasks." + return $__ta_error_no_tasks + end + + set -l result + set -l flags + set -q argv[3] + and set flags $argv[3..-1] + + # UI colors. + set -l tag_color "1;93" + set -l grep_color "0;103;1;90" + set -l text_color (set_color 777) + set -l query_color (set_color FF1493) + set -l normal_color (set_color normal) + + if test -n "$number" + # Truncate results via tail -n$number + set number "n$number" + end + + if contains -- regex $flags + set result (env GREP_COLOR="$grep_color" \ + grep --color=always -E "$keys" $__ta_file_data) + else + set result (cat $__ta_file_data) + if test -n "$keys" + for key in (echo "$keys" | tr + \n) + # grep results consecutively to produce an AND operator. + # Notice we append a `#' to the $key to filter only tags. + set result (printf "%s\n" $result | grep "#$key") + end + end + end + + if test -z "$result" + echo "Nothing to see here." + return $__ta_error_no_tasks + end + + # Trim special flags, print results in reverse and color #tags. + if set result (printf "%s\n" $result \ + | cut -d\t -f1 | tail -r"$number" \ + | ta.util.color.tags $tag_color) + # Append |$ at the end of the tag regex to make sure grep prints all + # incoming lines from the tail pipe, but colors only tags. $ matches + # the end of all lines but has nothing to colorize. + + set -l count (count $result) + + set -l s # Plural? + test $count -gt 1; and set s "s" + + # If both keys and number are empty just print tasks. + if test -z "$keys" -a -z "$number" + # set count (ta.util.tasks.count) + echo $text_color"$count task$s completed."$normal_color + + if test $count -gt 0 + set -l mark_color (set_color blue) + # Task marker is red if the task was completed within 10 mins. + if test $__ta_delta -gt 0 -a $__ta_delta -lt 600 + set mark_color (set_color red) + end + echo -n $mark_color\* $normal_color + end + else + if test -n "$keys" + echo /$query_color"$keys"$normal_color/ | begin + # Only for tag search, colorize `+' characters for love. + if not contains -- regex $keys + sed "s/+/$normal_color+$query_color/g" + end + end + end + echo $text_color"$count result$s."$normal_color + end + printf "%s\n" $result + end +end diff --git a/plugins/ta/cli/ta.cli.undo.fish b/plugins/ta/cli/ta.cli.undo.fish new file mode 100644 index 0000000..96dd574 --- /dev/null +++ b/plugins/ta/cli/ta.cli.undo.fish @@ -0,0 +1,21 @@ +function ta.cli.undo + if test $__ta_undo_lock = false + if test (ta.util.tasks.count) -gt 0 + # Display task for the last time. + ta.util.get.tail | grep -E --color=always ".*" + + if sed -Ei.bak '$ d' $__ta_file_data + rm $__ta_file_data.bak + else + set -l code $status + cp $__ta_file_data.bak $__ta_file_data + return $code + end + set -g __ta_undo_lock true + else + echo "There are no tasks." + return $__ta_error_no_tasks + end + end + echo "The undo stack is locked until a new task is added." +end diff --git a/plugins/ta/cli/ta.cli.version.fish b/plugins/ta/cli/ta.cli.version.fish new file mode 100644 index 0000000..2b2c2e9 --- /dev/null +++ b/plugins/ta/cli/ta.cli.version.fish @@ -0,0 +1,15 @@ +function ta.cli.version + set -l name (ta.util.tafile.get.key name) + set -l tagline (ta.util.tafile.get.key tagline) + set -l ver (ta.util.tafile.get.key version) + + echo $name - (set_color yellow)$tagline(set_color normal) $ver + + echo -s (set_color 777)" + If you are curious, ta or rather た, is a particle / deflection used in + Japanese to indicate the completion of an action, roughly corresponding + to the past tense in some western languages. + "(set_color normal)\ + " + Now go get some stuff done!" +end diff --git a/plugins/ta/config/tafile b/plugins/ta/config/tafile new file mode 100644 index 0000000..a216aae --- /dev/null +++ b/plugins/ta/config/tafile @@ -0,0 +1,3 @@ +name,ta +tagline,to-done manager +version,1.0 diff --git a/plugins/ta/images/add.png b/plugins/ta/images/add.png new file mode 100644 index 0000000..c64f15a Binary files /dev/null and b/plugins/ta/images/add.png differ diff --git a/plugins/ta/images/full-list.png b/plugins/ta/images/full-list.png new file mode 100644 index 0000000..402bad3 Binary files /dev/null and b/plugins/ta/images/full-list.png differ diff --git a/plugins/ta/images/list.png b/plugins/ta/images/list.png new file mode 100644 index 0000000..0ed096d Binary files /dev/null and b/plugins/ta/images/list.png differ diff --git a/plugins/ta/images/recent.png b/plugins/ta/images/recent.png new file mode 100644 index 0000000..2325c31 Binary files /dev/null and b/plugins/ta/images/recent.png differ diff --git a/plugins/ta/images/regex.png b/plugins/ta/images/regex.png new file mode 100644 index 0000000..773bebb Binary files /dev/null and b/plugins/ta/images/regex.png differ diff --git a/plugins/ta/images/ta.png b/plugins/ta/images/ta.png new file mode 100644 index 0000000..bbc4339 Binary files /dev/null and b/plugins/ta/images/ta.png differ diff --git a/plugins/ta/images/tags.png b/plugins/ta/images/tags.png new file mode 100644 index 0000000..6c27ac8 Binary files /dev/null and b/plugins/ta/images/tags.png differ diff --git a/plugins/ta/images/undo.png b/plugins/ta/images/undo.png new file mode 100644 index 0000000..fe5d094 Binary files /dev/null and b/plugins/ta/images/undo.png differ diff --git a/plugins/ta/spec/ta.spec.fish b/plugins/ta/spec/ta.spec.fish new file mode 100644 index 0000000..5461901 --- /dev/null +++ b/plugins/ta/spec/ta.spec.fish @@ -0,0 +1,16 @@ +import plugins/fish-spec +import plugins/ta + +function describe_ta -d "ta: to-done task manager" + function before_all + end + + function after_all + end + + # function it_does_something + # end + +end + +spec.run $argv diff --git a/plugins/ta/ta.fish b/plugins/ta/ta.fish new file mode 100644 index 0000000..c810c53 --- /dev/null +++ b/plugins/ta/ta.fish @@ -0,0 +1,143 @@ +# NAME +# ta - to-done manager +# +# SYNOPSIS +# ta [] +# [-u --undo] +# [-s --search ] +# [-r --regex] +# [-n --number ] +# [-h --help] +# [--clear] +# [--version] +# +# USAGE +# [] +# Add new completed task. Append a `#' to keywords to apply tags. +# Simply run ta without arguments to list all completed tasks. +# +# -s --search +# Search tasks tagged by . Use `+' to search tasks with all +# the specified tags. Use -r and `|' to search for tasks with at +# least one of the specified tags +# +# Some tags are automatically created based in the current date: +# +# Weekdays mon...sun +# Month jan...dec +# Day 1st, 2nd, 3rd, 4th...31st +# Time 12am...12pm +# +# -r --regex {-s} +# Use as a regular expression. +# +# -n --number +# Truncate results to . +# +# -u --undo +# Delete most recent task. Using this option locks the ability to undo +# until a new task is committed. This protects users from engaging in +# useless housekeeping habits. +# +# -h --help +# Show usage help. +# +# --clear +# Clear all data. Use with caution. +# +# --version +# Show version information. +# +# EXAMPLES +# Add a task. +# ta "talked to #mom #family" +# +# List all `spanish` tasks in July. +# ta -s spanish+jul +# +# List all `work` AND `opensource` tasks. +# ta -s work+opensource +# +# List all `workout` OR `cardio` OR `gym` tasks. +# ta -rs workout\|cardio\|gym +# +# List all `family` AND `friends` tasks. Show 5 most recent. +# ta --search family+friends -n5 +# +# DESCRIPTION +# In a todo-like system, each task is a promise scheduled to be fullfilled +# in the future. In practice, promises can be hard to keep and prioritize. +# +# GTD-like methods offer good strategies to help with this, but they often +# require breaking die-to-hard habits and can be too complicated for users. +# +# Information flux is unpredictable, and dividing how this information is +# collected and processed in often overlapping stages is challenging. +# +# A to-done approach is not incompatible with traditional todo-lists, but +# it was created in a world where todo lists are not prominent. +# +# The premise is as information flow crosses over the singularity threshold +# data-collection and sorting becomes impossible and unwieldy. The contract +# is to spend less time prioritizing and concentrate in completing only one +# task at a time. Only completed tasks can be logged into the system. +# +# Overall happiness and motivation increase will be directly proportional +# to the number of completed tasks. +# +# AUTHORS +# Jorge Bucaran +#/ +function ta -d "to-done manager" + set -l flags + + while set opts (getopts ":s:search: n:number: r:regex + u:undo h:help clear version" $argv) + switch $opts[1] + case s n + set flags $flags search + if test $opts[1] = n + set number $opts[2] + else + set search $opts[2] + end + case r + set flags $flags regex + case u + set flags undo + case h + set flags help + case clear + set flags clear + case version + set flags version + end + end + + if test $status -gt 1 + ta.cli.help + return $__ta_error_bad_input + + else if contains -- undo $flags + ta.cli.undo + + else if contains -- search $flags + # Pipe to less with color, left-width and verbose status bar. + ta.cli.search "$search" "$number" $flags \ + | less -JM --raw-control-chars + + else if contains -- version $flags + ta.cli.version + + else if contains -- clear $flags + ta.cli.clear + + else if test -n "$opts" + ta.cli.commit "$opts" + + else if contains -- help $flags + ta.cli.help + else + ta --search "" + end +end diff --git a/plugins/ta/ta.load b/plugins/ta/ta.load new file mode 100644 index 0000000..e0b3894 --- /dev/null +++ b/plugins/ta/ta.load @@ -0,0 +1,46 @@ +set -g __ta_error 1 +set -g __ta_error_bad_input 2 +set -g __ta_error_no_tasks 3 + +# Standalone installation. +if set -q ta_path + for file in $ta_path/** + switch $file + case \*.fish + set -l dir (dirname $file) + # Skip completions and spec directories. + if test (basename $dir) != "completions" -a \ + (basename $dir) != "spec" + if not contains -- "$dir" $fish_function_path + set fish_function_path "$dir" $fish_function_path + end + end + end + end + +# Oh-my-fish installation. +else if set -q fish_path + set -g ta_path $fish_path/plugins/ta + # Oh-my-fish lets you import modules easily. For standalone fish + # installations, fish getopts is already included in the path. + import plugins/getopts +else + # Neither $INSTALL_PATH or $fish_path exists. + echo "Please review the installation instructions and try again." ^&2 + exit $__ta_error +end + +set -g __ta_file_info $ta_path/config/tafile +set -g __ta_file_data $ta_path/data/tasks + +# Regular expression used to extract tags from tasks. +set -g __ta_regex "#\S*" + +# Seconds elapsed between last and current task to commit. +set -g __ta_delta 0 + +# Flag to track whether the undo stack is locked. Tasks are usually +# inmutable except for the most recent task to allow simple mistake +# correction. +set -q __ta_undo_lock + or set -g __ta_undo_lock false diff --git a/plugins/ta/util/ta.util.color.tags.fish b/plugins/ta/util/ta.util.color.tags.fish new file mode 100644 index 0000000..8e69d7c --- /dev/null +++ b/plugins/ta/util/ta.util.color.tags.fish @@ -0,0 +1,3 @@ +function ta.util.color.tags -a color + env GREP_COLOR="$color" grep --color=always -E "$__ta_regex|\$" +end diff --git a/plugins/ta/util/ta.util.get.tail.fish b/plugins/ta/util/ta.util.get.tail.fish new file mode 100644 index 0000000..97792f5 --- /dev/null +++ b/plugins/ta/util/ta.util.get.tail.fish @@ -0,0 +1,4 @@ +function ta.util.get.tail + tail -rn1 $__ta_file_data \ + | cut -f1 +end diff --git a/plugins/ta/util/ta.util.tafile.get.key.fish b/plugins/ta/util/ta.util.tafile.get.key.fish new file mode 100644 index 0000000..9ea1aa2 --- /dev/null +++ b/plugins/ta/util/ta.util.tafile.get.key.fish @@ -0,0 +1,3 @@ +function ta.util.tafile.get.key -a key + grep -E "\b$key\b" $__ta_file_info | cut -d, -f2 +end diff --git a/plugins/ta/util/ta.util.tags.get.fish b/plugins/ta/util/ta.util.tags.get.fish new file mode 100644 index 0000000..c67563e --- /dev/null +++ b/plugins/ta/util/ta.util.tags.get.fish @@ -0,0 +1,3 @@ +function ta.util.tags.get -a task + echo "$task" | tr -s "[:space:]" \n | grep -Eo "$__ta_regex" | cut -c2- +end diff --git a/plugins/ta/util/ta.util.tags.get.meta.fish b/plugins/ta/util/ta.util.tags.get.meta.fish new file mode 100644 index 0000000..6e835bf --- /dev/null +++ b/plugins/ta/util/ta.util.tags.get.meta.fish @@ -0,0 +1,20 @@ +function ta.util.tags.get.meta + set -l week (date +%a) + set -l day (date +%d) + switch $day + case 1 21 31 + set $day "$day"st + case 2 22 + set $day "$day"nd + case 3 23 + set $day "$day"rd + case \* + set $day "$day"th + end + set -l month (date +%b) + set -l year (date +%Y) + set -l hour (date "+%r" | \ + sed -E "s/0?([1-9][0-9]?).*(..)/\1\2/") + + printf "#%s " $week $day $month $year $hour | awk '{print tolower}' +end diff --git a/plugins/ta/util/ta.util.tasks.count.fish b/plugins/ta/util/ta.util.tasks.count.fish new file mode 100644 index 0000000..14f7b1e --- /dev/null +++ b/plugins/ta/util/ta.util.tasks.count.fish @@ -0,0 +1,3 @@ +function ta.util.tasks.count + wc -l < $__ta_file_data | awk '{print $1}' +end