ta-to-done 📒

pull/2/head
Jorge Bucaran 10 years ago committed by Jorge
parent 1007fe511f
commit c6bc4fdcd8

@ -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.

@ -0,0 +1,265 @@
<a name="ta"></a><em>
<p align="center">
:ledger: <b>ta</b>
|
<b><a href="#features">Features</a></b>
|
<b><a href="#rationale">Rationale</a></b>
|
<b><a href="#install">Install</a></b>
|
<b><a href="#synopsis">Synopsis</a></b>
|
<b><a href="#issues">Issues</a></b>
|
<b><a href="#about">?</a></b>
</p>
<p align="center">
<img width=65% height=65% src ="images/ta.png">
</p>
___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.
## <a name="features">Features</a>
<p align="center">
<table>
<tr>
<tr>
<th>1. <a href="#adding-tasks">Adding Tasks</a></th>
<th>2. <a href="#undoing-tasks">Undoing Tasks</a></th>
<th>3. <a href="#searching-tasks">Searching Tasks</a></th>
</tr>
<tr>
<td><img src="images/add.png"></td>
<td><img src="images/undo.png"></td>
<td><img src="images/tags.png"></td>
</tr>
</tr>
<tr>
<th>4. <a href="#searching-tasks">Regex</a></th>
<th>5. <a href="#navigating-tasks">Navigating Tasks</a></th>
<th>6. <a href="#recent-tasks">Recent Task Marker</a></th>
<tr>
<td><img src="images/regex.png"></td>
<td><img src="images/list.png"></td>
<td><img src="images/recent.png"></td>
</tr>
</tr>
</table>
<p align="right">
<a href="#ta">:arrow_up:</a> <a href="#ta">Top</a></p>
</p>
<hr>
### <a name="adding-tasks">Adding Tasks</a>
* `ta "called #mom"`
* `ta "pushed ta to #gh #projects"`
### <a name="undoing-tasks">Undoing Tasks</a>
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).
### <a name="searching-tasks">Searching Tasks</a>
Use `-s --search <tag>` to search for tasks tagged by `<tag>`.
* `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 <query>` or `-rs <query>` to search by an arbitrary regular expression.
* `ta -rs "workout|cardio|gym"`
List __all__ _#workout_, _#cardio_ __or__ _#gym_ tasks
### <a name="navigating-tasks">Navigating Tasks</a>
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.
<p align="center">
<img width=80% height=80% src ="images/full-list.png">
</p>
You can also limit the number of tasks using the `-n --number <number>` option.
### <a name="recent-tasks">Recent Tasks</a>
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.
<p align="right">
<a href="#ta">:arrow_up:</a> <a href="#ta">Top</a></p>
## <a name="rationale">Rationale</a>
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.
<p align="right">
<a href="#ta">:arrow_up:</a> <a href="#ta">Top</a></p>
## <a name="install">Install</a>
### 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"
```
#### <a name="uninstall"></a> Uninstall
```fish
fish $ta_path/tools/uninstall
```
<p align="right">
<a href="#ta">:arrow_up:</a> <a href="#ta">Top</a></p>
## <a name="synopsis">Synopsis</a>
```
ta [<task #tag1 #tag2...">]
[-u --undo]
[-s --search <key[+key...]>]
[-r --regex]
[-n --number <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.
<p align="right">
<a href="#ta">:arrow_up:</a> <a href="#ta">Top</a></p>
## <a name="issues">Issues</a>
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.
## <a name="about">About</a>
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.
<p align="right">
<a href="#ta">:arrow_up:</a> <a href="#ta">Top</a></p>
## <a name="license">License</a>
[MIT](http://opensource.org/licenses/MIT) :heart: [Jorge Bucaran](https://github.com/bucaran)

@ -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

@ -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

@ -0,0 +1,13 @@
function ta.cli.help
echo "
USAGE
ta [<task #tag #tag...>]
[-u --undo]
[-s --search <key[+key...]>]
[-r --regex]
[-n --number <number>]
[-h --help]
[--clear]
[--version]
"
end

@ -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

@ -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

@ -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

@ -0,0 +1,3 @@
name,ta
tagline,to-done manager
version,1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -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

@ -0,0 +1,143 @@
# NAME
# ta - to-done manager
#
# SYNOPSIS
# ta [<task #tag #tag...>]
# [-u --undo]
# [-s --search <key[+key...]>]
# [-r --regex]
# [-n --number <number>]
# [-h --help]
# [--clear]
# [--version]
#
# USAGE
# [<task>]
# Add new completed task. Append a `#' 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 -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<key>}
# Use <key> as a regular expression.
#
# -n --number <number>
# Truncate results to <number>.
#
# -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 <jbucaran@me.com>
#/
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

@ -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

@ -0,0 +1,3 @@
function ta.util.color.tags -a color
env GREP_COLOR="$color" grep --color=always -E "$__ta_regex|\$"
end

@ -0,0 +1,4 @@
function ta.util.get.tail
tail -rn1 $__ta_file_data \
| cut -f1
end

@ -0,0 +1,3 @@
function ta.util.tafile.get.key -a key
grep -E "\b$key\b" $__ta_file_info | cut -d, -f2
end

@ -0,0 +1,3 @@
function ta.util.tags.get -a task
echo "$task" | tr -s "[:space:]" \n | grep -Eo "$__ta_regex" | cut -c2-
end

@ -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

@ -0,0 +1,3 @@
function ta.util.tasks.count
wc -l < $__ta_file_data | awk '{print $1}'
end
Loading…
Cancel
Save