Compare commits
72 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4cb9f76cd | ||
|
|
511bd5889c | ||
|
|
84a045378d | ||
|
|
833cfccbb7 | ||
|
|
e8b4f6ef82 | ||
|
|
8ea6d011d1 | ||
|
|
87a5f669c0 | ||
|
|
a699492284 | ||
|
|
0e54c74655 | ||
|
|
3c7c46aada | ||
|
|
fe3cd3aa0f | ||
|
|
ecbe1cfa53 | ||
|
|
8d7e9d98d6 | ||
|
|
465fe7a66a | ||
|
|
47faac3f09 | ||
|
|
953af37e9d | ||
|
|
09cf2a80d7 | ||
|
|
b6af2d734c | ||
|
|
df351de096 | ||
|
|
a92d353e59 | ||
|
|
fb5ae311d1 | ||
|
|
2c0da605d8 | ||
|
|
7bde7c38d8 | ||
|
|
d625c9a98d | ||
|
|
286954a6e7 | ||
|
|
3884183dce | ||
|
|
e9276f6292 | ||
|
|
544d0a7dc3 | ||
|
|
806588a6ef | ||
|
|
ef0b16082d | ||
|
|
1d392ea69e | ||
|
|
8260e9c61e | ||
|
|
be548ad9fd | ||
|
|
1a57540166 | ||
|
|
32a3023dfd | ||
|
|
2223e44a2c | ||
|
|
7b32458e92 | ||
|
|
7a10cfe303 | ||
|
|
b08c2eb2e6 | ||
|
|
1178967c83 | ||
|
|
20bbe987fb | ||
|
|
4d965564e4 | ||
|
|
a896042fdd | ||
|
|
a353f9eae7 | ||
|
|
98dd82d000 | ||
|
|
e84e6d9740 | ||
|
|
5dc7443b15 | ||
|
|
3826504d22 | ||
|
|
a011c568dd | ||
|
|
f5e43fad82 | ||
|
|
3d1a7489be | ||
|
|
40fd3b83ad | ||
|
|
eba40f37a3 | ||
|
|
c2c8cce495 | ||
|
|
c27456a45f | ||
|
|
b81bf08d56 | ||
|
|
aabab86ddc | ||
|
|
c67da82b54 | ||
|
|
cb170f4b0e | ||
|
|
77ef1c64ae | ||
|
|
7a662d5cda | ||
|
|
8dfd0f956d | ||
|
|
c90c2de9c3 | ||
|
|
123f25caee | ||
|
|
f1ca022fc5 | ||
|
|
2785fb8e49 | ||
|
|
c998eb4539 | ||
|
|
65b809eae9 | ||
|
|
f91d9d87b6 | ||
|
|
86277ec66d | ||
|
|
f8cc2139cd | ||
|
|
95fd1aa1ef |
1
.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
VERSION-FILE
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Based on git's GIT-VERSION-GEN.
|
|
||||||
|
|
||||||
VF=VERSION-FILE
|
|
||||||
DEF_VER=v2.2
|
|
||||||
|
|
||||||
LF='
|
|
||||||
'
|
|
||||||
|
|
||||||
if test -d .git -o -f .git &&
|
|
||||||
VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
|
|
||||||
case "$VN" in
|
|
||||||
*$LF*) (exit 1) ;;
|
|
||||||
v[0-9]*)
|
|
||||||
git update-index -q --refresh
|
|
||||||
test -z "$(git diff-index --name-only HEAD --)" ||
|
|
||||||
VN="$VN-dirty" ;;
|
|
||||||
esac
|
|
||||||
then
|
|
||||||
VN=$(echo "$VN" | sed -e 's/-/./g');
|
|
||||||
else
|
|
||||||
VN="$DEF_VER"
|
|
||||||
fi
|
|
||||||
|
|
||||||
VN=$(expr "$VN" : v*'\(.*\)')
|
|
||||||
|
|
||||||
if test -r $VF
|
|
||||||
then
|
|
||||||
VC=$(sed -e 's/^VERSION=//' <$VF)
|
|
||||||
else
|
|
||||||
VC=unset
|
|
||||||
fi
|
|
||||||
test "$VN" = "$VC" || {
|
|
||||||
echo >&2 "VERSION=$VN"
|
|
||||||
echo "VERSION=$VN" >$VF
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
34
Makefile
@@ -1,34 +0,0 @@
|
|||||||
#
|
|
||||||
# Makefile for todo.txt
|
|
||||||
#
|
|
||||||
|
|
||||||
# Dynamically detect/generate version file as necessary
|
|
||||||
# This file will define a variable called VERSION.
|
|
||||||
.PHONY: .FORCE-VERSION-FILE
|
|
||||||
VERSION-FILE: .FORCE-VERSION-FILE
|
|
||||||
@./GEN-VERSION-FILE
|
|
||||||
-include VERSION-FILE
|
|
||||||
|
|
||||||
# Maybe this will include the version in it.
|
|
||||||
todo.sh: VERSION-FILE
|
|
||||||
|
|
||||||
# For packaging
|
|
||||||
DISTFILES := todo.cfg
|
|
||||||
|
|
||||||
DISTNAME=todo.txt_cli-$(VERSION)
|
|
||||||
dist: $(DISTFILES) todo.sh
|
|
||||||
mkdir -p $(DISTNAME)
|
|
||||||
cp -f $(DISTFILES) $(DISTNAME)/
|
|
||||||
sed -e 's/@DEV_VERSION@/'$(VERSION)'/' todo.sh > $(DISTNAME)/todo.sh
|
|
||||||
tar cf $(DISTNAME).tar $(DISTNAME)/
|
|
||||||
gzip -f -9 $(DISTNAME).tar
|
|
||||||
zip -9r $(DISTNAME).zip $(DISTNAME)/
|
|
||||||
rm -r $(DISTNAME)
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
rm -f $(DISTNAME).tar.gz $(DISTNAME).zip
|
|
||||||
|
|
||||||
.PHONY: test
|
|
||||||
test:
|
|
||||||
@echo "TBD!"
|
|
||||||
8
README
@@ -1,8 +0,0 @@
|
|||||||
TODO.TXT Command Line Interface
|
|
||||||
Latest version: http://github.com/ginatrapani/todo.txt-cli/tree/master
|
|
||||||
First release: 5/11/2006
|
|
||||||
Conceived and released by: Gina Trapani (http://ginatrapani.org)
|
|
||||||
Contributors: http://github.com/ginatrapani/todo.txt-cli/network
|
|
||||||
License: GPL, http://www.gnu.org/copyleft/gpl.html
|
|
||||||
More information and mailing list at http://todotxt.com
|
|
||||||
To submit patches, fork the repository at http://github.com/ginatrapani/todo.txt-cli/tree/master
|
|
||||||
686
css/bootstrap-responsive.css
vendored
Normal file
@@ -0,0 +1,686 @@
|
|||||||
|
/*!
|
||||||
|
* Bootstrap Responsive v2.0.2
|
||||||
|
*
|
||||||
|
* Copyright 2012 Twitter, Inc
|
||||||
|
* Licensed under the Apache License v2.0
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Designed and built with all the love in the world @twitter by @mdo and @fat.
|
||||||
|
*/
|
||||||
|
.clearfix {
|
||||||
|
*zoom: 1;
|
||||||
|
}
|
||||||
|
.clearfix:before,
|
||||||
|
.clearfix:after {
|
||||||
|
display: table;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
.clearfix:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
.hide-text {
|
||||||
|
overflow: hidden;
|
||||||
|
text-indent: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.input-block-level {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 28px;
|
||||||
|
/* Make inputs at least the height of their button counterpart */
|
||||||
|
|
||||||
|
/* Makes inputs behave like true block-level elements */
|
||||||
|
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-ms-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.visible-phone {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.visible-tablet {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.visible-desktop {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.hidden-phone {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.hidden-tablet {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.hidden-desktop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.visible-phone {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.hidden-phone {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.hidden-desktop {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.visible-desktop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) and (max-width: 979px) {
|
||||||
|
.visible-tablet {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.hidden-tablet {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.hidden-desktop {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.visible-desktop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.nav-collapse {
|
||||||
|
-webkit-transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
.page-header h1 small {
|
||||||
|
display: block;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
input[type="checkbox"],
|
||||||
|
input[type="radio"] {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
.form-horizontal .control-group > label {
|
||||||
|
float: none;
|
||||||
|
width: auto;
|
||||||
|
padding-top: 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.form-horizontal .controls {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.form-horizontal .control-list {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
.form-horizontal .form-actions {
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
.modal {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: 10px;
|
||||||
|
right: 10px;
|
||||||
|
width: auto;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.modal.fade.in {
|
||||||
|
top: auto;
|
||||||
|
}
|
||||||
|
.modal-header .close {
|
||||||
|
padding: 10px;
|
||||||
|
margin: -10px;
|
||||||
|
}
|
||||||
|
.carousel-caption {
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
body {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
.navbar-fixed-top {
|
||||||
|
margin-left: -20px;
|
||||||
|
margin-right: -20px;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
.row-fluid {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.row > [class*="span"],
|
||||||
|
.row-fluid > [class*="span"] {
|
||||||
|
float: none;
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.thumbnails [class*="span"] {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
input[class*="span"],
|
||||||
|
select[class*="span"],
|
||||||
|
textarea[class*="span"],
|
||||||
|
.uneditable-input {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 28px;
|
||||||
|
/* Make inputs at least the height of their button counterpart */
|
||||||
|
|
||||||
|
/* Makes inputs behave like true block-level elements */
|
||||||
|
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-ms-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.input-prepend input[class*="span"],
|
||||||
|
.input-append input[class*="span"] {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) and (max-width: 979px) {
|
||||||
|
.row {
|
||||||
|
margin-left: -20px;
|
||||||
|
*zoom: 1;
|
||||||
|
}
|
||||||
|
.row:before,
|
||||||
|
.row:after {
|
||||||
|
display: table;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
.row:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
[class*="span"] {
|
||||||
|
float: left;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
.container,
|
||||||
|
.navbar-fixed-top .container,
|
||||||
|
.navbar-fixed-bottom .container {
|
||||||
|
width: 724px;
|
||||||
|
}
|
||||||
|
.span12 {
|
||||||
|
width: 724px;
|
||||||
|
}
|
||||||
|
.span11 {
|
||||||
|
width: 662px;
|
||||||
|
}
|
||||||
|
.span10 {
|
||||||
|
width: 600px;
|
||||||
|
}
|
||||||
|
.span9 {
|
||||||
|
width: 538px;
|
||||||
|
}
|
||||||
|
.span8 {
|
||||||
|
width: 476px;
|
||||||
|
}
|
||||||
|
.span7 {
|
||||||
|
width: 414px;
|
||||||
|
}
|
||||||
|
.span6 {
|
||||||
|
width: 352px;
|
||||||
|
}
|
||||||
|
.span5 {
|
||||||
|
width: 290px;
|
||||||
|
}
|
||||||
|
.span4 {
|
||||||
|
width: 228px;
|
||||||
|
}
|
||||||
|
.span3 {
|
||||||
|
width: 166px;
|
||||||
|
}
|
||||||
|
.span2 {
|
||||||
|
width: 104px;
|
||||||
|
}
|
||||||
|
.span1 {
|
||||||
|
width: 42px;
|
||||||
|
}
|
||||||
|
.offset12 {
|
||||||
|
margin-left: 764px;
|
||||||
|
}
|
||||||
|
.offset11 {
|
||||||
|
margin-left: 702px;
|
||||||
|
}
|
||||||
|
.offset10 {
|
||||||
|
margin-left: 640px;
|
||||||
|
}
|
||||||
|
.offset9 {
|
||||||
|
margin-left: 578px;
|
||||||
|
}
|
||||||
|
.offset8 {
|
||||||
|
margin-left: 516px;
|
||||||
|
}
|
||||||
|
.offset7 {
|
||||||
|
margin-left: 454px;
|
||||||
|
}
|
||||||
|
.offset6 {
|
||||||
|
margin-left: 392px;
|
||||||
|
}
|
||||||
|
.offset5 {
|
||||||
|
margin-left: 330px;
|
||||||
|
}
|
||||||
|
.offset4 {
|
||||||
|
margin-left: 268px;
|
||||||
|
}
|
||||||
|
.offset3 {
|
||||||
|
margin-left: 206px;
|
||||||
|
}
|
||||||
|
.offset2 {
|
||||||
|
margin-left: 144px;
|
||||||
|
}
|
||||||
|
.offset1 {
|
||||||
|
margin-left: 82px;
|
||||||
|
}
|
||||||
|
.row-fluid {
|
||||||
|
width: 100%;
|
||||||
|
*zoom: 1;
|
||||||
|
}
|
||||||
|
.row-fluid:before,
|
||||||
|
.row-fluid:after {
|
||||||
|
display: table;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
.row-fluid:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
.row-fluid > [class*="span"] {
|
||||||
|
float: left;
|
||||||
|
margin-left: 2.762430939%;
|
||||||
|
}
|
||||||
|
.row-fluid > [class*="span"]:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.row-fluid > .span12 {
|
||||||
|
width: 99.999999993%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span11 {
|
||||||
|
width: 91.436464082%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span10 {
|
||||||
|
width: 82.87292817100001%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span9 {
|
||||||
|
width: 74.30939226%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span8 {
|
||||||
|
width: 65.74585634900001%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span7 {
|
||||||
|
width: 57.182320438000005%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span6 {
|
||||||
|
width: 48.618784527%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span5 {
|
||||||
|
width: 40.055248616%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span4 {
|
||||||
|
width: 31.491712705%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span3 {
|
||||||
|
width: 22.928176794%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span2 {
|
||||||
|
width: 14.364640883%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span1 {
|
||||||
|
width: 5.801104972%;
|
||||||
|
}
|
||||||
|
input,
|
||||||
|
textarea,
|
||||||
|
.uneditable-input {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
input.span12, textarea.span12, .uneditable-input.span12 {
|
||||||
|
width: 714px;
|
||||||
|
}
|
||||||
|
input.span11, textarea.span11, .uneditable-input.span11 {
|
||||||
|
width: 652px;
|
||||||
|
}
|
||||||
|
input.span10, textarea.span10, .uneditable-input.span10 {
|
||||||
|
width: 590px;
|
||||||
|
}
|
||||||
|
input.span9, textarea.span9, .uneditable-input.span9 {
|
||||||
|
width: 528px;
|
||||||
|
}
|
||||||
|
input.span8, textarea.span8, .uneditable-input.span8 {
|
||||||
|
width: 466px;
|
||||||
|
}
|
||||||
|
input.span7, textarea.span7, .uneditable-input.span7 {
|
||||||
|
width: 404px;
|
||||||
|
}
|
||||||
|
input.span6, textarea.span6, .uneditable-input.span6 {
|
||||||
|
width: 342px;
|
||||||
|
}
|
||||||
|
input.span5, textarea.span5, .uneditable-input.span5 {
|
||||||
|
width: 280px;
|
||||||
|
}
|
||||||
|
input.span4, textarea.span4, .uneditable-input.span4 {
|
||||||
|
width: 218px;
|
||||||
|
}
|
||||||
|
input.span3, textarea.span3, .uneditable-input.span3 {
|
||||||
|
width: 156px;
|
||||||
|
}
|
||||||
|
input.span2, textarea.span2, .uneditable-input.span2 {
|
||||||
|
width: 94px;
|
||||||
|
}
|
||||||
|
input.span1, textarea.span1, .uneditable-input.span1 {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 979px) {
|
||||||
|
body {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
.navbar-fixed-top {
|
||||||
|
position: static;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
.navbar-fixed-top .navbar-inner {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
.navbar .container {
|
||||||
|
width: auto;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.navbar .brand {
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
margin: 0 0 0 -5px;
|
||||||
|
}
|
||||||
|
.navbar .nav-collapse {
|
||||||
|
clear: left;
|
||||||
|
}
|
||||||
|
.navbar .nav {
|
||||||
|
float: none;
|
||||||
|
margin: 0 0 9px;
|
||||||
|
}
|
||||||
|
.navbar .nav > li {
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
.navbar .nav > li > a {
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
.navbar .nav > .divider-vertical {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.navbar .nav .nav-header {
|
||||||
|
color: #999999;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
.navbar .nav > li > a,
|
||||||
|
.navbar .dropdown-menu a {
|
||||||
|
padding: 6px 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #999999;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.navbar .dropdown-menu li + li a {
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
.navbar .nav > li > a:hover,
|
||||||
|
.navbar .dropdown-menu a:hover {
|
||||||
|
background-color: #222222;
|
||||||
|
}
|
||||||
|
.navbar .dropdown-menu {
|
||||||
|
position: static;
|
||||||
|
top: auto;
|
||||||
|
left: auto;
|
||||||
|
float: none;
|
||||||
|
display: block;
|
||||||
|
max-width: none;
|
||||||
|
margin: 0 15px;
|
||||||
|
padding: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
-webkit-border-radius: 0;
|
||||||
|
-moz-border-radius: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
-moz-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.navbar .dropdown-menu:before,
|
||||||
|
.navbar .dropdown-menu:after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.navbar .dropdown-menu .divider {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.navbar-form,
|
||||||
|
.navbar-search {
|
||||||
|
float: none;
|
||||||
|
padding: 9px 15px;
|
||||||
|
margin: 9px 0;
|
||||||
|
border-top: 1px solid #222222;
|
||||||
|
border-bottom: 1px solid #222222;
|
||||||
|
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||||
|
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
.navbar .nav.pull-right {
|
||||||
|
float: none;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.navbar-static .navbar-inner {
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
.btn-navbar {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.nav-collapse {
|
||||||
|
overflow: hidden;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 980px) {
|
||||||
|
.nav-collapse.collapse {
|
||||||
|
height: auto !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
.row {
|
||||||
|
margin-left: -30px;
|
||||||
|
*zoom: 1;
|
||||||
|
}
|
||||||
|
.row:before,
|
||||||
|
.row:after {
|
||||||
|
display: table;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
.row:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
[class*="span"] {
|
||||||
|
float: left;
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
.container,
|
||||||
|
.navbar-fixed-top .container,
|
||||||
|
.navbar-fixed-bottom .container {
|
||||||
|
width: 1170px;
|
||||||
|
}
|
||||||
|
.span12 {
|
||||||
|
width: 1170px;
|
||||||
|
}
|
||||||
|
.span11 {
|
||||||
|
width: 1070px;
|
||||||
|
}
|
||||||
|
.span10 {
|
||||||
|
width: 970px;
|
||||||
|
}
|
||||||
|
.span9 {
|
||||||
|
width: 870px;
|
||||||
|
}
|
||||||
|
.span8 {
|
||||||
|
width: 770px;
|
||||||
|
}
|
||||||
|
.span7 {
|
||||||
|
width: 670px;
|
||||||
|
}
|
||||||
|
.span6 {
|
||||||
|
width: 570px;
|
||||||
|
}
|
||||||
|
.span5 {
|
||||||
|
width: 470px;
|
||||||
|
}
|
||||||
|
.span4 {
|
||||||
|
width: 370px;
|
||||||
|
}
|
||||||
|
.span3 {
|
||||||
|
width: 270px;
|
||||||
|
}
|
||||||
|
.span2 {
|
||||||
|
width: 170px;
|
||||||
|
}
|
||||||
|
.span1 {
|
||||||
|
width: 70px;
|
||||||
|
}
|
||||||
|
.offset12 {
|
||||||
|
margin-left: 1230px;
|
||||||
|
}
|
||||||
|
.offset11 {
|
||||||
|
margin-left: 1130px;
|
||||||
|
}
|
||||||
|
.offset10 {
|
||||||
|
margin-left: 1030px;
|
||||||
|
}
|
||||||
|
.offset9 {
|
||||||
|
margin-left: 930px;
|
||||||
|
}
|
||||||
|
.offset8 {
|
||||||
|
margin-left: 830px;
|
||||||
|
}
|
||||||
|
.offset7 {
|
||||||
|
margin-left: 730px;
|
||||||
|
}
|
||||||
|
.offset6 {
|
||||||
|
margin-left: 630px;
|
||||||
|
}
|
||||||
|
.offset5 {
|
||||||
|
margin-left: 530px;
|
||||||
|
}
|
||||||
|
.offset4 {
|
||||||
|
margin-left: 430px;
|
||||||
|
}
|
||||||
|
.offset3 {
|
||||||
|
margin-left: 330px;
|
||||||
|
}
|
||||||
|
.offset2 {
|
||||||
|
margin-left: 230px;
|
||||||
|
}
|
||||||
|
.offset1 {
|
||||||
|
margin-left: 130px;
|
||||||
|
}
|
||||||
|
.row-fluid {
|
||||||
|
width: 100%;
|
||||||
|
*zoom: 1;
|
||||||
|
}
|
||||||
|
.row-fluid:before,
|
||||||
|
.row-fluid:after {
|
||||||
|
display: table;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
.row-fluid:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
.row-fluid > [class*="span"] {
|
||||||
|
float: left;
|
||||||
|
margin-left: 2.564102564%;
|
||||||
|
}
|
||||||
|
.row-fluid > [class*="span"]:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.row-fluid > .span12 {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span11 {
|
||||||
|
width: 91.45299145300001%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span10 {
|
||||||
|
width: 82.905982906%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span9 {
|
||||||
|
width: 74.358974359%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span8 {
|
||||||
|
width: 65.81196581200001%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span7 {
|
||||||
|
width: 57.264957265%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span6 {
|
||||||
|
width: 48.717948718%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span5 {
|
||||||
|
width: 40.170940171000005%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span4 {
|
||||||
|
width: 31.623931624%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span3 {
|
||||||
|
width: 23.076923077%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span2 {
|
||||||
|
width: 14.529914530000001%;
|
||||||
|
}
|
||||||
|
.row-fluid > .span1 {
|
||||||
|
width: 5.982905983%;
|
||||||
|
}
|
||||||
|
input,
|
||||||
|
textarea,
|
||||||
|
.uneditable-input {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
input.span12, textarea.span12, .uneditable-input.span12 {
|
||||||
|
width: 1160px;
|
||||||
|
}
|
||||||
|
input.span11, textarea.span11, .uneditable-input.span11 {
|
||||||
|
width: 1060px;
|
||||||
|
}
|
||||||
|
input.span10, textarea.span10, .uneditable-input.span10 {
|
||||||
|
width: 960px;
|
||||||
|
}
|
||||||
|
input.span9, textarea.span9, .uneditable-input.span9 {
|
||||||
|
width: 860px;
|
||||||
|
}
|
||||||
|
input.span8, textarea.span8, .uneditable-input.span8 {
|
||||||
|
width: 760px;
|
||||||
|
}
|
||||||
|
input.span7, textarea.span7, .uneditable-input.span7 {
|
||||||
|
width: 660px;
|
||||||
|
}
|
||||||
|
input.span6, textarea.span6, .uneditable-input.span6 {
|
||||||
|
width: 560px;
|
||||||
|
}
|
||||||
|
input.span5, textarea.span5, .uneditable-input.span5 {
|
||||||
|
width: 460px;
|
||||||
|
}
|
||||||
|
input.span4, textarea.span4, .uneditable-input.span4 {
|
||||||
|
width: 360px;
|
||||||
|
}
|
||||||
|
input.span3, textarea.span3, .uneditable-input.span3 {
|
||||||
|
width: 260px;
|
||||||
|
}
|
||||||
|
input.span2, textarea.span2, .uneditable-input.span2 {
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
input.span1, textarea.span1, .uneditable-input.span1 {
|
||||||
|
width: 60px;
|
||||||
|
}
|
||||||
|
.thumbnails {
|
||||||
|
margin-left: -30px;
|
||||||
|
}
|
||||||
|
.thumbnails > li {
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
584
css/bootstrap.min.css
vendored
Normal file
126
css/style.css
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
body {
|
||||||
|
padding-top:50px;
|
||||||
|
color:#777;
|
||||||
|
background:#666;
|
||||||
|
}
|
||||||
|
body, p, li, input, button, select, textarea {
|
||||||
|
font-family:;'Open Sans', sans-serif;
|
||||||
|
}
|
||||||
|
body, p, li {
|
||||||
|
font-size:14px;
|
||||||
|
line-height:20px;
|
||||||
|
}
|
||||||
|
h1, h2, h3 {letter-spacing: -1px;}
|
||||||
|
|
||||||
|
/* Links */
|
||||||
|
a {color:#18D;}
|
||||||
|
a:hover {color:#26B;}
|
||||||
|
|
||||||
|
/* Titles */
|
||||||
|
h1 {font-family:Courier;color: #196DB5;font-size:26px;font-weight:300;text-shadow: 0 1px -1px white;}
|
||||||
|
h1 a {color:white;}
|
||||||
|
h1 a:hover {color:white;text-decoration:none;}
|
||||||
|
h2 {color: #555;font-size:22px;font-weight:300;margin-bottom:10px;text-shadow: 0 1px -1px white;}
|
||||||
|
h3 {font-weight:normal;color:#444;margin-bottom: 10px;}
|
||||||
|
h4 {color: #444;margin-bottom: 2px;margin-top:10px;line-height:20px;}
|
||||||
|
h5 {color: #444;line-height:20px;}
|
||||||
|
h6 {line-height:20px; color:#AAA;}
|
||||||
|
.bold {font-weight:bold;}
|
||||||
|
.italic {font-style:italic;}
|
||||||
|
|
||||||
|
/* Hero unit */
|
||||||
|
.hero-unit {
|
||||||
|
background:#666;
|
||||||
|
border-bottom: 1px solid white;
|
||||||
|
-webkit-border-radius: 0;
|
||||||
|
-moz-border-radius:0;
|
||||||
|
border-radius: 0;
|
||||||
|
margin: 0;
|
||||||
|
margin-top:-50px;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
.hero-unit .container {
|
||||||
|
padding: 40px 0 30px 0;
|
||||||
|
text-shadow:0 -1px 1px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-unit h1{color:#E9E9E9;font-size:40px;margin-top:12px;letter-spacing:-2px;text-shadow: 0 -1px -1px black;}
|
||||||
|
.hero-unit h2, .hero-unit h4 {color:#fff;line-height:24px;text-shadow: 0 -1px -1px black;}
|
||||||
|
.hero-unit h1 > img {vertical-align:top;}
|
||||||
|
.hero-unit ul.unstyled li {border-bottom:1px solid #000;border-top:1px solid #2B2B2B;padding:15px 0 15px 15px;}
|
||||||
|
.hero-unit ul.unstyled li:first-child {border-top:0;}
|
||||||
|
.hero-unit ul.unstyled, .hero-unit hr {border-bottom:1px solid #2B2B2B;}
|
||||||
|
.hero-unit .buttons {
|
||||||
|
margin: 10px -15px 0 -15px;
|
||||||
|
padding:20px 0;
|
||||||
|
}
|
||||||
|
.hero-unit hr {border-top:1px solid #000;}
|
||||||
|
.hero-unit .buttons a, .hero-unit iframe {vertical-align:middle;}
|
||||||
|
.hero-unit .divider-vertical {
|
||||||
|
height:20px;
|
||||||
|
width:1px;
|
||||||
|
display:inline-block;
|
||||||
|
background-color:black;
|
||||||
|
border-right:1px solid #333;
|
||||||
|
vertical-align:middle;
|
||||||
|
margin:0 6px;
|
||||||
|
}
|
||||||
|
.hero-unit .github-btn-large .gh-btn, .hero-unit .github-btn-large .gh-count {
|
||||||
|
padding: 2px 10px 2px 8px !important;
|
||||||
|
font-size: 15px !important;
|
||||||
|
}
|
||||||
|
.hero-unit .btn-large {
|
||||||
|
padding: 3px 10px 3px 6px;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
.hero-unit .stitched {
|
||||||
|
outline: 1px dashed #444;
|
||||||
|
outline-offset: -5px;
|
||||||
|
background: #2B2B2B;
|
||||||
|
border-radius: 4px 4px 4px 4px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius:4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section */
|
||||||
|
.section {
|
||||||
|
background: white;
|
||||||
|
margin: -20px -20px 35px -20px;
|
||||||
|
padding:19px;
|
||||||
|
border:1px solid #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Footer*/
|
||||||
|
.footer {
|
||||||
|
background: #151515;
|
||||||
|
padding: 20px 10px 10px 10px;
|
||||||
|
box-shadow: inset 0 15px 10px rgba(0,0,0,0.6);
|
||||||
|
-webkit-box-shadow: inset 0 15px 10px rgba(0,0,0,0.6);
|
||||||
|
-moz-box-shadow:inset 0 15px 10px rgba(0,0,0,0.6);
|
||||||
|
color:#999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer a {
|
||||||
|
color:#eee;
|
||||||
|
font-weight:normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer bottom */
|
||||||
|
.footer.footer-btm {
|
||||||
|
background:#151515;
|
||||||
|
border-top: 1px solid #222;
|
||||||
|
color:#999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive */
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border: 0;
|
||||||
|
-ms-interpolation-mode: bicubic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.above-footer {
|
||||||
|
background:#eee;
|
||||||
|
max-width:100%;
|
||||||
|
}
|
||||||
BIN
favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
favicon.png
Normal file
|
After Width: | Height: | Size: 147 KiB |
BIN
images/Todo.txt Touch for iPad - Page 1.png
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
images/Todo.txt Touch for iPad - Page 2.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
images/download-on-app-store.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
images/mobileappsheader.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
images/todotxt-apps_lrg.png
Normal file
|
After Width: | Height: | Size: 155 KiB |
BIN
images/todotxt_logo_2011.png
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
images/todotxt_logo_2012.png
Normal file
|
After Width: | Height: | Size: 206 KiB |
261
index.html
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>Todo.txt: Future-proof task tracking in a file you control</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/bootstrap-responsive.css"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/style.css"/>
|
||||||
|
<link href="http://fonts.googleapis.com/css?family=Open+Sans:400,600,700" rel="stylesheet" type="text/css" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="description" content="Track your tasks and projects in a plain text file, todo.txt. A todo.txt is software and operating system agnostic; it's searchable, portable, lightweight and easily manipulated." />
|
||||||
|
<meta name="keywords" content="Todo.txt, To do list" />
|
||||||
|
<meta name="robots" content="all,follow" />
|
||||||
|
<meta name="author" content="Gina Trapani" />
|
||||||
|
<link rel="shortcut icon" href="favicon.png" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="body">
|
||||||
|
<div class="above-footer">
|
||||||
|
<div class="hero-unit">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="span7">
|
||||||
|
<a href="" title="Todo.txt"><img src="images/todotxt_logo_2012.png" alt="Todo.txt" width="100" style="float:left;margin-right:10px"/></a>
|
||||||
|
<h1><a href="">Todo.txt</a></h1>
|
||||||
|
<h2>If you want to get it done, first write it down.</h2>
|
||||||
|
<br style="clear:both">
|
||||||
|
</div>
|
||||||
|
<span class="hidden-phone">
|
||||||
|
<div class="span3">
|
||||||
|
<a href="http://itunes.apple.com/us/app/todo.txt-touch/id491342186?ls=1&mt=8" title="Download on the App Store">
|
||||||
|
<img alt="Download on App Store" src="images/download-on-app-store.png" style="float:right"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="span2">
|
||||||
|
<a href="http://play.google.com/store/apps/details?id=com.todotxt.todotxttouch" title="Get it on Google Play">
|
||||||
|
<img alt="Android app on Google Play" src="https://play.google.com/intl/en_us/badges/images/apps/en-play-badge-border.png" width="203" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container content">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<div class="span12">
|
||||||
|
<span class="hidden-phone"><img src="images/todotxt-apps_lrg.png" alt="Todo.txt apps" width="768" style="float:right;margin-bottom:5px"/></span>
|
||||||
|
<h3>If you have a file called todo.txt on your computer right now, you're in the right place.</h3>
|
||||||
|
<p>So many power users try dozens of complicated todo list software applications, only to go right back to their trusty todo.txt file.</p>
|
||||||
|
|
||||||
|
<p>But it's not easy to open todo.txt, make a change, and save it—especially on your touchscreen device and at the command line. Todo.txt apps solve that problem.</p>
|
||||||
|
|
||||||
|
<h3>Simplicity is todo.txt's core value.</h3>
|
||||||
|
|
||||||
|
<p>You're not going to find many checkboxes, drop-downs, reminders, or date pickers here.</p>
|
||||||
|
|
||||||
|
<p>Todo.txt apps are minimal, todo.txt-focused editors which help you manage your tasks with as few keystrokes and taps possible.</p></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<div class="span4">
|
||||||
|
<h2>On Your Phone and Tablet</h2>
|
||||||
|
<span class="hidden-phone"><p><img src="images/mobileappsheader.png" alt="Todo.txt mobile apps" /></p></span>
|
||||||
|
<p>Your todo.txt file isn't useful if it's not always at your fingertips. The Todo.txt mobile apps make it easy to view and update your tasks on the go.</p>
|
||||||
|
<p>Currently connected to <a href="http://dropbox.com">Dropbox</a>, Todo.txt Touch helps you manage your todo.txt on your touchscreen mobile device and automatically syncs your changes to all your computers.</p>
|
||||||
|
<h4>iPhone, iPod touch, and iPad users:</h4>
|
||||||
|
<p>
|
||||||
|
<a href="http://itunes.apple.com/us/app/todo.txt-touch/id491342186?ls=1&mt=8" title="Download on the App Store">
|
||||||
|
<img alt="Download on App Store" src="images/download-on-app-store.png" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<h4>Android users:</h4>
|
||||||
|
<p>
|
||||||
|
<a href="http://play.google.com/store/apps/details?id=com.todotxt.todotxttouch" title="Get it on Google Play">
|
||||||
|
<img alt="Android app on Google Play" src="https://play.google.com/intl/en_us/badges/images/apps/en-play-badge.png" width="203" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p>Also available in <a href="http://www.amazon.com/o/ASIN/B004MNQTVU/ref=nosim/lifehackerboo-20">the Amazon Appstore</a>.
|
||||||
|
</div>
|
||||||
|
<div class="span4">
|
||||||
|
<h2>At the Command Line</h2>
|
||||||
|
<p>With a simple but powerful shell script called todo.sh, you can interact with todo.txt at the command line for quick and easy, Unix-y access.</p>
|
||||||
|
<p><span class="hidden-phone"><iframe src="http://player.vimeo.com/video/3263629?byline=0&portrait=0" width="100%" height="320" frameborder="0" webkitAllowFullScreen allowFullScreen></iframe></span></p>
|
||||||
|
<p>The Todo.txt CLI supports archiving completed tasks to done.txt and priority/context tab autocompletion.</p><br>
|
||||||
|
<p><a href="http://github.com/ginatrapani/todo.txt-cli/releases" class="btn-large btn-success" title="Download Todo.txt CLI">Download Todo.txt CLI »</a></p><br>
|
||||||
|
<p>Find out more:</p>
|
||||||
|
<p><ul>
|
||||||
|
<li><a href="http://wiki.github.com/ginatrapani/todo.txt-cli">Documentation</a>—everything you need to know about how to use Todo.txt CLI</li>
|
||||||
|
<li><a href="http://groups.yahoo.com/group/todotxt/">Mailing List</a>—ask the Todo.txt community</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="span4">
|
||||||
|
<h2>In Any Text Editor</h2>
|
||||||
|
<p>Countless productivity apps and sites store your tasks in their own proprietary database and file format. But you can work with your todo.txt file in every text editor ever made, regardless of operating system or vendor.</p>
|
||||||
|
<p>The todo.txt format is <a href="https://github.com/ginatrapani/todo.txt-cli/wiki/The-Todo.txt-Format">a simple set of rules</a> that make todo.txt both human and machine-readable. The format supports priorities, creation and completion dates, projects and contexts. That's all you need to be productive. <a href="todo.txt">See an example Todo.txt file</a>.</p><br>
|
||||||
|
<span class="hidden-tablet">
|
||||||
|
<h3>What Users Are Saying</h3>
|
||||||
|
<p>
|
||||||
|
<strong>The easiest to-do list I ever used.</strong> -<a href="https://play.google.com/store/apps/details?id=com.todotxt.todotxttouch&reviewId=bGc6QU9xcFRPR1UzN3RldEpIX05yTjhtQ0tyb3lEREd0SHhuY0RzaXVzU2FweVp2Z3JPQ2ZuNmNSMXltaWV2dHFCMk1HcUlRNDRJU0R1bTQ5dDJtMXBqMmow">Dennis</a>
|
||||||
|
<p>
|
||||||
|
<strong>Brilliant... the "cool" factor is off the charts.</strong> -<a href="https://play.google.com/store/apps/details?id=com.todotxt.todotxttouch&reviewId=bGc6QU9xcFRPSERJa1czRmcwaUtYT0lCa2RLZmlhWGlVZ1ppNGc1RWFzVERQT05paWZaRlBHMUZtRE0zQzJHVzhBRENiWEVHX3RrbGxMQ1ktcm1oSmFpazM0">John</a>
|
||||||
|
<p>
|
||||||
|
<strong>So simple, yet also very versatile and flexible. I love it!</strong> -<a href="https://play.google.com/store/apps/details?id=com.todotxt.todotxttouch&reviewId=bGc6QU9xcFRPR2p1QjdWRkZuUGdXN1hwYmNMTUJ5eGFoWDZPcTltemV5a1BkRWYwV3VSdGZ5WXhaWlA1WFNkajczS3dVa2dCRko1d2d1R1EwazdEZ0hXaGtn">mschooler93</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Extremely useful and well executed.</strong> -<a href="https://play.google.com/store/apps/details?id=com.todotxt.todotxttouch&reviewId=bGc6QU9xcFRPR1BpeV9OTXZsNE5wcXZKcWNMN1l1WWhROExia2dadkZNVjdqcGthSFhRQmZreEhVTEV3dENwRm1wSmQxc2dLT0FINUFHbWplem1EX01CLU13">nemof</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>No frills, highly effective and convenient.</strong> -<a href="https://play.google.com/store/apps/details?id=com.todotxt.todotxttouch&reviewId=bGc6QU9xcFRPRUFjYkZRRG53RlBJYVNiYl83Vm5wbVZZOW5FQ01GQ2IyV2s5OFNCMDRwbFFac1NEUDJHeVVOSnFFWFpFVVJpaUVHZU1EXzR3elhwN2VtanJR">Will</a>
|
||||||
|
</p>
|
||||||
|
<br/><br/>
|
||||||
|
</span>
|
||||||
|
<h3>Developers</h3>
|
||||||
|
<p>Todo.txt CLI and Todo.txt Touch are proudly open source. Browse the source code for the <a href="https://github.com/ginatrapani/todo.txt-cli">CLI</a>, <a href="https://github.com/ginatrapani/todo.txt-touch-ios">iOS</a>, and <a href="https://github.com/ginatrapani/todo.txt-touch">Android</a>.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<div class="span12">
|
||||||
|
<h2>Community Apps: Todo.txt on <em>your</em> favorite device or platform.</h2>
|
||||||
|
<p>In addition to the official Todo.txt apps, community members have built more apps and add-ons that work with Todo.txt.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="span3">
|
||||||
|
<h3>Desktop</h3>
|
||||||
|
|
||||||
|
<h4><a href="http://benrhughes.com/todotxt.net/">Todotxt.net</a></h4>
|
||||||
|
<p>A minimalist, keyboard-driven Windows GUI for your todo.txt file, by <a href="http://benrhughes.com/">Ben Hughes</a>.</p>
|
||||||
|
|
||||||
|
<h4><a href="https://mjdescy.github.io/TodoTxtMac/">TodoTxtMac</a></h4>
|
||||||
|
<p>TodoTxtMac is a minimalist, keyboard-driven to-do manager for Mac OS X (10.8 Mountain Lion and higher), by <a href="https://github.com/mjdescy">mjdescy</a>.</p>
|
||||||
|
|
||||||
|
<h4><a href="http://nerdur.com/todour.html">Todour</a></h4>
|
||||||
|
<p>Todour is an application for handling todo.txt files on the Mac and Windows, by Sverrir Valgeirsson.</p>
|
||||||
|
|
||||||
|
<h4><a href="https://launchpad.net/~ximilian/+archive/ppa">DoStuff</a></h4>
|
||||||
|
<p>"A todo.txt client for humans" on Ubuntu (<a href="http://2buntu.com/1197/review-dostuff-a-todotxt-client-for-humans/">screenshots and video clip</a>), by ximilian.</p>
|
||||||
|
|
||||||
|
<h4><a href="http://burnsoftware.wordpress.com/daytasks/">DayTasks</a></h4>
|
||||||
|
<p>A fast, simple, and efficient todo.txt-compatible task list for Ubuntu, by Zach Burnham.</p>
|
||||||
|
|
||||||
|
<h4><a href="https://github.com/mNantern/QTodoTxt">QTodoTxt</a></h4>
|
||||||
|
<p>A fast, cross-platform todo.txt GUI written in Python, by Matthieu Nantern.</p>
|
||||||
|
|
||||||
|
<h4><a href="http://jdotxt.chschmid.com">jdotxt</a></h4>
|
||||||
|
<p>An open-source, Java-based client for Windows, Mac OS X and Linux, by Christian M. Schmid.</p>
|
||||||
|
|
||||||
|
<h4><a href="https://github.com/onovy/otodo">otodo</a></h4>
|
||||||
|
<p>Simple but powerfull TUI for todo.txt by Ondrej Novy.</p>
|
||||||
|
</div>
|
||||||
|
<div class="span3">
|
||||||
|
<h3>Web</h3>
|
||||||
|
|
||||||
|
<h4><a href="http://todotxttdi.com">Todotxttdi.com</a></h4>
|
||||||
|
<p>HTML5 Dropbox app with text-driven user interface (<a href="https://github.com/DavidPratten/todotxttdi">source</a>), by <a href="http://davidpratten.com">David Pratten</a>.</p>
|
||||||
|
|
||||||
|
<h4><a href="http://todo.martinsgill.co.uk">TodoTxtJs</a></h4>
|
||||||
|
<p>Interactive HTML5 todo.txt app with optional Dropbox integration (<a href="https://github.com/MartinSGill/TodoTxtJs">source</a>), by Martin Gill.</p>
|
||||||
|
|
||||||
|
<h4><a href="https://github.com/bicarbon8/todoTxtWebUi">todoTxtWebUi</a></h4>
|
||||||
|
<p>A web UI to use with a todo.txt file (<a href="http://monsoonstudios.com/Code/todoTxt/">demo</a>), by <a href="https://github.com/bicarbon8">Jason Holt</a>.</p>
|
||||||
|
|
||||||
|
<h4><a href="https://github.com/infews/bulldog">Bulldog</a></h4>
|
||||||
|
<p>HTML5 task manager, built on todo.txt, by <a href="https://github.com/infews">Davis W. Frank</a>.</p>
|
||||||
|
|
||||||
|
<h4><a href="https://github.com/trestletech/Todo.txt">Todo.txt++</a></h4>
|
||||||
|
<p>A sleek, hosted, mobile-friendly web app with Dropbox synchronization, filtering, and searching. You can use it <a href ="https://www.todotxtpp.com">here</a></p>
|
||||||
|
|
||||||
|
<h4><a href="https://chrome.google.com/webstore/detail/mndijfcodpjlhgjcpcbhncjakaboedbl">Todo.txt for Chrome</a></h4>
|
||||||
|
<p>Chrome extension with Dropbox integration, and features such as pending task count, saved filters, and more, by <a href="https://c306.net/">Aditya Bhaskar</a>.</p>
|
||||||
|
</div>
|
||||||
|
<div class="span3">
|
||||||
|
<h3>Plugins and Add-ons</h3>
|
||||||
|
|
||||||
|
<h4><a href="https://github.com/freitass/todo.txt-vim">Vim plugin for todo.txt</a></h4>
|
||||||
|
<p>by <a href="https://github.com/freitass">Leandro Freitas</a>.</p>
|
||||||
|
|
||||||
|
<h4><a href="https://ifttt.com/recipes/42299">#todo.txt IFTTT Recipe</a></h4>
|
||||||
|
<p>Add items to your todo.txt file in Dropbox from Google Chat, by Nick Barrett.</p>
|
||||||
|
|
||||||
|
<h4><a href="https://github.com/ginatrapani/todo.txt-cli/wiki/Todo.sh-Add-on-Directory">Todo.sh Add-on Directory</a></h4>
|
||||||
|
<p>A collection of add-ons, custom actions, and filters that enhance the Todo.txt CLI script, authored by community members.</p>
|
||||||
|
|
||||||
|
<h4><a href="https://github.com/dertuxmalwieder/SublimeTodoTxt">Sublime Text todo.txt syntax highlighting</a></h4>
|
||||||
|
<p>by <a href="https://github.com/dertuxmalwieder">Cthulhux</a></p>
|
||||||
|
|
||||||
|
<h4><a href="https://addons.mozilla.org/en-US/thunderbird/addon/todotxt-extension/">Todo.txt Thunderbird Extension</a></h4>
|
||||||
|
<p>by <a href="https://github.com/rkokkelk/todo.txt-ext">Roy Kokkelkoren</a></p>
|
||||||
|
</div>
|
||||||
|
<div class="span3">
|
||||||
|
<h3>Mobile</h3>
|
||||||
|
|
||||||
|
<h4><a href="http://www.windowsphone.com/en-US/apps/50b1ca07-7e23-4963-a0ba-1536e6913543">Todo.txt for Windows Phone 7</a></h4>
|
||||||
|
<p>Todo.txt for Windows Phone 7 is a task manager based on the todo.txt file format, by <a href="https://github.com/hartez">E.Z. Hart</a>.</p>
|
||||||
|
|
||||||
|
<h4><a href="http://monkeystew.org/apps/">Todo.txt Enyo</a></h4>
|
||||||
|
<p>A webOS application for managing your todo.txt file written using the EnyoJS framework, by <a href="https://github.com/thrrgilag">thrrgilag</a>.</p>
|
||||||
|
|
||||||
|
<h4><a href="https://play.google.com/store/apps/details?id=nl.mpcjanssen.todotxtholo">Simpletask</a></h4>
|
||||||
|
<p>Powerful todo.txt app for Android, by <a href="http://mpcjanssen.nl/">Mark Janssen</a>. Also available in a <a href="https://play.google.com/store/apps/details?id=nl.mpcjanssen.simpletask">cloudless</a> version.</p>
|
||||||
|
|
||||||
|
<h4><a href="https://play.google.com/store/apps/details?id=net.c306.ttsuper">Todo.txt for Android</a></h4>
|
||||||
|
<p>Todo.txt for Android - simple, efficient, integrated with Dropbox, includes home screen widgets. Supports 6.0 Marshmallow or higher, by <a href="https://c306.net">Aditya Bhaskar</a>.</p>
|
||||||
|
|
||||||
|
<h3>Developer Tools</h3>
|
||||||
|
|
||||||
|
<h4><a href="https://github.com/samwho/todo-txt-gem">Todo.txt Gem</a></h4>
|
||||||
|
<p>A RubyGem for parsing todo.txt files, by <a href="https://github.com/samwho">Sam Rose</a>.</p>
|
||||||
|
|
||||||
|
<h4><a href="http://search.cpan.org/~andrew/Text-Todo-v0.2.0/lib/Text/Todo.pm">Text::Todo</a></h4>
|
||||||
|
<p>Perl interface to todotxt files by Andrew Fresh.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="span4 offset8" align="right">
|
||||||
|
<a href="https://twitter.com/todotxt" class="twitter-follow-button" data-show-count="true" data-lang="en">Follow @todotxt</a><script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<div class="fill">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<p>Unless otherwise noted, Todo.txt apps published herein are authored by <a href="http://ginatrapani.org/" title="Gina Trapani: The Official Site">Gina Trapani</a> in collaboration with <a href="https://github.com/ginatrapani/todo.txt-cli/contributors">Todo.txt</a> <a href="https://github.com/ginatrapani/todo.txt-touch-ios/contributors">community</a> <a href="https://github.com/ginatrapani/todo.txt-touch/contributors">members</a> and released under the <a href="http://www.gnu.org/copyleft/gpl.html">GNU General Public License</a>.</p>
|
||||||
|
<p>Todo.txt's icon designed by <a href="http://twitter.com/eJohnR">John Rowley</a>.</p>
|
||||||
|
<p>The first version of the Todo.txt CLI script was originally <a href="http://lifehacker.com/software/top/geek-to-live--readerwritten-todotxt-manager-173018.php">published in 2006 on Lifehacker</a>.</p>
|
||||||
|
|
||||||
|
<p>All software comes as is with no warranty. Do back up your todo.txt before you read another word. Support is available on the <a href="http://groups.yahoo.com/group/todotxt/">Todo.txt community mailing list</a>.</p>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer footer-btm">
|
||||||
|
<div class="fill">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<p>Copyright © 2006-2016, <a href="http://ginatrapani.org/" title="Gina Trapani">Gina Trapani</a>.<a style="visibility:hidden;" href="https://plus.google.com/113612142759476883204?rel=author">Gina Trapani</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
_uacct = "UA-436966-1";
|
||||||
|
urchinTracker();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
media/todotxt20_controller.swf
Executable file
41
todo.cfg
@@ -1,41 +0,0 @@
|
|||||||
# === EDIT FILE LOCATIONS BELOW ===
|
|
||||||
|
|
||||||
# Your todo.txt directory
|
|
||||||
#export TODO_DIR="/Users/gina/Documents/todo"
|
|
||||||
export TODO_DIR="C:/Documents and Settings/gina/My Documents"
|
|
||||||
|
|
||||||
# Your todo/done/report.txt locations
|
|
||||||
export TODO_FILE="$TODO_DIR/todo.txt"
|
|
||||||
export DONE_FILE="$TODO_DIR/done.txt"
|
|
||||||
export REPORT_FILE="$TODO_DIR/report.txt"
|
|
||||||
export TMP_FILE="$TODO_DIR/todo.tmp"
|
|
||||||
|
|
||||||
# == EDIT FILE LOCATIONS ABOVE ===
|
|
||||||
|
|
||||||
# === COLOR MAP ===
|
|
||||||
|
|
||||||
export NONE=''
|
|
||||||
export BLACK='\\033[0;30m'
|
|
||||||
export RED='\\033[0;31m'
|
|
||||||
export GREEN='\\033[0;32m'
|
|
||||||
export BROWN='\\033[0;33m'
|
|
||||||
export BLUE='\\033[0;34m'
|
|
||||||
export PURPLE='\\033[0;35m'
|
|
||||||
export CYAN='\\033[0;36m'
|
|
||||||
export LIGHT_GREY='\\033[0;37m'
|
|
||||||
export DARK_GREY='\\033[1;30m'
|
|
||||||
export LIGHT_RED='\\033[1;31m'
|
|
||||||
export LIGHT_GREEN='\\033[1;32m'
|
|
||||||
export YELLOW='\\033[1;33m'
|
|
||||||
export LIGHT_BLUE='\\033[1;34m'
|
|
||||||
export LIGHT_PURPLE='\\033[1;35m'
|
|
||||||
export LIGHT_CYAN='\\033[1;36m'
|
|
||||||
export WHITE='\\033[1;37m'
|
|
||||||
export DEFAULT='\\033[0m'
|
|
||||||
|
|
||||||
# === PRIORITY COLORS ===
|
|
||||||
|
|
||||||
export PRI_A=$YELLOW # color for A priority
|
|
||||||
export PRI_B=$GREEN # color for B priority
|
|
||||||
export PRI_C=$LIGHT_BLUE # color for C priority
|
|
||||||
export PRI_X=$WHITE # color for rest of them
|
|
||||||
860
todo.sh
@@ -1,860 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
# NOTE: Todo.sh requires the todo.cfg configuration file to run.
|
|
||||||
# Place the todo.cfg file in your home directory or use the -d option for a custom location.
|
|
||||||
|
|
||||||
[ -f VERSION-FILE ] && . VERSION-FILE || VERSION="@DEV_VERSION@"
|
|
||||||
version() { sed -e 's/^ //' <<EndVersion
|
|
||||||
TODO.TXT Command Line Interface v$VERSION
|
|
||||||
|
|
||||||
First release: 5/11/2006
|
|
||||||
Original conception by: Gina Trapani (http://ginatrapani.org)
|
|
||||||
Contributors: http://github.com/ginatrapani/todo.txt-cli/network
|
|
||||||
License: GPL, http://www.gnu.org/copyleft/gpl.html
|
|
||||||
More information and mailing list at http://todotxt.com
|
|
||||||
Code repository: http://github.com/ginatrapani/todo.txt-cli/tree/master
|
|
||||||
EndVersion
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
oneline_usage="todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]"
|
|
||||||
|
|
||||||
usage()
|
|
||||||
{
|
|
||||||
sed -e 's/^ //' <<EndUsage
|
|
||||||
Usage: $oneline_usage
|
|
||||||
Try 'todo.sh -h' for more information.
|
|
||||||
EndUsage
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
shorthelp()
|
|
||||||
{
|
|
||||||
sed -e 's/^ //' <<EndHelp
|
|
||||||
Usage: $oneline_usage
|
|
||||||
|
|
||||||
Actions:
|
|
||||||
add|a "THING I NEED TO DO +project @context"
|
|
||||||
addto DEST "TEXT TO ADD"
|
|
||||||
append|app NUMBER "TEXT TO APPEND"
|
|
||||||
archive
|
|
||||||
command [ACTIONS]
|
|
||||||
del|rm NUMBER [TERM]
|
|
||||||
dp|depri NUMBER
|
|
||||||
do NUMBER
|
|
||||||
help
|
|
||||||
list|ls [TERM...]
|
|
||||||
listall|lsa [TERM...]
|
|
||||||
listcon|lsc
|
|
||||||
listfile|lf SRC [TERM...]
|
|
||||||
listpri|lsp [PRIORITY]
|
|
||||||
listproj|lsprj
|
|
||||||
move|mv NUMBER DEST [SRC]
|
|
||||||
prepend|prep NUMBER "TEXT TO PREPEND"
|
|
||||||
pri|p NUMBER PRIORITY
|
|
||||||
replace NUMBER "UPDATED TODO"
|
|
||||||
report
|
|
||||||
|
|
||||||
See "help" for more details.
|
|
||||||
EndHelp
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
help()
|
|
||||||
{
|
|
||||||
sed -e 's/^ //' <<EndHelp
|
|
||||||
Usage: $oneline_usage
|
|
||||||
|
|
||||||
Actions:
|
|
||||||
add "THING I NEED TO DO +project @context"
|
|
||||||
a "THING I NEED TO DO +project @context"
|
|
||||||
Adds THING I NEED TO DO to your todo.txt file on its own line.
|
|
||||||
Project and context notation optional.
|
|
||||||
Quotes optional.
|
|
||||||
|
|
||||||
addto DEST "TEXT TO ADD"
|
|
||||||
Adds a line of text to any file located in the todo.txt directory.
|
|
||||||
For example, addto inbox.txt "decide about vacation"
|
|
||||||
|
|
||||||
append NUMBER "TEXT TO APPEND"
|
|
||||||
app NUMBER "TEXT TO APPEND"
|
|
||||||
Adds TEXT TO APPEND to the end of the todo on line NUMBER.
|
|
||||||
Quotes optional.
|
|
||||||
|
|
||||||
archive
|
|
||||||
Moves done items from todo.txt to done.txt and removes blank lines.
|
|
||||||
|
|
||||||
command [ACTIONS]
|
|
||||||
Runs the remaining arguments using only todo.sh builtins.
|
|
||||||
Will not call any .todo.actions.d scripts.
|
|
||||||
|
|
||||||
del NUMBER [TERM]
|
|
||||||
rm NUMBER [TERM]
|
|
||||||
Deletes the item on line NUMBER in todo.txt.
|
|
||||||
If term specified, deletes only the term from the line.
|
|
||||||
|
|
||||||
depri NUMBER
|
|
||||||
dp NUMBER
|
|
||||||
Deprioritizes (removes the priority) from the item
|
|
||||||
on line NUMBER in todo.txt.
|
|
||||||
|
|
||||||
do NUMBER
|
|
||||||
Marks item on line NUMBER as done in todo.txt.
|
|
||||||
|
|
||||||
help
|
|
||||||
Display this help message.
|
|
||||||
|
|
||||||
list [TERM...]
|
|
||||||
ls [TERM...]
|
|
||||||
Displays all todo's that contain TERM(s) sorted by priority with line
|
|
||||||
numbers. If no TERM specified, lists entire todo.txt.
|
|
||||||
|
|
||||||
listall [TERM...]
|
|
||||||
lsa [TERM...]
|
|
||||||
Displays all the lines in todo.txt AND done.txt that contain TERM(s)
|
|
||||||
sorted by priority with line numbers. If no TERM specified, lists
|
|
||||||
entire todo.txt AND done.txt concatenated and sorted.
|
|
||||||
|
|
||||||
listcon
|
|
||||||
lsc
|
|
||||||
Lists all the task contexts that start with the @ sign in todo.txt.
|
|
||||||
|
|
||||||
listfile SRC [TERM...]
|
|
||||||
lf SRC [TERM...]
|
|
||||||
Displays all the lines in SRC file located in the todo.txt directory,
|
|
||||||
sorted by priority with line numbers. If TERM specified, lists
|
|
||||||
all lines that contain TERM in SRC file.
|
|
||||||
|
|
||||||
listpri [PRIORITY]
|
|
||||||
lsp [PRIORITY]
|
|
||||||
Displays all items prioritized PRIORITY.
|
|
||||||
If no PRIORITY specified, lists all prioritized items.
|
|
||||||
|
|
||||||
listproj
|
|
||||||
lsprj
|
|
||||||
Lists all the projects that start with the + sign in todo.txt.
|
|
||||||
|
|
||||||
move NUMBER DEST [SRC]
|
|
||||||
mv NUMBER DEST [SRC]
|
|
||||||
Moves a line from source text file (SRC) to destination text file (DEST).
|
|
||||||
Both source and destination file must be located in the directory defined
|
|
||||||
in the configuration directory. When SRC is not defined
|
|
||||||
it's by default todo.txt.
|
|
||||||
|
|
||||||
prepend NUMBER "TEXT TO PREPEND"
|
|
||||||
prep NUMBER "TEXT TO PREPEND"
|
|
||||||
Adds TEXT TO PREPEND to the beginning of the todo on line NUMBER.
|
|
||||||
Quotes optional.
|
|
||||||
|
|
||||||
pri NUMBER PRIORITY
|
|
||||||
p NUMBER PRIORITY
|
|
||||||
Adds PRIORITY to todo on line NUMBER. If the item is already
|
|
||||||
prioritized, replaces current priority with new PRIORITY.
|
|
||||||
PRIORITY must be an uppercase letter between A and Z.
|
|
||||||
|
|
||||||
replace NUMBER "UPDATED TODO"
|
|
||||||
Replaces todo on line NUMBER with UPDATED TODO.
|
|
||||||
|
|
||||||
report
|
|
||||||
Adds the number of open todo's and closed done's to report.txt.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-@
|
|
||||||
Hide context names in list output. Use twice to show context
|
|
||||||
names (default).
|
|
||||||
-+
|
|
||||||
Hide project names in list output. Use twice to show project
|
|
||||||
names (default).
|
|
||||||
-d CONFIG_FILE
|
|
||||||
Use a configuration file other than the default ~/todo.cfg
|
|
||||||
-f
|
|
||||||
Forces actions without confirmation or interactive input
|
|
||||||
-h
|
|
||||||
Display a short help message
|
|
||||||
-p
|
|
||||||
Plain mode turns off colors
|
|
||||||
-P
|
|
||||||
Hide priority labels in list output. Use twice to show
|
|
||||||
priority labels (default).
|
|
||||||
-a
|
|
||||||
Don't auto-archive tasks automatically on completion
|
|
||||||
-n
|
|
||||||
Don't preserve line numbers; automatically remove blank lines
|
|
||||||
on task deletion
|
|
||||||
-t
|
|
||||||
Prepend the current date to a task automatically
|
|
||||||
when it's added.
|
|
||||||
-v
|
|
||||||
Verbose mode turns on confirmation messages
|
|
||||||
-vv
|
|
||||||
Extra verbose mode prints some debugging information
|
|
||||||
-V
|
|
||||||
Displays version, license and credits
|
|
||||||
|
|
||||||
|
|
||||||
Environment variables:
|
|
||||||
TODOTXT_AUTO_ARCHIVE=0 is same as option -a
|
|
||||||
TODOTXT_CFG_FILE=CONFIG_FILE is same as option -d CONFIG_FILE
|
|
||||||
TODOTXT_FORCE=1 is same as option -f
|
|
||||||
TODOTXT_PRESERVE_LINE_NUMBERS=0 is same as option -n
|
|
||||||
TODOTXT_PLAIN=1 is same as option -p
|
|
||||||
TODOTXT_DATE_ON_ADD=1 is same as option -t
|
|
||||||
TODOTXT_VERBOSE=1 is same as option -v
|
|
||||||
TODOTXT_DEFAULT_ACTION="" run this when called with no arguments
|
|
||||||
EndHelp
|
|
||||||
|
|
||||||
if [ -d "$HOME/.todo.actions.d" ]
|
|
||||||
then
|
|
||||||
echo ""
|
|
||||||
for action in $HOME/.todo.actions.d/*
|
|
||||||
do
|
|
||||||
if [ -x $action ]
|
|
||||||
then
|
|
||||||
$action usage
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
die()
|
|
||||||
{
|
|
||||||
echo "$*"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup()
|
|
||||||
{
|
|
||||||
[ -f "$TMP_FILE" ] && rm "$TMP_FILE"
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
archive()
|
|
||||||
{
|
|
||||||
#defragment blank lines
|
|
||||||
sed -i.bak -e '/./!d' "$TODO_FILE"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && grep "^x " "$TODO_FILE"
|
|
||||||
grep "^x " "$TODO_FILE" >> "$DONE_FILE"
|
|
||||||
sed -i.bak '/^x /d' "$TODO_FILE"
|
|
||||||
cp "$TODO_FILE" "$TMP_FILE"
|
|
||||||
sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P' "$TMP_FILE" > "$TODO_FILE"
|
|
||||||
#[[ $TODOTXT_VERBOSE -gt 0 ]] && echo "TODO: Duplicate tasks have been removed."
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: $TODO_FILE archived."
|
|
||||||
cleanup
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# == PROCESS OPTIONS ==
|
|
||||||
while getopts ":fhpnatvV+@Pd:" Option
|
|
||||||
do
|
|
||||||
case $Option in
|
|
||||||
'@' )
|
|
||||||
## HIDE_CONTEXT_NAMES starts at zero (false); increment it to one
|
|
||||||
## (true) the first time this flag is seen. Each time the flag
|
|
||||||
## is seen after that, increment it again so that an even
|
|
||||||
## number hides project names and an odd number shows project
|
|
||||||
## names.
|
|
||||||
: $(( HIDE_CONTEXT_NAMES++ ))
|
|
||||||
if [ $(( $HIDE_CONTEXT_NAMES % 2 )) -eq 0 ]
|
|
||||||
then
|
|
||||||
## Zero or even value -- show context names
|
|
||||||
unset HIDE_CONTEXTS_SUBSTITUTION
|
|
||||||
else
|
|
||||||
## One or odd value -- hide context names
|
|
||||||
export HIDE_CONTEXTS_SUBSTITUTION='[[:space:]]@[^[:space:]]\{1,\}'
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
'+' )
|
|
||||||
## HIDE_PROJECT_NAMES starts at zero (false); increment it to one
|
|
||||||
## (true) the first time this flag is seen. Each time the flag
|
|
||||||
## is seen after that, increment it again so that an even
|
|
||||||
## number hides project names and an odd number shows project
|
|
||||||
## names.
|
|
||||||
: $(( HIDE_PROJECT_NAMES++ ))
|
|
||||||
if [ $(( $HIDE_PROJECT_NAMES % 2 )) -eq 0 ]
|
|
||||||
then
|
|
||||||
## Zero or even value -- show project names
|
|
||||||
unset HIDE_PROJECTS_SUBSTITUTION
|
|
||||||
else
|
|
||||||
## One or odd value -- hide project names
|
|
||||||
export HIDE_PROJECTS_SUBSTITUTION='[[:space:]][+][^[:space:]]\{1,\}'
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
a )
|
|
||||||
TODOTXT_AUTO_ARCHIVE=0
|
|
||||||
;;
|
|
||||||
d )
|
|
||||||
TODOTXT_CFG_FILE=$OPTARG
|
|
||||||
;;
|
|
||||||
f )
|
|
||||||
TODOTXT_FORCE=1
|
|
||||||
;;
|
|
||||||
h )
|
|
||||||
shorthelp
|
|
||||||
;;
|
|
||||||
n )
|
|
||||||
TODOTXT_PRESERVE_LINE_NUMBERS=0
|
|
||||||
;;
|
|
||||||
p )
|
|
||||||
TODOTXT_PLAIN=1
|
|
||||||
;;
|
|
||||||
P )
|
|
||||||
## HIDE_PRIORITY_LABELS starts at zero (false); increment it to one
|
|
||||||
## (true) the first time this flag is seen. Each time the flag
|
|
||||||
## is seen after that, increment it again so that an even
|
|
||||||
## number hides project names and an odd number shows project
|
|
||||||
## names.
|
|
||||||
: $(( HIDE_PRIORITY_LABELS++ ))
|
|
||||||
if [ $(( $HIDE_PRIORITY_LABELS % 2 )) -eq 0 ]
|
|
||||||
then
|
|
||||||
## Zero or even value -- show priority labels
|
|
||||||
unset HIDE_PRIORITY_SUBSTITUTION
|
|
||||||
else
|
|
||||||
## One or odd value -- hide priority labels
|
|
||||||
export HIDE_PRIORITY_SUBSTITUTION="([A-Z])[[:space:]]"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
t )
|
|
||||||
TODOTXT_DATE_ON_ADD=1
|
|
||||||
;;
|
|
||||||
v )
|
|
||||||
: $(( TODOTXT_VERBOSE++ ))
|
|
||||||
;;
|
|
||||||
V )
|
|
||||||
version
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
shift $(($OPTIND - 1))
|
|
||||||
|
|
||||||
# defaults if not yet defined
|
|
||||||
TODOTXT_VERBOSE=${TODOTXT_VERBOSE:-1}
|
|
||||||
TODOTXT_PLAIN=${TODOTXT_PLAIN:-0}
|
|
||||||
TODOTXT_CFG_FILE=${TODOTXT_CFG_FILE:-$HOME/todo.cfg}
|
|
||||||
TODOTXT_FORCE=${TODOTXT_FORCE:-0}
|
|
||||||
TODOTXT_PRESERVE_LINE_NUMBERS=${TODOTXT_PRESERVE_LINE_NUMBERS:-1}
|
|
||||||
TODOTXT_AUTO_ARCHIVE=${TODOTXT_AUTO_ARCHIVE:-1}
|
|
||||||
TODOTXT_DATE_ON_ADD=${TODOTXT_DATE_ON_ADD:-0}
|
|
||||||
TODOTXT_DEFAULT_ACTION=${TODOTXT_DEFAULT_ACTION:-}
|
|
||||||
|
|
||||||
[ -e "$TODOTXT_CFG_FILE" ] || {
|
|
||||||
CFG_FILE_ALT="$HOME/.todo.cfg"
|
|
||||||
|
|
||||||
if [ -e "$CFG_FILE_ALT" ]
|
|
||||||
then
|
|
||||||
TODOTXT_CFG_FILE="$CFG_FILE_ALT"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
export TODOTXT_VERBOSE TODOTXT_PLAIN TODOTXT_CFG_FILE TODOTXT_FORCE TODOTXT_PRESERVE_LINE_NUMBERS TODOTXT_AUTO_ARCHIVE TODOTXT_DATE_ON_ADD
|
|
||||||
|
|
||||||
TODO_SH="$0"
|
|
||||||
export TODO_SH
|
|
||||||
|
|
||||||
# === SANITY CHECKS (thanks Karl!) ===
|
|
||||||
[ -r "$TODOTXT_CFG_FILE" ] || die "Fatal error: Cannot read configuration file $TODOTXT_CFG_FILE"
|
|
||||||
|
|
||||||
. "$TODOTXT_CFG_FILE"
|
|
||||||
|
|
||||||
ACTION=${1:-$TODOTXT_DEFAULT_ACTION}
|
|
||||||
|
|
||||||
[ -z "$ACTION" ] && usage
|
|
||||||
[ -d "$TODO_DIR" ] || die "Fatal Error: $TODO_DIR is not a directory"
|
|
||||||
( cd "$TODO_DIR" ) || die "Fatal Error: Unable to cd to $TODO_DIR"
|
|
||||||
|
|
||||||
[ -w "$TMP_FILE" ] || echo -n > "$TMP_FILE" || die "Fatal Error: Unable to write to $TMP_FILE"
|
|
||||||
[ -f "$TODO_FILE" ] || cp /dev/null "$TODO_FILE"
|
|
||||||
[ -f "$DONE_FILE" ] || cp /dev/null "$DONE_FILE"
|
|
||||||
[ -f "$REPORT_FILE" ] || cp /dev/null "$REPORT_FILE"
|
|
||||||
|
|
||||||
if [ $TODOTXT_PLAIN = 1 ]; then
|
|
||||||
PRI_A=$NONE
|
|
||||||
PRI_B=$NONE
|
|
||||||
PRI_C=$NONE
|
|
||||||
PRI_X=$NONE
|
|
||||||
DEFAULT=$NONE
|
|
||||||
fi
|
|
||||||
|
|
||||||
# === HEAVY LIFTING ===
|
|
||||||
shopt -s extglob
|
|
||||||
|
|
||||||
_list() {
|
|
||||||
local FILE="$1"
|
|
||||||
## If the file starts with a "/" use absolute path. Otherwise,
|
|
||||||
## try to find it in either $TODO_DIR or using a relative path
|
|
||||||
if [ "${1:0:1}" == / ]
|
|
||||||
then
|
|
||||||
## Absolute path
|
|
||||||
src="$FILE"
|
|
||||||
elif [ -f "$TODO_DIR/$FILE" ]
|
|
||||||
then
|
|
||||||
## Path relative to todo.sh directory
|
|
||||||
src="$TODO_DIR/$1"
|
|
||||||
elif [ -f "$FILE" ]
|
|
||||||
then
|
|
||||||
## Path relative to current working directory
|
|
||||||
src="$FILE"
|
|
||||||
else
|
|
||||||
echo "TODO: File $FILE does not exist."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
## Get our search arguments, if any
|
|
||||||
shift ## was file name, new $1 is first search term
|
|
||||||
|
|
||||||
## Prefix the filter_command with the pre_filter_command
|
|
||||||
filter_command="${pre_filter_command:-}"
|
|
||||||
|
|
||||||
for search_term in "$@"
|
|
||||||
do
|
|
||||||
## See if the first character of $search_term is a dash
|
|
||||||
if [ ${search_term:0:1} != '-' ]
|
|
||||||
then
|
|
||||||
## First character isn't a dash: hide lines that don't match
|
|
||||||
## this $search_term
|
|
||||||
filter_command="${filter_command:-} ${filter_command:+|} \
|
|
||||||
grep -i \"$search_term\" "
|
|
||||||
else
|
|
||||||
## First character is a dash: hide lines that match this
|
|
||||||
## $search_term
|
|
||||||
#
|
|
||||||
## Remove the first character (-) before adding to our filter command
|
|
||||||
filter_command="${filter_command:-} ${filter_command:+|} \
|
|
||||||
grep -v -i \"${search_term:1}\" "
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
## If post_filter_command is set, append it to the filter_command
|
|
||||||
[ -n "$post_filter_command" ] && {
|
|
||||||
filter_command="${filter_command:-}${filter_command:+ | }${post_filter_command:-}"
|
|
||||||
}
|
|
||||||
|
|
||||||
## Figure out how much padding we need to use
|
|
||||||
## We need one level of padding for each power of 10 $LINES uses
|
|
||||||
LINES=$( sed -n '$ =' "$src" )
|
|
||||||
PADDING=${#LINES}
|
|
||||||
|
|
||||||
## Number the file, then run the filter command,
|
|
||||||
## then sort and mangle output some more
|
|
||||||
items=$(
|
|
||||||
sed = "$src" \
|
|
||||||
| sed "N; s/^/ /; s/ *\(.\{$PADDING,\}\)\n/\1 /" \
|
|
||||||
| grep -v "^[0-9]\+ *$"
|
|
||||||
)
|
|
||||||
if [ "${filter_command}" ]; then
|
|
||||||
filtered_items=$(echo -ne "$items" | eval ${filter_command})
|
|
||||||
else
|
|
||||||
filtered_items=$items
|
|
||||||
fi
|
|
||||||
filtered_items=$(
|
|
||||||
echo -ne "$filtered_items" \
|
|
||||||
| sed '''
|
|
||||||
s/^ /00000/;
|
|
||||||
s/^ /0000/;
|
|
||||||
s/^ /000/;
|
|
||||||
s/^ /00/;
|
|
||||||
s/^ /0/;
|
|
||||||
''' \
|
|
||||||
| sort -f -k2 \
|
|
||||||
| sed '''
|
|
||||||
/^[0-9]\{'$PADDING'\} x /! {
|
|
||||||
s/\(.*(A).*\)/'$PRI_A'\1 '$DEFAULT'/g;
|
|
||||||
s/\(.*(B).*\)/'$PRI_B'\1 '$DEFAULT'/g;
|
|
||||||
s/\(.*(C).*\)/'$PRI_C'\1 '$DEFAULT'/g;
|
|
||||||
s/\(.*([D-Z]).*\)/'$PRI_X'\1 '$DEFAULT'/g;
|
|
||||||
}
|
|
||||||
''' \
|
|
||||||
| sed '''
|
|
||||||
s/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g
|
|
||||||
s/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g
|
|
||||||
s/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g
|
|
||||||
''' \
|
|
||||||
)
|
|
||||||
echo -ne "$filtered_items${filtered_items:+\n}"
|
|
||||||
|
|
||||||
if [ $TODOTXT_VERBOSE -gt 0 ]; then
|
|
||||||
NUMTASKS=$( echo -ne "$filtered_items" | sed -n '$ =' )
|
|
||||||
TOTALTASKS=$( echo -ne "$items" | sed -n '$ =' )
|
|
||||||
|
|
||||||
echo "--"
|
|
||||||
echo "TODO: ${NUMTASKS:-0} of ${TOTALTASKS:-0} tasks shown from $FILE"
|
|
||||||
fi
|
|
||||||
if [ $TODOTXT_VERBOSE -gt 1 ]
|
|
||||||
then
|
|
||||||
echo "TODO DEBUG: Filter Command was: ${filter_command:-cat}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
export -f _list
|
|
||||||
|
|
||||||
# == HANDLE ACTION ==
|
|
||||||
action=$( printf "%s\n" "$ACTION" | tr 'A-Z' 'a-z' )
|
|
||||||
|
|
||||||
## If the first argument is "command", run the rest of the arguments
|
|
||||||
## using todo.sh builtins.
|
|
||||||
## Else, run a actions script with the name of the command if it exists
|
|
||||||
## or fallback to using a builtin
|
|
||||||
if [ "$action" == command ]
|
|
||||||
then
|
|
||||||
## Get rid of "command" from arguments list
|
|
||||||
shift
|
|
||||||
## Reset action to new first argument
|
|
||||||
action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' )
|
|
||||||
elif [ -d "$HOME/.todo.actions.d" -a -x "$HOME/.todo.actions.d/$action" ]
|
|
||||||
then
|
|
||||||
"$HOME/.todo.actions.d/$action" "$@"
|
|
||||||
cleanup
|
|
||||||
fi
|
|
||||||
|
|
||||||
## Only run if $action isn't found in .todo.actions.d
|
|
||||||
case $action in
|
|
||||||
"add" | "a")
|
|
||||||
if [[ -z "$2" && $TODOTXT_FORCE = 0 ]]; then
|
|
||||||
echo -n "Add: "
|
|
||||||
read input
|
|
||||||
else
|
|
||||||
[ -z "$2" ] && die "usage: $0 add \"TODO ITEM\""
|
|
||||||
shift
|
|
||||||
input=$*
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $TODOTXT_DATE_ON_ADD = 1 ]]; then
|
|
||||||
now=`date '+%Y-%m-%d'`
|
|
||||||
input="$now $input"
|
|
||||||
fi
|
|
||||||
echo "$input" >> "$TODO_FILE"
|
|
||||||
TASKNUM=$(sed -n '$ =' "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: '$input' added on line $TASKNUM."
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
"addto" )
|
|
||||||
[ -z "$2" ] && die "usage: $0 addto DEST \"TODO ITEM\""
|
|
||||||
dest="$TODO_DIR/$2"
|
|
||||||
[ -z "$3" ] && die "usage: $0 addto DEST \"TODO ITEM\""
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
input=$*
|
|
||||||
|
|
||||||
if [ -f "$dest" ]; then
|
|
||||||
echo "$input" >> "$dest"
|
|
||||||
TASKNUM=$(sed -n '$ =' "$dest")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: '$input' added to $dest on line $TASKNUM."
|
|
||||||
else
|
|
||||||
echo "TODO: Destination file $dest does not exist."
|
|
||||||
fi
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
"append" | "app" )
|
|
||||||
errmsg="usage: $0 append ITEM# \"TEXT TO APPEND\""
|
|
||||||
shift; item=$1; shift
|
|
||||||
|
|
||||||
[ -z "$item" ] && die "$errmsg"
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
todo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ -z "$todo" ] && die "$item: No such todo."
|
|
||||||
if [[ -z "$1" && $TODOTXT_FORCE = 0 ]]; then
|
|
||||||
echo -n "Append: "
|
|
||||||
read input
|
|
||||||
else
|
|
||||||
input=$*
|
|
||||||
fi
|
|
||||||
if sed -i.bak $item" s|^.*|& $input|" "$TODO_FILE"; then
|
|
||||||
newtodo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "$item: $newtodo"
|
|
||||||
else
|
|
||||||
echo "TODO: Error appending task $item."
|
|
||||||
fi
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
"archive" )
|
|
||||||
archive;;
|
|
||||||
|
|
||||||
"del" | "rm" )
|
|
||||||
# replace deleted line with a blank line when TODOTXT_PRESERVE_LINE_NUMBERS is 1
|
|
||||||
errmsg="usage: $0 del ITEM#"
|
|
||||||
item=$2
|
|
||||||
[ -z "$item" ] && die "$errmsg"
|
|
||||||
|
|
||||||
if [ -z "$3" ]; then
|
|
||||||
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
if sed -ne "$item p" "$TODO_FILE" | grep "^."; then
|
|
||||||
DELETEME=$(sed "$2!d" "$TODO_FILE")
|
|
||||||
|
|
||||||
if [ $TODOTXT_FORCE = 0 ]; then
|
|
||||||
echo "Delete '$DELETEME'? (y/n)"
|
|
||||||
read ANSWER
|
|
||||||
else
|
|
||||||
ANSWER="y"
|
|
||||||
fi
|
|
||||||
if [ "$ANSWER" = "y" ]; then
|
|
||||||
if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then
|
|
||||||
# delete line (changes line numbers)
|
|
||||||
sed -i.bak -e $2"s/^.*//" -e '/./!d' "$TODO_FILE"
|
|
||||||
else
|
|
||||||
# leave blank line behind (preserves line numbers)
|
|
||||||
sed -i.bak -e $2"s/^.*//" "$TODO_FILE"
|
|
||||||
fi
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: '$DELETEME' deleted."
|
|
||||||
cleanup
|
|
||||||
else
|
|
||||||
echo "TODO: No tasks were deleted."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "$item: No such todo."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
sed -i.bak -e $item"s/$3/ /g" "$TODO_FILE"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: $3 removed from $item."
|
|
||||||
fi ;;
|
|
||||||
|
|
||||||
"depri" | "dp" )
|
|
||||||
item=$2
|
|
||||||
errmsg="usage: $0 depri ITEM#"
|
|
||||||
|
|
||||||
todo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ -z "$todo" ] && die "$item: No such todo."
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
|
|
||||||
sed -e $item"s/^(.*) //" "$TODO_FILE" > /dev/null 2>&1
|
|
||||||
|
|
||||||
if [ "$?" -eq 0 ]; then
|
|
||||||
#it's all good, continue
|
|
||||||
sed -i.bak -e $2"s/^(.*) //" "$TODO_FILE"
|
|
||||||
NEWTODO=$(sed "$2!d" "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo -e "`echo "$item: $NEWTODO"`"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: $item deprioritized."
|
|
||||||
cleanup
|
|
||||||
else
|
|
||||||
die "$errmsg"
|
|
||||||
fi;;
|
|
||||||
|
|
||||||
"do" )
|
|
||||||
errmsg="usage: $0 do ITEM#"
|
|
||||||
item=$2
|
|
||||||
[ -z "$item" ] && die "$errmsg"
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
|
|
||||||
todo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ -z "$todo" ] && die "$item: No such todo."
|
|
||||||
|
|
||||||
now=`date '+%Y-%m-%d'`
|
|
||||||
# remove priority once item is done
|
|
||||||
sed -i.bak $item"s/^(.*) //" "$TODO_FILE"
|
|
||||||
sed -i.bak $item"s|^|&x $now |" "$TODO_FILE"
|
|
||||||
newtodo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "$item: $newtodo"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: $item marked as done."
|
|
||||||
|
|
||||||
if [ $TODOTXT_AUTO_ARCHIVE = 1 ]; then
|
|
||||||
archive
|
|
||||||
fi
|
|
||||||
cleanup ;;
|
|
||||||
|
|
||||||
"help" )
|
|
||||||
help
|
|
||||||
;;
|
|
||||||
|
|
||||||
"list" | "ls" )
|
|
||||||
shift ## Was ls; new $1 is first search term
|
|
||||||
_list "$TODO_FILE" "$@"
|
|
||||||
|
|
||||||
cleanup
|
|
||||||
;;
|
|
||||||
|
|
||||||
"listall" | "lsa" )
|
|
||||||
shift ## Was lsa; new $1 is first search term
|
|
||||||
|
|
||||||
cat "$TODO_FILE" "$DONE_FILE" > "$TMP_FILE"
|
|
||||||
_list "$TMP_FILE" "$@"
|
|
||||||
|
|
||||||
cleanup
|
|
||||||
;;
|
|
||||||
|
|
||||||
"listfile" | "lf" )
|
|
||||||
shift ## Was listfile, next $1 is file name
|
|
||||||
FILE="$1"
|
|
||||||
shift ## Was filename; next $1 is first search term
|
|
||||||
|
|
||||||
_list "$FILE" "$@"
|
|
||||||
|
|
||||||
cleanup
|
|
||||||
;;
|
|
||||||
|
|
||||||
"listcon" | "lsc" )
|
|
||||||
gawk '{for(i = 1; i <= NF; i++) print $i}' "$TODO_FILE" | grep '@' | sort | uniq
|
|
||||||
cleanup ;;
|
|
||||||
|
|
||||||
"listproj" | "lsprj" )
|
|
||||||
gawk '{for(i = 1; i <= NF; i++) print $i}' "$TODO_FILE" | grep '+' | sort | uniq
|
|
||||||
cleanup ;;
|
|
||||||
|
|
||||||
|
|
||||||
"listpri" | "lsp" )
|
|
||||||
shift ## was "listpri", new $1 is priority to list
|
|
||||||
|
|
||||||
if [ "${1:-}" ]
|
|
||||||
then
|
|
||||||
## A priority was specified
|
|
||||||
pri=$( printf "%s\n" "$1" | tr 'a-z' 'A-Z' | grep '^[A-Z]$' ) || {
|
|
||||||
die "usage: $0 listpri PRIORITY
|
|
||||||
note: PRIORITY must a single letter from A to Z."
|
|
||||||
}
|
|
||||||
else
|
|
||||||
## No priority specified; show all priority tasks
|
|
||||||
pri="[[:upper:]]"
|
|
||||||
fi
|
|
||||||
pri="($pri)"
|
|
||||||
|
|
||||||
_list "$TODO_FILE" "$pri"
|
|
||||||
;;
|
|
||||||
|
|
||||||
"move" | "mv" )
|
|
||||||
# replace moved line with a blank line when TODOTXT_PRESERVE_LINE_NUMBERS is 1
|
|
||||||
errmsg="usage: $0 mv ITEM# DEST [SRC]"
|
|
||||||
item=$2
|
|
||||||
dest="$TODO_DIR/$3"
|
|
||||||
src="$TODO_DIR/$4"
|
|
||||||
|
|
||||||
[ -z "$item" ] && die "$errmsg"
|
|
||||||
[ -z "$4" ] && src="$TODO_FILE"
|
|
||||||
[ -z "$dest" ] && die "$errmsg"
|
|
||||||
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
|
|
||||||
if [ -f "$src" ]; then
|
|
||||||
if [ -f "$dest" ]; then
|
|
||||||
if sed -ne "$item p" "$src" | grep "^."; then
|
|
||||||
MOVEME=$(sed "$item!d" "$src")
|
|
||||||
if [ $TODOTXT_FORCE = 0 ]; then
|
|
||||||
echo "Move '$MOVEME' from $src to $dest? (y/n)"
|
|
||||||
read ANSWER
|
|
||||||
else
|
|
||||||
ANSWER="y"
|
|
||||||
fi
|
|
||||||
if [ "$ANSWER" = "y" ]; then
|
|
||||||
if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then
|
|
||||||
# delete line (changes line numbers)
|
|
||||||
sed -i.bak -e $item"s/^.*//" -e '/./!d' "$src"
|
|
||||||
else
|
|
||||||
# leave blank line behind (preserves line numbers)
|
|
||||||
sed -i.bak -e $item"s/^.*//" "$src"
|
|
||||||
fi
|
|
||||||
echo "$MOVEME" >> "$dest"
|
|
||||||
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: '$MOVEME' moved from '$src' to '$dest'."
|
|
||||||
cleanup
|
|
||||||
else
|
|
||||||
echo "TODO: No tasks moved."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "$item: No such item in $src."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "TODO: Destination file $dest does not exist."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "TODO: Source file $src does not exist."
|
|
||||||
fi
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
"prepend" | "prep" )
|
|
||||||
errmsg="usage: $0 prepend ITEM# \"TEXT TO PREPEND\""
|
|
||||||
shift; item=$1; shift
|
|
||||||
|
|
||||||
[ -z "$item" ] && die "$errmsg"
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
|
|
||||||
todo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ -z "$todo" ] && die "$item: No such todo."
|
|
||||||
|
|
||||||
if [[ -z "$1" && $TODOTXT_FORCE = 0 ]]; then
|
|
||||||
echo -n "Prepend: "
|
|
||||||
read input
|
|
||||||
else
|
|
||||||
input=$*
|
|
||||||
fi
|
|
||||||
|
|
||||||
if sed -i.bak $item" s|^.*|$input &|" "$TODO_FILE"; then
|
|
||||||
newtodo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "$item: $newtodo"
|
|
||||||
else
|
|
||||||
echo "TODO: Error prepending task $item."
|
|
||||||
fi
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
"pri" | "p" )
|
|
||||||
item=$2
|
|
||||||
newpri=$( printf "%s\n" "$3" | tr 'a-z' 'A-Z' )
|
|
||||||
|
|
||||||
errmsg="usage: $0 pri ITEM# PRIORITY
|
|
||||||
note: PRIORITY must be anywhere from A to Z."
|
|
||||||
|
|
||||||
[ "$#" -ne 3 ] && die "$errmsg"
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
[[ "$newpri" = +([A-Z]) ]] || die "$errmsg"
|
|
||||||
|
|
||||||
sed -e $item"s/^(.*) //" -e $item"s/^/($newpri) /" "$TODO_FILE" > /dev/null 2>&1
|
|
||||||
|
|
||||||
if [ "$?" -eq 0 ]; then
|
|
||||||
#it's all good, continue
|
|
||||||
sed -i.bak -e $2"s/^(.*) //" -e $2"s/^/($newpri) /" "$TODO_FILE"
|
|
||||||
NEWTODO=$(sed "$2!d" "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo -e "`echo "$item: $NEWTODO"`"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: $item prioritized ($newpri)."
|
|
||||||
cleanup
|
|
||||||
else
|
|
||||||
die "$errmsg"
|
|
||||||
fi;;
|
|
||||||
|
|
||||||
"replace" )
|
|
||||||
errmsg="usage: $0 replace ITEM# \"UPDATED ITEM\""
|
|
||||||
shift; item=$1; shift
|
|
||||||
|
|
||||||
[ -z "$item" ] && die "$errmsg"
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
|
|
||||||
todo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ -z "$todo" ] && die "$item: No such todo."
|
|
||||||
|
|
||||||
if [[ -z "$1" && $TODOTXT_FORCE = 0 ]]; then
|
|
||||||
echo -n "Replacement: "
|
|
||||||
read input
|
|
||||||
else
|
|
||||||
input=$*
|
|
||||||
fi
|
|
||||||
|
|
||||||
sed -i.bak $item" s|^.*|$input|" "$TODO_FILE"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && NEWTODO=$(head -$item "$TODO_FILE" | tail -1)
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "replaced with"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "$item: $NEWTODO"
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
"report" )
|
|
||||||
#archive first
|
|
||||||
sed '/^x /!d' "$TODO_FILE" >> "$DONE_FILE"
|
|
||||||
sed -i.bak '/^x /d' "$TODO_FILE"
|
|
||||||
|
|
||||||
NUMLINES=$( sed -n '$ =' "$TODO_FILE" )
|
|
||||||
if [ ${NUMLINES:-0} = "0" ]; then
|
|
||||||
echo "datetime todos dones" >> "$REPORT_FILE"
|
|
||||||
fi
|
|
||||||
#now report
|
|
||||||
TOTAL=$( sed -n '$ =' "$TODO_FILE" )
|
|
||||||
TDONE=$( sed -n '$ =' "$DONE_FILE" )
|
|
||||||
TECHO=$(echo $(date +%Y-%m-%d-%T); echo ' '; echo ${TOTAL:-0}; echo ' ';
|
|
||||||
echo ${TDONE:-0})
|
|
||||||
echo $TECHO >> "$REPORT_FILE"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: Report file updated."
|
|
||||||
cat "$REPORT_FILE"
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
* )
|
|
||||||
usage
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
8
todo.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
(A) Call Mom @Phone +Family
|
||||||
|
(A) Schedule annual checkup +Health
|
||||||
|
(B) Outline chapter 5 +Novel @Computer
|
||||||
|
(C) Add cover sheets @Office +TPSReports
|
||||||
|
Plan backyard herb garden @Home
|
||||||
|
Pick up milk @GroceryStore
|
||||||
|
Research self-publishing services +Novel @Computer
|
||||||
|
x Download Todo.txt mobile app @Phone
|
||||||