mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
Merge branch '1.8.0'
Conflicts: .gitignore AUTHORS ChangeLog DEVELOPERS Makefile.am NEWS README configure.ac doc/man/task.1 doc/man/taskrc.5 src/T.cpp src/T.h src/TDB.cpp src/TDB.h src/command.cpp src/edit.cpp src/import.cpp src/parse.cpp src/report.cpp src/rules.cpp src/task.cpp src/task.h task_completion.sh
This commit is contained in:
commit
90d53245c3
231 changed files with 16844 additions and 11820 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -5,11 +5,14 @@ config.h.in
|
|||
config.status
|
||||
src/.deps
|
||||
src/Makefile
|
||||
*/task
|
||||
*/*task
|
||||
stamp-h1
|
||||
Makefile
|
||||
Makefile.in
|
||||
configure
|
||||
config.log
|
||||
www.xls
|
||||
src/tests/all.log
|
||||
src/tests/*.data
|
||||
*~
|
||||
Makefile.in
|
||||
.*.swp
|
||||
|
|
15
AUTHORS
15
AUTHORS
|
@ -1,7 +1,10 @@
|
|||
Principal Author:
|
||||
Paul Beckingham
|
||||
The development of task was made possible by the significant contributions of the following people:
|
||||
Paul Beckingham (Principal Author)
|
||||
Federico Hernandez (Package Maintainer & Contributing Author)
|
||||
David J Patrick (Designer)
|
||||
John Florian (Contributing Author)
|
||||
|
||||
Contributing Authors:
|
||||
The following submitted code, packages or analysis, and deserve special thanks:
|
||||
Damian Glenny
|
||||
Andy Lester
|
||||
H. İbrahim Güngör
|
||||
|
@ -10,14 +13,12 @@ Contributing Authors:
|
|||
Benjamin Tegarden
|
||||
Chris Pride
|
||||
Richard Querin
|
||||
Federico Hernandez
|
||||
T. Charles Yun
|
||||
David J Patrick
|
||||
P.C. Shyamshankar
|
||||
Johan Friis
|
||||
Steven de Brouwer
|
||||
|
||||
With thanks to:
|
||||
Thanks to the following, who submitted detailed bug reports and excellent suggestions:
|
||||
Eugene Kramer
|
||||
Srijith K
|
||||
Bruce Israel
|
||||
|
@ -34,4 +35,6 @@ With thanks to:
|
|||
Bruce Dillahunty
|
||||
Askme Too
|
||||
Mike Adonay
|
||||
Thomas@BIC
|
||||
Ian Mortimer
|
||||
|
||||
|
|
83
ChangeLog
83
ChangeLog
|
@ -1,14 +1,83 @@
|
|||
|
||||
------ current release ---------------------------
|
||||
|
||||
1.8.0 (7/21/2009)
|
||||
+ Added zsh tab completion script (thanks to P.C. Shyamshankar).
|
||||
+ Fixed bug that cause the _forcecolor configuration variable to be
|
||||
considered obsolete (thank to Bruce Dillahunty).
|
||||
+ Fixed documentation errors (thanks to Thomas@BIC).
|
||||
+ The 'weekstart' configuration variable now controls the 'calendar'
|
||||
report (thanks to Federico Hernandez).
|
||||
+ The 'displayweeknumber' configuration variable now controls the display
|
||||
of week number in the 'calendar' report (thanks to Federico Hernandez).
|
||||
+ Supports '--' argument to indicate that all subsequence arguments are
|
||||
part of the description, despite what they otherwise might mean.
|
||||
+ Removed support for the obsolete task file format 1 (never released).
|
||||
+ Fixed bug that allowed blank annotations to be added (thanks to Bruce
|
||||
Dillahunty).
|
||||
+ Supports negative tag filters, so that (task list +foo -bar) now filters
|
||||
tasks that have the "foo" tag, but do not have the "bar" tag (thanks to
|
||||
Chris Pride).
|
||||
+ Custom reports now support a more compact form of the "age" column,
|
||||
called "age_compact" (thanks to T. Charles Yun).
|
||||
+ Supports 'rc.name:value' for a command line override to .taskrc data
|
||||
(thanks to Federico Hernandez).
|
||||
+ Removed obsolete DEVELOPERS file. The online support forums at
|
||||
http://taskwarrior.org will provide better information.
|
||||
+ Fixed bug that kept some deleted tasks showing up on the calendar report
|
||||
(thanks to Federico Hernandez).
|
||||
+ Now asks the user to confirm large changes if configuration variable
|
||||
'confirmation' is set to 'yes'. A large change is one that completely
|
||||
replaces a task description, or operates on a large number of tasks,
|
||||
which defaults to 4 but is configurable via the 'bulk' configuration
|
||||
variable (thanks to John Florian).
|
||||
+ Now echoes back the new task ID on 'add' (thanks to Bruce Dillahunty).
|
||||
+ The new "shell" command provides an interactive shell for task. All
|
||||
commands are supported (thanks to Bruce Dillahunty, Federico Hernandez,
|
||||
and John Florian).
|
||||
+ New "recurring" report to list all recurring tasks.
|
||||
+ New, more flexible, more consistent, grep-able file format.
|
||||
+ If task is renamed to "cal", or there is a symlink to task called "cal",
|
||||
then task can act as a replacement for the Unix "cal" command.
|
||||
+ Supports arguments to the cal command like "month year", "year", etc.
|
||||
+ The "tags" report now shows the tag usage count.
|
||||
+ The "projects" report now shows totals by project and priority.
|
||||
+ Now supports attribute modifiers that allow much finer control over report
|
||||
filtering, for example "task list due.before:friday", or "task list
|
||||
pri.not:H" and many more.
|
||||
+ Now supports new "age_compact" and "wait" custom report columns.
|
||||
+ Now supports colorization of the header and footnote messages that are
|
||||
printed before and after report output, with the 'color.header' and
|
||||
'color.footnote' configuration variables.
|
||||
+ Now supports the 'limit' attribute, to control the number of tasks that
|
||||
are shown, for example: "task list limit:10".
|
||||
+ Now supports a debug mode that can be used to generate helpful information
|
||||
when reporting a problem. Just run the command with "task rc.debug:on ..."
|
||||
and diagnostics will be generated that will help pinpoint a problem.
|
||||
+ The new "undo" command replaces the old "undo" and "undelete" command
|
||||
with a complete undo stack that can rollback all changes.
|
||||
+ While waiting for a file lock, task states the reason for the delay.
|
||||
+ Now supports a 'waiting' state that causes tasks to not appear until
|
||||
a certain date, for example "task <ID> wait:<date>". The task
|
||||
will then not show up on any report (except 'all') until that date.
|
||||
+ The "active", "completed", "overdue" and "next" reports are now custom
|
||||
reports, and therefore modifiable.
|
||||
+ Now supports a 'waiting' custom report to list all waiting tasks.
|
||||
+ Now supports a 'recurring' custom report to list all recurring tasks.
|
||||
+ Now supports an 'all' report to list all tasks, including deleted
|
||||
+ Supports command aliases - create an alias for any command by creating
|
||||
a .taskrc entry like "alias.new_name=old_name".
|
||||
and completed tasks.
|
||||
+ Now over 1,600 unit tests, helping to maintain code quality.
|
||||
|
||||
------ old releases ------------------------------
|
||||
|
||||
1.7.1 (6/8/2009)
|
||||
+ Fixed build failure on OpenBSD (thanks to Mike Adonay).
|
||||
+ Took the opportunity of a patch release to update the various email
|
||||
addresses and URLs in the various documents.
|
||||
|
||||
------ old releases ------------------------------
|
||||
|
||||
1.7.0 (5/14/2009)
|
||||
1.7.0 (5/14/2009) f6b8b39d8b4a85c30a457e9e78b582b74531bfe4
|
||||
+ Improved the errors when parsing a corrupt or unrecognized pending.data
|
||||
or completed.data file (thanks to T. Charles Yun).
|
||||
+ Added details to the "info" report about recurring tasks (thanks to T.
|
||||
|
@ -38,8 +107,8 @@
|
|||
to /usr/local/share/task (thanks to Federico Hernandez).
|
||||
+ Applied patch to allow task to build on Arch Linux (thanks to Johan Friis).
|
||||
+ Applied patch to fix a UUID bug on Solaris 8 (thanks to Steven de Brouwer).
|
||||
+ The task man page is now installed. Try "man task" (thanks to Federico
|
||||
Hernandez and P.C. Shyamshankar).
|
||||
+ The task and taskrc man pages are here. Try "man task", "man taskrc"
|
||||
(thanks to Federico Hernandez and P.C. Shyamshankar).
|
||||
+ Fixed bug that causes task to create a default .task directory, even if
|
||||
data.location specified otherwise (thanks to Federico Hernandez).
|
||||
+ New "edit" command that fires up a text editor (uses 'editor' configuration
|
||||
|
@ -287,7 +356,7 @@
|
|||
+ Made unit tests compile and run again.
|
||||
+ Removed tests from distibution.
|
||||
|
||||
0.9.6 (5/13/208)
|
||||
0.9.6 (5/13/2008)
|
||||
+ Corrected wrong include file in Table.cpp.
|
||||
+ Replaced color management code.
|
||||
+ Improved color rules code.
|
||||
|
@ -334,7 +403,7 @@
|
|||
+ Rules-based colorization.
|
||||
|
||||
0.8.1 (1/28/2008) - 0.8.16 (3/13/2008)
|
||||
+ autoconf conversion (many builds).
|
||||
+ autoconf conversion
|
||||
|
||||
0.8.0 Polish (1/25/2008)
|
||||
+ Code cleanup, reorganization.
|
||||
|
|
22
DEVELOPERS
22
DEVELOPERS
|
@ -1,22 +0,0 @@
|
|||
Developers may wish to change task, and here is a high-level guide to the files
|
||||
included.
|
||||
|
||||
task.{cpp,h} Implements main, high level processing.
|
||||
command.cpp Implements all non-report task commands.
|
||||
report.cpp Implements all task reports.
|
||||
parse.cpp Parses the command line.
|
||||
TDB.{cpp,h} The task database, performs all file I/O.
|
||||
T.{cpp,h} Represents a single task - parses a record from TDB, and also
|
||||
composes record for TDB. Provides accessors for tasks.
|
||||
Grid.{cpp,h} Implements a sparse 2D array, provides data storage for the
|
||||
Table object.
|
||||
Table.{cpp,h} Implements tabular data rendering, wrapping etc.
|
||||
Config.{cpp,h} Implements a reader for the .taskrc file.
|
||||
Date.{cpp,h} General date class for the time_t type.
|
||||
text.cpp Text manipulation functions.
|
||||
util.cpp General utility functions.
|
||||
color.cpp Color support functions.
|
||||
rules.cpp Auto-colorization rules.
|
||||
|
||||
Please send bugs, patches to support@taskwarrior.org
|
||||
|
24
Makefile.am
24
Makefile.am
|
@ -1,6 +1,20 @@
|
|||
SUBDIRS = src
|
||||
EXTRA_DIST = task_completion.sh doc/man1/task.1 doc/man5/taskrc.5
|
||||
man1_MANS = doc/man1/task.1
|
||||
man5_MANS = doc/man5/taskrc.5
|
||||
otherdir = $(datadir)/doc/task-$(VERSION)
|
||||
other_DATA = AUTHORS ChangeLog COPYING INSTALL NEWS README task_completion.sh
|
||||
|
||||
dist_man_MANS = doc/man/task.1 doc/man/taskrc.5 doc/man/task-tutorial.5
|
||||
|
||||
docdir = $(datadir)/doc/${PACKAGE}-${VERSION}
|
||||
doc_DATA = AUTHORS ChangeLog COPYING NEWS README
|
||||
|
||||
EXTRA_DIST = INSTALL
|
||||
|
||||
bashscriptsdir = $(docdir)
|
||||
nobase_dist_bashscripts_DATA = scripts/bash/task_completion.sh
|
||||
|
||||
zshscriptsdir = $(docdir)
|
||||
nobase_dist_zshscripts_DATA = scripts/zsh/_task
|
||||
|
||||
vimscriptsdir = $(docdir)
|
||||
nobase_dist_vimscripts_DATA = scripts/vim/README scripts/vim/ftdetect/task.vim scripts/vim/syntax/taskdata.vim scripts/vim/syntax/taskedit.vim
|
||||
|
||||
i18ndir = $(docdir)
|
||||
nobase_dist_i18n_DATA = i18n/strings.de-DE i18n/strings.en-US i18n/strings.es-ES i18n/strings.fr-FR i18n/strings.nl-NL i18n/strings.sv-SE i18n/tips.de-DE i18n/tips.en-US i18n/tips.sv-SE
|
||||
|
|
55
NEWS
55
NEWS
|
@ -1,43 +1,48 @@
|
|||
Welcome to Task 1.7.1.
|
||||
|
||||
New Features in task 1.8.0
|
||||
|
||||
- Attribute modifiers, for precise queries
|
||||
- Improved calendar feature
|
||||
- Full undo capability
|
||||
- All reports now customizable
|
||||
- Command aliases can now be created
|
||||
- In addition to being a standard part of Fedora 10 and 11 (yum install task),
|
||||
task is now also a standard part of Cygwin 1.5
|
||||
- There are new demo movies on taskwarrior.org
|
||||
|
||||
Please refer to the ChangeLog file for full details. There are too many to
|
||||
list here.
|
||||
|
||||
Task has been built and tested on the following configurations:
|
||||
|
||||
- OS X 10.4 Tiger
|
||||
- OS X 10.5 Leopard
|
||||
- Fedora Core 8
|
||||
- Fedora Core 9
|
||||
- Fedora Core 10
|
||||
- Ubuntu 7 Feisty Fawn
|
||||
- Ubuntu 8 Hardy Heron
|
||||
- Ubuntu 8.10 Intrepid Ibex
|
||||
- OS X 10.4 Tiger
|
||||
- Fedora Core 11 Leonidas
|
||||
- Fedora Core 10 Cambridge
|
||||
- Ubuntu 9.04 Jaunty Jackalope
|
||||
- Ubuntu 8.10 Intrepid Ibex
|
||||
- Ubuntu 8.04 Hardy Heron
|
||||
- Slackware 12.2
|
||||
- Arch Linux
|
||||
- OpenBSD 4.5
|
||||
- Solaris 8
|
||||
- Solaris 10
|
||||
- Solaris 8
|
||||
- OpenBSD 4.5
|
||||
- FreeBSD
|
||||
- Cygwin 1.5.25-14
|
||||
|
||||
While Task has undergone testing, bugs are sure to remain. If you encounter a
|
||||
bug, please contact me at support@taskwarrior.org. Here is what you could do, in
|
||||
order of increasing effort (to you) and usefulness (to me):
|
||||
bug, please enter a new issue at:
|
||||
|
||||
- Do nothing. Bug probably won't get fixed.
|
||||
http://taskwarrior.org/projects/taskwarrior/issues/new
|
||||
|
||||
- Send an email to support@taskwarrior.org, explaining what you saw. The bug
|
||||
will be addressed, and a new release will be made. You will be a hero.
|
||||
Or you can also report the issue in the forums at:
|
||||
|
||||
- Send an email, and a reproducible test case in the form of the few commands
|
||||
it takes to recreate the problem. The bug will be addressed, and a new
|
||||
release will be made. You will be a hero.
|
||||
http://taskwarrior.org/projects/taskwarrior/boards
|
||||
|
||||
- If you are a developer, send a patch that fixes the problem. Your patch
|
||||
will be applied and tested, and a new release will be made. You will be a
|
||||
hero.
|
||||
Or just send a message to:
|
||||
|
||||
- Another option involves using the taskwarrior.org issue tracker, which can
|
||||
be found at http://taskwarrior.org/projects/taskwarrior/issues/new which has
|
||||
the advantage that everyone gets to see and track the issue. You will still
|
||||
be a hero.
|
||||
support@taskwarrior.org
|
||||
|
||||
Thank you.
|
||||
|
||||
---
|
||||
|
|
61
README
61
README
|
@ -1,51 +1,24 @@
|
|||
Thank you for taking a look at task. Task is a GTD utility featuring:
|
||||
|
||||
- Robust C++ implementation
|
||||
- Tags
|
||||
- Colorful, tabular output
|
||||
- Reports, graphs
|
||||
- Lots of commands
|
||||
- Low-level API
|
||||
- Abbreviations for all commands, options
|
||||
- Multi-user file locking
|
||||
- Clean architecture allowing quick addition of new features
|
||||
- Recurring tasks
|
||||
Thank you for taking a look at task!
|
||||
|
||||
It is intended that features, mainly in the form of reports will be added
|
||||
frequently, with best practices and useful reports evolving from usage patterns.
|
||||
|
||||
Task is scope-limited to GTD-like functionality only.
|
||||
|
||||
You may want to watch the old task movie on YouTube:
|
||||
|
||||
http://www.youtube.com/watch?v=l68LCl6BYvs
|
||||
|
||||
or the new improved one:
|
||||
|
||||
http://www.youtube.com/watch?v=D2Kn4DMOVSw
|
||||
|
||||
Either will give you a fairly good idea of what task is capable of, and
|
||||
whether it fits in to your way of working. As a command line application,
|
||||
task is not for everyone and some of you may prefer to not proceed. The
|
||||
movie or online tutorial file are the quickest way for you to make that
|
||||
decision. The online tutorial can be found at:
|
||||
|
||||
http://taskwarrior.org/wiki/taskwarrior/Simple
|
||||
|
||||
Task has many more features than todo.sh, but fundamentally, they are
|
||||
both working toward the same goals, which is to help you follow basic
|
||||
Getting Things Done (GTD) principles.
|
||||
|
||||
All feedback is welcome, in addition to any bug reports or patches to:
|
||||
|
||||
support@taskwarrior.org
|
||||
|
||||
Or better yet, get involved in the discussion at
|
||||
Task is a GTD, todo list, task management, command line utility with a multitude
|
||||
of features. It is a portable, well supported, very active project, and it is
|
||||
Open Source. Task has binary distributions, online documentation, demonstration
|
||||
movies, and you'll find all the details at the site:
|
||||
|
||||
http://taskwarrior.org
|
||||
|
||||
Got an idea for an enhancement? Post a message!
|
||||
At the site you'll find a wiki, discussion forums, downloads, news and more.
|
||||
|
||||
We have found that task makes me more productive and organized.
|
||||
We hope task can do the same for you.
|
||||
|
||||
Your contributions are especially welcome. Whether it comes in the form of
|
||||
code patches, ideas, discussion, bug reports or just encouragement, your input
|
||||
is needed.
|
||||
|
||||
Please send your support questions and code patches to:
|
||||
|
||||
support@taskwarrior.org
|
||||
|
||||
Consider joining taskwarrior.org and participating in the future of task.
|
||||
|
||||
---
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
Thank you for taking a look at task. Task is a GTD utility featuring:
|
||||
|
||||
- Robust C++ implementation
|
||||
- Tags
|
||||
- Colorful, tabular output
|
||||
- Reports, graphs
|
||||
- Lots of commands
|
||||
- Low-level API
|
||||
- Abbreviations for all commands, options
|
||||
- Multi-user file locking
|
||||
- Clean architecture allowing quick addition of new features
|
||||
- Recurring tasks
|
||||
|
||||
It is intended that features, mainly in the form of reports will be added
|
||||
frequently, with best practices and useful reports evolving from usage patterns.
|
||||
|
||||
Task is scope-limited to GTD functionality only.
|
||||
|
||||
You may want to watch the old task movie on YouTube:
|
||||
|
||||
http://www.youtube.com/watch?v=l68LCl6BYvs
|
||||
|
||||
or the new improved one:
|
||||
|
||||
http://www.youtube.com/watch?v=D2Kn4DMOVSw
|
||||
|
||||
Either will give you a fairly good idea of what task is capable of, and
|
||||
whether it fits in to your way of working. As a command line application,
|
||||
task is not for everyone and some of you may prefer to not proceed. The
|
||||
movie or online tutorial file are the quickest way for you to make that
|
||||
decision. The online tutorial can be found at:
|
||||
|
||||
http://www.beckingham.net/task.html
|
||||
|
||||
Task is based on ideas presented in the todo.sh script, found on:
|
||||
|
||||
http://todotxt.org
|
||||
|
||||
Task has many more features than todo.sh, but fundamentally, they are
|
||||
both working toward the same goals, which is to help you follow basic
|
||||
Getting Things Done (GTD) principles.
|
||||
|
||||
All feedback is welcome, in addition to any bug reports or patches to:
|
||||
|
||||
task@beckingham.net
|
||||
|
||||
Got an idea for an enhancement? Send a message!
|
||||
|
||||
I have found that task makes me more productive and organized.
|
||||
I hope task can do the same for you.
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
Adding New Command Checklist
|
||||
----------------------------
|
||||
|
||||
- Create new handler in command.cpp or report.cpp.
|
||||
- Add prototype to task.h.
|
||||
- Add call to appropriate section in task.cpp.
|
||||
- Add usage info in task.cpp.
|
||||
- Add command name to list in parse.cpp.
|
||||
- Add unit tests in src/tests.
|
||||
- Add new configuration details to html/config.html.
|
||||
- Add command details to html/advanced.html.
|
||||
- Add description to ChangeLog, with attribution if the idea
|
||||
came from a single user, but not if it came from multiple
|
||||
users.
|
||||
- Add description to html/task.html.
|
||||
|
||||
|
||||
|
||||
Release Checklist
|
||||
-----------------
|
||||
|
||||
- Update "Upcoming Features" document on group
|
||||
- Ensure all unit tests pass on OS X
|
||||
- Ensure clean build on OS X
|
||||
- Make a source package (1)
|
||||
- Ensure clean build on latest Fedora Core from source package
|
||||
- Git clone and rebuild, ensure all unit tests pass
|
||||
- Ensure clean build on latest Ubuntu from source package
|
||||
- Git clone and rebuild, ensure all unit tests pass
|
||||
- Ensure clean build on Windows/Cygwin from source package
|
||||
- Git clone and rebuild, ensure all unit tests pass
|
||||
- Make a new source package (2)
|
||||
- Add actual release date to ChangeLog
|
||||
- Add actual release date to html/task.html
|
||||
- Merge version branch to master
|
||||
- Tag master
|
||||
- Make a new source package (3)
|
||||
- Send source package to package maintainer
|
||||
- Make OS X .pkg package
|
||||
- Wait for all packages
|
||||
- Upload all packages to website
|
||||
- Upload all docs to website
|
||||
- Send announcement to group
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.61)
|
||||
AC_INIT(task, 1.7.1, support@taskwarrior.org)
|
||||
AC_INIT(task, 1.8.0, support@taskwarrior.org)
|
||||
|
||||
CFLAGS="${CFLAGS=}"
|
||||
CXXFLAGS="${CXXFLAGS=}"
|
||||
|
@ -10,7 +10,7 @@ CXXFLAGS="${CXXFLAGS=}"
|
|||
# to the configure script (./configure --enable-debug)
|
||||
# Check if we have enable debug support.
|
||||
AC_MSG_CHECKING(whether to enable debugging)
|
||||
debug_default="yes"
|
||||
debug_default="no"
|
||||
AC_ARG_ENABLE(debug, [ --enable-debug=[no/yes] turn on debugging
|
||||
[default=$debug_default]],, enable_debug=$debug_default)
|
||||
# Yes, shell scripts can be used
|
||||
|
@ -33,7 +33,7 @@ else
|
|||
fi
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
AC_CONFIG_SRCDIR([src/task.cpp])
|
||||
AC_CONFIG_SRCDIR([src/main.cpp])
|
||||
AC_CONFIG_HEADER([auto.h])
|
||||
|
||||
# Checks for programs.
|
||||
|
|
394
doc/man/task-tutorial.5
Normal file
394
doc/man/task-tutorial.5
Normal file
|
@ -0,0 +1,394 @@
|
|||
.TH task-tutorial 5 2009-07-14 "Task 1.8.0" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
task-tutorial \- A tutorial for the task(1) command line todo manager.
|
||||
|
||||
.SH DESCRIPTION
|
||||
Task is a command line TODO list manager. It maintains a list of tasks that you
|
||||
want to do, allowing you to add/remove, and otherwise manipulate them. Task
|
||||
has a rich list of subcommands that allow you to do various things with it.
|
||||
|
||||
.SH 30 second tutorial
|
||||
|
||||
For the excessively lazy. Add two tasks:
|
||||
.br
|
||||
.RS
|
||||
$ task add Read task documents later
|
||||
.br
|
||||
$ task add priority:H Pay bills
|
||||
.RE
|
||||
|
||||
Easy. See that second one has a High priority? Now let's look at those tasks:
|
||||
.br
|
||||
.RS
|
||||
$ task ls
|
||||
.br
|
||||
ID Project Pri Description
|
||||
.br
|
||||
2 H Pay bills
|
||||
.br
|
||||
1 Read task documents later
|
||||
.RE
|
||||
|
||||
They are ordered by priority. Let's mark number 2 as done:
|
||||
.br
|
||||
.RS
|
||||
$ task 2 done
|
||||
.br
|
||||
$ task ls
|
||||
.br
|
||||
ID Project Pri Description
|
||||
.br
|
||||
1 Read task documents later
|
||||
.RE
|
||||
|
||||
Gone. Now let's delete that remaining task, because, well, why bother
|
||||
now we are already using task:
|
||||
.br
|
||||
.RS
|
||||
$ task delete 1
|
||||
.br
|
||||
$ task ls
|
||||
.br
|
||||
No matches
|
||||
.RE
|
||||
|
||||
Easy. But now consider checking out what task can really do...
|
||||
|
||||
.SH Simple usage of task
|
||||
Let us begin by adding some tasks:
|
||||
.br
|
||||
.RS
|
||||
$ task add Book plane ticket
|
||||
.br
|
||||
$ task add Rent a tux
|
||||
.br
|
||||
$ task add Reserve a rental car
|
||||
.br
|
||||
$ task add Reserve a hotel room
|
||||
.RE
|
||||
|
||||
That's it. You'll notice immediately that task has a very minimalist
|
||||
interface. Let us take a look at those tasks:
|
||||
.br
|
||||
.RS
|
||||
$ task ls
|
||||
.br
|
||||
ID Project Pri Description
|
||||
.br
|
||||
1 Book plane ticket
|
||||
.br
|
||||
2 Rent a tux
|
||||
.br
|
||||
3 Reserve a rental car
|
||||
.br
|
||||
4 Send John a birthday card
|
||||
.RE
|
||||
|
||||
The 'ls' command provides the most minimal list of tasks. Each task has
|
||||
been given an id number, and you can see that there are no projects or
|
||||
priorities assigned. Wait a minute - I own a tux, I don't need to rent
|
||||
one. Let us delete task 2:
|
||||
.br
|
||||
.RS
|
||||
$ task 2 delete
|
||||
.br
|
||||
Permanently delete task? (y/n) y
|
||||
.RE
|
||||
|
||||
Task wants you to confirm deletions. To remove the confirmation, edit
|
||||
your .taskrc file and change the line:
|
||||
.br
|
||||
.RS
|
||||
confirmation=yes
|
||||
.RE
|
||||
.br
|
||||
to have a value of "no".
|
||||
|
||||
While the use of projects and priorities are not essential to benefiting
|
||||
from task, they can be very useful when the list of tasks grows large.
|
||||
Let's assign a project to these tasks:
|
||||
.br
|
||||
.RS
|
||||
$ task 1 project:Wedding
|
||||
.br
|
||||
$ task 3 project:Wedding
|
||||
.br
|
||||
$ task 4 project:Family
|
||||
.br
|
||||
$ task ls
|
||||
.br
|
||||
ID Project Pri Description
|
||||
.br
|
||||
3 Family Send John a birthday card
|
||||
.br
|
||||
2 Wedding Reserve a rental car
|
||||
.br
|
||||
1 Wedding Book plane ticket
|
||||
.RE
|
||||
|
||||
Notice that the id numbers have changed. When tasks get deleted, or have
|
||||
their attributes changed (project, for example), the ids are prone to change.
|
||||
But the id numbers will remain valid until the next 'ls' command is run.
|
||||
You should only use the ids from the most recent 'ls' command. The ids change,
|
||||
because task is always trying to use small numbers so that it is easy for you
|
||||
to enter them correctly. Now that projects are assigned, we can look at just
|
||||
the Wedding project tasks:
|
||||
|
||||
Subprojects are supported. If you have a project "Wedding", you can specify
|
||||
that a task is a subproject "Transport" of "Wedding" by assigning the project
|
||||
"Wedding.Transport". Let's do this:
|
||||
.br
|
||||
.RS
|
||||
$ task 2 project:Wedding.Transport
|
||||
.br
|
||||
$ task ls
|
||||
.br
|
||||
ID Project Pri Description
|
||||
.br
|
||||
3 Family Send John a birthday card
|
||||
.br
|
||||
2 Wedding.Transport Reserve a rental car
|
||||
.br
|
||||
1 Wedding Book plane ticket
|
||||
.RE
|
||||
|
||||
Task matches the leftmost part of the project when searching, so projects may
|
||||
be abbreviated:
|
||||
.br
|
||||
.RS
|
||||
$ task ls project:Wedding.Tra
|
||||
.br
|
||||
ID Project Pri Description
|
||||
.br
|
||||
2 Wedding.Transport Reserve a rental car
|
||||
.RE
|
||||
|
||||
This way of matching projects can be used to see all tasks under the "Wedding"
|
||||
project and all subprojects:
|
||||
.br
|
||||
.RS
|
||||
$ task ls project:Wedding
|
||||
.br
|
||||
ID Project Pri Description
|
||||
.br
|
||||
2 Wedding.Transport Reserve a rental car
|
||||
.br
|
||||
1 Wedding Book plane ticket
|
||||
.RE
|
||||
|
||||
Let's reassign 2 back to the "Wedding" project:
|
||||
.br
|
||||
.RS
|
||||
$ task 2 project:Wedding
|
||||
.RE
|
||||
|
||||
Now that projects are assigned, we can look at just the Wedding project tasks:
|
||||
.br
|
||||
.RS
|
||||
$ task ls project:Wedding
|
||||
.br
|
||||
ID Project Pri Description
|
||||
.br
|
||||
1 Wedding Book plane ticket
|
||||
.br
|
||||
2 Wedding Reserve a rental car
|
||||
.RE
|
||||
|
||||
Any command arguments after the 'ls' are used for filtering the output.
|
||||
We could also have requested:
|
||||
.br
|
||||
.RS
|
||||
$ task ls ticket plane
|
||||
.br
|
||||
ID Project Pri Description
|
||||
.br
|
||||
1 Wedding Book plane ticket
|
||||
.RE
|
||||
|
||||
Now let's prioritize. Priorities can be H, M or L (High, Medium, Low).
|
||||
.br
|
||||
.RS
|
||||
$ task ls
|
||||
.br
|
||||
ID Project Pri Description
|
||||
.br
|
||||
3 Family Send John a birthday card
|
||||
.br
|
||||
2 Wedding Reserve a rental car
|
||||
.br
|
||||
1 Wedding Book plane ticket
|
||||
.br
|
||||
$ task 1 priority:H
|
||||
.br
|
||||
$ task 2 prior:M
|
||||
.br
|
||||
$ task 3 pr:H
|
||||
.br
|
||||
Ambiguous attribute 'pr' - could be either of project, priority
|
||||
.br
|
||||
$ task 3 pri:H
|
||||
.br
|
||||
$ task ls
|
||||
.br
|
||||
ID Project Pri Description
|
||||
.br
|
||||
3 Family H Send John a birthday card
|
||||
.br
|
||||
1 Wedding H Book plane ticket
|
||||
.br
|
||||
2 Wedding M Reserve a rental car
|
||||
.RE
|
||||
|
||||
Notice that task supports the abbreviation of words such as priority,
|
||||
project. Priority can be abbreviated to pri, but not pr, because it
|
||||
is ambiguous. Now that tasks have been prioritized, you can see that
|
||||
the tasks are being sorted by priority, with the highest priority
|
||||
tasks at the top.
|
||||
|
||||
These attributes can all be provided when the task is added, instead of
|
||||
applying them afterwards, as shown. The following command shows how to
|
||||
set all the attributes at once:
|
||||
.br
|
||||
.RS
|
||||
$ task add project:Wedding priority:H Book plane ticket
|
||||
.RE
|
||||
|
||||
The 'ls' command provides the least information for each task. The 'list'
|
||||
command provides more:
|
||||
.br
|
||||
.RS
|
||||
$ task list
|
||||
.br
|
||||
ID Project Pri Due Active Age Description
|
||||
.br
|
||||
3 Family H 4 mins Send John a birthday card
|
||||
.br
|
||||
1 Wedding H 5 mins Book plane ticket
|
||||
.br
|
||||
2 Wedding M 5 mins Reserve a rental car
|
||||
.RE
|
||||
|
||||
Notice that a task can have a due date, and can be active. The task lists are
|
||||
sorted by due date, then priority. Let's add due dates:
|
||||
.br
|
||||
.RS
|
||||
$ task 3 due:6/25/2008
|
||||
.br
|
||||
$ task 1 due:7/31/2008
|
||||
.br
|
||||
$ task list
|
||||
.br
|
||||
ID Project Pri Due Active Age Description
|
||||
.br
|
||||
3 Family H 6/25/2008 6 mins Send John a birthday card
|
||||
.br
|
||||
1 Wedding H 7/31/2008 7 mins Book plane ticket
|
||||
.br
|
||||
2 Wedding M 7 mins Reserve a rental car
|
||||
.RE
|
||||
|
||||
If today's date is 6/23/2008, then task 3 is due in 2 days. It will be colored
|
||||
yellow if your terminal supports color. To change this color, edit your .taskrc
|
||||
file, and change the line to one of these alternatives:
|
||||
.br
|
||||
.RS
|
||||
color.due=red
|
||||
.br
|
||||
color.due=on_blue
|
||||
.br
|
||||
color.due=red on_blue
|
||||
.br
|
||||
color.due=bold_red on_blue
|
||||
.RE
|
||||
|
||||
Where color is one of the following:
|
||||
|
||||
.br
|
||||
.RS
|
||||
black, blue, red, green, cyan, magenta, yellow or white
|
||||
.RE
|
||||
|
||||
All colors are specified in this way. Take a look in .taskrc for all the other
|
||||
color rules that you control.
|
||||
|
||||
Tagging tasks is a good way to group them, aside from specifying a project.
|
||||
To add a tag to a task:
|
||||
.br
|
||||
.RS
|
||||
$ task <id> +tag
|
||||
.RE
|
||||
|
||||
The plus sign indicates that this is a tag. Any number of tags may be applied to a
|
||||
task, and then used for searching. Tags are just single words that are labels.
|
||||
.br
|
||||
.RS
|
||||
$ task list
|
||||
.br
|
||||
ID Project Pri Due Active Age Description
|
||||
.br
|
||||
3 Family H 6/25/2008 8 mins Send John a birthday card
|
||||
.br
|
||||
1 Wedding H 7/31/2008 9 mins Book plane ticket
|
||||
.br
|
||||
2 Wedding M 9 mins Reserve a rental car
|
||||
.br
|
||||
$ task 1 +phone
|
||||
.br
|
||||
$ task 2 +phone
|
||||
.br
|
||||
$ task 3 +shopping
|
||||
.br
|
||||
$ task 3 +john
|
||||
.br
|
||||
$ task list +phone
|
||||
.br
|
||||
ID Project Pri Due Active Age Description
|
||||
.br
|
||||
1 Wedding H 7/31/2008 9 mins Book plane ticket
|
||||
.br
|
||||
2 Wedding M 9 mins Reserve a rental car
|
||||
.RE
|
||||
|
||||
To remove a tag from a task, use the minus sign:
|
||||
.br
|
||||
.RS
|
||||
$ task 3 \-john
|
||||
.RE
|
||||
|
||||
.SH Advanced usage of task
|
||||
Advanced examples of the usage of task can be found at
|
||||
the official site at <http://taskwarrior.org>
|
||||
|
||||
.SH "CREDITS & COPYRIGHTS"
|
||||
task was written by P. Beckingham <paul@beckingham.net>.
|
||||
.br
|
||||
Copyright (C) 2006 \- 2009 P. Beckingham
|
||||
|
||||
This man page was originally written by Federico Hernandez.
|
||||
|
||||
task is distributed under the GNU General Public License. See
|
||||
http://www.gnu.org/licenses/gpl-2.0.txt for more information.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR task(1),
|
||||
.BR taskrc(5)
|
||||
|
||||
For more information regarding task, the following may be referenced:
|
||||
|
||||
.TP
|
||||
The official site at
|
||||
<http://taskwarrior.org>
|
||||
|
||||
.TP
|
||||
The official code repository at
|
||||
<http://github.com/pbeckingham/task/>
|
||||
|
||||
.TP
|
||||
You can contact the project by writing an email to
|
||||
<support@taskwarrior.org>
|
||||
|
||||
.SH REPORTING BUGS
|
||||
.TP
|
||||
Bugs in task may be reported to the issue-tracker at
|
||||
<http://taskwarrior.org>
|
|
@ -1,4 +1,4 @@
|
|||
.TH task 1 2009-05-14 "Task 1.7.1" "User Manuals"
|
||||
.TH task 1 2009-07-14 "Task 1.8.0" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
task \- A command line todo manager.
|
||||
|
@ -7,7 +7,7 @@ task \- A command line todo manager.
|
|||
.B task [subcommand] [args]
|
||||
|
||||
.SH DESCRIPTION
|
||||
Task is a command line TODO list manager. It maintains a list of tasks that you
|
||||
Task is a command line todo list manager. It maintains a list of tasks that you
|
||||
want to do, allowing you to add/remove, and otherwise manipulate them. Task
|
||||
has a rich list of subcommands that allow you to do various things with it.
|
||||
|
||||
|
@ -26,22 +26,30 @@ task.
|
|||
.B annotate ID description
|
||||
Adds an annotation to an existing task.
|
||||
|
||||
.TP
|
||||
.B completed [tags] [attrs] description
|
||||
Provides a chronological listing of all completed tasks matching specified
|
||||
criteria.
|
||||
|
||||
.TP
|
||||
.B ID [tags] [attrs] [description]
|
||||
Modifies the existing task with provided information.
|
||||
|
||||
.TP
|
||||
.B ID /from/to/
|
||||
Performs one substitution on task description for fixing mistakes.
|
||||
Performs one substitution on task description and annotation for fixing mistakes.
|
||||
|
||||
.TP
|
||||
.B ID /from/to/g
|
||||
Performs all substitutions on task description for fixing mistakes.
|
||||
Performs all substitutions on task description and annotation for fixing mistakes.
|
||||
|
||||
.TP
|
||||
.B edit ID
|
||||
Launches an editor to let you modify all aspects of a task directly.
|
||||
Use carefully.
|
||||
|
||||
.TP
|
||||
.B undo
|
||||
Reverts the most recent action.
|
||||
|
||||
.TP
|
||||
.B shell
|
||||
Launches an interactive shell with all the task commands available.
|
||||
|
||||
.TP
|
||||
.B duplicate ID [tags] [attrs] [description]
|
||||
|
@ -51,10 +59,6 @@ Duplicates the specified task and allows modifications.
|
|||
.B delete ID
|
||||
Deletes the specified task from task list.
|
||||
|
||||
.TP
|
||||
.B undelete ID
|
||||
Undeletes the specified task, provided a report has not yet been run.
|
||||
|
||||
.TP
|
||||
.B info ID
|
||||
Shows all data and metadata for the specified task.
|
||||
|
@ -73,10 +77,6 @@ time from the specified task.
|
|||
.B done ID [tags] [attrs] [description]
|
||||
Marks the specified task as done.
|
||||
|
||||
.TP
|
||||
.B undo ID
|
||||
Marks the specified task as pending, provided a report has not yet been run.
|
||||
|
||||
.TP
|
||||
.B projects
|
||||
Lists all project names used, and the number of tasks for each.
|
||||
|
@ -102,21 +102,9 @@ Shows a report of task history by month.
|
|||
Shows a graphical report of task status by month.
|
||||
|
||||
.TP
|
||||
.B next
|
||||
Shows the most important pending tasks for each project.
|
||||
|
||||
.TP
|
||||
.B calendar
|
||||
.B calendar [ y | due [y] | month year [y] | year ]
|
||||
Shows a monthly calendar with due tasks marked.
|
||||
|
||||
.TP
|
||||
.B active
|
||||
Shows all tasks that are started but not completed.
|
||||
|
||||
.TP
|
||||
.B overdue
|
||||
Shows all incomplete tasks that are beyond their due date.
|
||||
|
||||
.TP
|
||||
.B stats
|
||||
Shows task database statistics.
|
||||
|
@ -145,8 +133,22 @@ Shows the long usage text.
|
|||
.SH REPORT SUBCOMMANDS
|
||||
|
||||
A report is a listing of information from the task database. There are several
|
||||
built-in reports currently in task. The output and sort behaviour of these
|
||||
subcommands can be configured in the configuration file.
|
||||
reports currently predefined in task. The output and sort behavior of these
|
||||
reports can be configured in the configuration file. See also the man page taskrc(5).
|
||||
|
||||
.TP
|
||||
.B active [tags] [attrs] [description]
|
||||
Shows all tasks matching the specified criteria
|
||||
that are started but not completed.
|
||||
|
||||
.TP
|
||||
.B all [tags] [attrs] [description]
|
||||
Shows all tasks matching the specified criteria.
|
||||
|
||||
.TP
|
||||
.B completed [tags] [attrs] [description]
|
||||
Shows all tasks matching the specified criteria
|
||||
that are completed.
|
||||
|
||||
.TP
|
||||
.B ls [tags] [attrs] [description]
|
||||
|
@ -161,13 +163,30 @@ Provides a more detailed listing of tasks with specified criteria.
|
|||
Provides the most detailed listing of tasks with specified criteria.
|
||||
|
||||
.TP
|
||||
.B newest [tags] [attrs] [description] | newest [limit]
|
||||
.B newest [tags] [attrs] [description]
|
||||
Shows the newest tasks with specified criteria.
|
||||
|
||||
.TP
|
||||
.B oldest [tags] [attrs] [description] | oldest [limit]
|
||||
.B oldest [tags] [attrs] [description]
|
||||
Shows the oldest tasks with specified criteria
|
||||
|
||||
.TP
|
||||
.B overdue [tags] [attrs] [description]
|
||||
Shows all incomplete tasks matching the specified criteria
|
||||
that are beyond their due date.
|
||||
|
||||
.TP
|
||||
.B recurring [tags] [attrs] [description]
|
||||
Shows all recurring tasks matching the specified criteria.
|
||||
|
||||
.TP
|
||||
.B waiting [tags] [attrs] [description]
|
||||
Shows all waiting tasks matching the specified criteria.
|
||||
|
||||
.TP
|
||||
.B next [tags] [attrs] [description]
|
||||
Shows all tasks with upcoming due dates matching the specified criteria.
|
||||
|
||||
.SH ATTRIBUTES AND METADATA
|
||||
|
||||
.TP
|
||||
|
@ -175,47 +194,82 @@ Shows the oldest tasks with specified criteria
|
|||
Tasks can be specified uniquely by IDs, which are simply the index of the
|
||||
task in a report. Be careful, as the IDs of tasks may change after a
|
||||
modification to the database. Always run a report to check you have the right
|
||||
ID for a task. IDs can be given to task as a sequence, for example,
|
||||
ID for a task. IDs can be given to task as a sequences, for example,
|
||||
.br
|
||||
.B
|
||||
task del 1 2 5-10,12
|
||||
task del 1,4-10,19
|
||||
|
||||
.TP
|
||||
.B +tag|-tag
|
||||
Tags are arbitrary words associated with a task. Use + to add a tag and - to
|
||||
remove a tag from a task.
|
||||
remove a tag from a task. A task can have any quantity of tags
|
||||
|
||||
.TP
|
||||
.B project:<project-name>
|
||||
Specify the project to which a task is related to.
|
||||
Specifies the project to which a task is related to.
|
||||
|
||||
.TP
|
||||
.B priority:H|M|L|N
|
||||
Specify High, Medium, Low and No priority for a task.
|
||||
Specifies High, Medium, Low and No priority for a task.
|
||||
|
||||
.TP
|
||||
.B due:<due-date>
|
||||
Specify the due-date of a task.
|
||||
|
||||
.TP
|
||||
.B until:<end-date-of-recurrence>
|
||||
Specify the Recurrence end-date of a task.
|
||||
Specifies the due-date of a task.
|
||||
|
||||
.TP
|
||||
.B recur:<frequency>
|
||||
Specify the frequency of recurrence of a task.
|
||||
Specifies the frequency of a recurrence of a task.
|
||||
|
||||
.TP
|
||||
.B until:<end-date-of-recurrence>
|
||||
Specifies the Recurrence end-date of a task.
|
||||
|
||||
.TP
|
||||
.B fg:<color-spec>
|
||||
Specify foreground color.
|
||||
Specifies foreground color.
|
||||
|
||||
.TP
|
||||
.B bg:<color-spec>
|
||||
Specify background color.
|
||||
Specifies background color.
|
||||
|
||||
.TP
|
||||
.B rc:<path>
|
||||
Specify alternate configuration file.
|
||||
.B limit:<number-of-rows>
|
||||
Specifies the desired number of rows a report should have.
|
||||
|
||||
.TP
|
||||
.B wait:<wait-date>
|
||||
Date until task becomes pending.
|
||||
|
||||
.SH ATTRIBUTE MODIFIERS
|
||||
Attribute modifiers improve filters. Supported modifiers are:
|
||||
|
||||
.RS
|
||||
.B before (synonyms under, below)
|
||||
.br
|
||||
.B after (synonyms over, above)
|
||||
.br
|
||||
.B none
|
||||
.br
|
||||
.B any
|
||||
.br
|
||||
.B is (synonym equals)
|
||||
.br
|
||||
.B isnt (synonym not)
|
||||
.br
|
||||
.B has (synonym contain)
|
||||
.br
|
||||
.B hasnt
|
||||
.br
|
||||
.B startswith (synonym left)
|
||||
.br
|
||||
.B endswith (synonym right)
|
||||
.RE
|
||||
|
||||
For example:
|
||||
|
||||
.RS
|
||||
task list due.before:eom priority.not:L
|
||||
.RE
|
||||
|
||||
.SH SPECIFYING DATES AND FREQUENCIES
|
||||
|
||||
|
@ -317,11 +371,50 @@ $ task l
|
|||
|
||||
could be list, ls or long.
|
||||
|
||||
.SH SPECIFYING DESCRIPTIONS
|
||||
Some task descriptions need to be escaped because of the shell
|
||||
and the special meaning of some characters to the shell. This can be
|
||||
done either by adding quotes to the description or escaping the special
|
||||
character:
|
||||
|
||||
.RS
|
||||
$ task add "quoted ' quote"
|
||||
.br
|
||||
$ task add escaped \\' quote
|
||||
.RE
|
||||
|
||||
The argument \-\- (a double dash) tells task to treat all other args
|
||||
as description:
|
||||
|
||||
.RS
|
||||
$ task add -- project:Home needs scheduling
|
||||
.RE
|
||||
|
||||
.SH CONFIGURATION FILE AND OVERRIDE OPTIONS
|
||||
Task stores its configuration in a file in the user's home directory:
|
||||
~/.taskrc . The default configuration file can be overridden with
|
||||
|
||||
.TP
|
||||
.B task rc:<path-to-alternate-file>
|
||||
Specifies an alternate configuration file.
|
||||
|
||||
.TP
|
||||
.B task rc.<name>:<value> ...
|
||||
Specifies individual configuration file overrides.
|
||||
|
||||
.SH EXAMPLES
|
||||
|
||||
For examples please see the online documentation at
|
||||
.br
|
||||
For examples please see the task tutorial man page at
|
||||
|
||||
.RS
|
||||
man task-tutorial
|
||||
.RE
|
||||
|
||||
or the online documentation starting at
|
||||
|
||||
.RS
|
||||
<http://taskwarrior.org/wiki/taskwarrior/Simple>
|
||||
.RE
|
||||
|
||||
.SH FILES
|
||||
|
||||
|
@ -338,6 +431,9 @@ can be configured in the configuration file.
|
|||
.TP
|
||||
~/.task/completed.data The file that contains the completed "done" tasks.
|
||||
|
||||
.TP
|
||||
~/.task/undo.data The file that contains the information to the "undo" command.
|
||||
|
||||
.SH "CREDITS & COPYRIGHTS"
|
||||
task was written by P. Beckingham <paul@beckingham.net>.
|
||||
.br
|
||||
|
@ -350,7 +446,8 @@ task is distributed under the GNU General Public License. See
|
|||
http://www.gnu.org/licenses/gpl-2.0.txt for more information.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR taskrc (5)
|
||||
.BR taskrc(5),
|
||||
.BR task-tutorial(5)
|
||||
|
||||
For more information regarding task, the following may be referenced:
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
.TH taskrc 5 2009-05-14 "Task 1.7.1" "User Manuals"
|
||||
.TH taskrc 5 2009-07-14 "Task 1.8.0" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
taskrc \- Configuration file for the task(1) command
|
||||
|
@ -26,6 +26,14 @@ attribute when running task:
|
|||
$ task rc:<directory-path>/.taskrc
|
||||
.RE
|
||||
|
||||
Individual option can be overridden by using the
|
||||
.I rc.<name>:
|
||||
attribute when running task:
|
||||
|
||||
.RS
|
||||
$ task rc.<name>:<value> ...
|
||||
.RE
|
||||
|
||||
If
|
||||
.B task
|
||||
is run without an existing configuration file it will ask if it should create a default, sample
|
||||
|
@ -53,24 +61,59 @@ and set a configuration variable to a certain value. The equal sign ("=") is use
|
|||
name from the value to be set.
|
||||
|
||||
The hash mark, or pound sign ("#") is used as a "comment" character. It can be used to annotate the
|
||||
configuration file. It is placed at the beginning of a line and all text after the character to the
|
||||
end of the line is ignored.
|
||||
configuration file. All text after the character to the end of the line is ignored.
|
||||
|
||||
.SH CONFIGURATION VARIABLES
|
||||
Valid variable names and their default values are:
|
||||
|
||||
.SS FILES
|
||||
|
||||
.TP
|
||||
.B data.location=$HOME/.task
|
||||
This is a path to the directory containing all the task files. By default, it is set up to be ~/.task,
|
||||
for example: /Users/paul/.task
|
||||
for example: /home/paul/.task
|
||||
|
||||
.TP
|
||||
.B locking=on
|
||||
Determines whether task uses file locking when accessing the pending.data and completed.data files.
|
||||
Default to "on". Solaris users who store the task data files on an NFS mount may need to set locking
|
||||
to "off". Note that setting this value to "off" is dangerous. It means that another program may write
|
||||
to the task.pending file when task is attempting to do the same.
|
||||
|
||||
.SS TERMINAL
|
||||
.TP
|
||||
.B curses=on
|
||||
Determines whether task uses ncurses to establish the size of the window you are
|
||||
using, for text wrapping.
|
||||
|
||||
.TP
|
||||
.B defaultwidth=80
|
||||
The width of tables used when ncurses support is not available. Defaults to 80.
|
||||
|
||||
.TP
|
||||
.B editor=vi
|
||||
Specifies which text editor you wish to use for when the
|
||||
.B task edit <ID>
|
||||
command is used. Task will first look for this configuration variable. If found, it is used.
|
||||
Otherwise task will look for the $VISUAL or $EDITOR environment variables, before it defaults
|
||||
to using "vi".
|
||||
|
||||
.SS MISCELLANEOUS
|
||||
|
||||
.TP
|
||||
.B locale=en-US
|
||||
The locale is a combination of ISO 639-1 language code and ISO 3166 country
|
||||
code. If not specified, task will assume en-US. If specified, task will locate
|
||||
the correct file of localized strings and proceed. It is an error to specify a
|
||||
locale for which there is no strings file.
|
||||
|
||||
.TP
|
||||
.B confirmation=yes
|
||||
May be "yes" or "no", and determines whether task will ask for confirmation before deleting a task.
|
||||
May be "yes" or "no", and determines whether task will ask for confirmation before deleting a task or doing bulk changes.
|
||||
|
||||
.TP
|
||||
.B echo.command=yes
|
||||
May be "yes" or "no", and causes task to display the ID and description of any task when you run the start, stop, do, undo, delete and undelete commands. The default value is "yes".
|
||||
May be "yes" or "no", and causes task to display the ID and description of any task when you run the start, stop, do, undo or delete commands. The default value is "yes".
|
||||
|
||||
.TP
|
||||
.B next=2
|
||||
|
@ -78,6 +121,31 @@ Is a number, defaulting to 2, which is the number of tasks for each project that
|
|||
.B task next
|
||||
command.
|
||||
|
||||
.TP
|
||||
.B bulk=2
|
||||
Is a number, defaulting to 2. When more than this number of tasks are modified in a single command, confirmation will be required, unless the
|
||||
.B confirmation
|
||||
variable is "no".
|
||||
|
||||
.TP
|
||||
.B nag=You have higher priority tasks.
|
||||
This may be a string of text, or blank. It is used as a prompt when a task is completed
|
||||
that is not considered high priority. The "task next" command lists important tasks, and
|
||||
completing one of those does not generate this nagging. Default value is: You have higher
|
||||
priority tasks.
|
||||
|
||||
.TP
|
||||
.B complete.all.projects=yes
|
||||
May be yes or no, and determines whether the tab completion scripts consider all the
|
||||
project names you have used, or just the ones used in active tasks.
|
||||
|
||||
.TP
|
||||
.B complete.all.tags=yes
|
||||
May be yes or no, and determines whether the tab completion scripts consider all the
|
||||
tag names you have used, or just the ones used in active tasks.
|
||||
|
||||
.SS DATES
|
||||
|
||||
.TP
|
||||
.B dateformat=m/d/Y
|
||||
This is a string of characters that define how task formats dates. The default value is: m/d/Y.
|
||||
|
@ -110,19 +178,13 @@ m-d-y would output 07-24-09
|
|||
.RE
|
||||
|
||||
.TP
|
||||
.B monthsperline=99
|
||||
Determines how many months the "task calendar" command renders across the screen.
|
||||
Defaults to however many will fit. If more months that will fit are specified,
|
||||
task will only show as many that will fit.
|
||||
.B weekstart=Sunday
|
||||
Determines the day a week starts. Valid values are Sunday or Monday only.
|
||||
|
||||
.TP
|
||||
.B defaultwidth=80
|
||||
The width of tables used when ncurses support is not available. Defaults to 80.
|
||||
|
||||
.TP
|
||||
.B curses=on
|
||||
Determines whether task uses ncurses to establish the size of the window you are
|
||||
using, for text wrapping.
|
||||
.B displayweeknumber=yes
|
||||
Determines if week numbers are displayed when using the "task calendar" command.
|
||||
The week number is dependent on the day a week starts.
|
||||
|
||||
.TP
|
||||
.B due=7
|
||||
|
@ -130,32 +192,23 @@ This is the number of days into the future that define when a task is considered
|
|||
and is colored accordingly. Defaults to 7.
|
||||
|
||||
.TP
|
||||
.B nag=You have higher priority tasks.
|
||||
This may be a string of text, or blank. It is used as a prompt when a task is completed
|
||||
that is not considered high priority. The "task next" command lists important tasks, and
|
||||
completing one of those does not generate this nagging. Default value is: You have higher
|
||||
priority tasks.
|
||||
.B monthsperline=2
|
||||
Determines how many months the "task calendar" command renders across the screen.
|
||||
Defaults to however many will fit. If more months that will fit are specified,
|
||||
task will only show as many that will fit.
|
||||
|
||||
.TP
|
||||
.B locking=on
|
||||
Determines whether task uses file locking when accessing the pending.data and completed.data files.
|
||||
Default to "on". Solaris users who store the task data files on an NFS mount may need to set locking
|
||||
to "off". Note that setting this value to "off" is dangerous. It means that another program may write
|
||||
to the task.pending file when task is attempting to do the same.
|
||||
|
||||
.TP
|
||||
.B editor=vi
|
||||
Specifies which text editor you wish to use for when the
|
||||
.B task edit <ID>
|
||||
command is used. Task will first look for this configuration variable. If found, it is used.
|
||||
Otherwise task will look for the $VISUAL or $EDITOR environment variables, before it defaults
|
||||
to using "vi".
|
||||
.SS COLOR CONTROLS
|
||||
|
||||
.TP
|
||||
.B color=on
|
||||
May be "on" or "off". Determines whether task uses color. When "off", task will
|
||||
use dashes (-----) to underline column headings.
|
||||
|
||||
.TP
|
||||
.B fontunderline=on
|
||||
Determines if font underlines or ASCII dashes should be used to underline
|
||||
headers.
|
||||
|
||||
Task has a number of coloration rules. They correspond to a particular attribute
|
||||
of a task, such as it being due, or being active, and specifies the automatic
|
||||
coloring of that task. A list of valid color, depending on your terminal, can be
|
||||
|
@ -172,22 +225,31 @@ The coloration rules and their defaults are:
|
|||
.RS
|
||||
.RS
|
||||
.B color.overdue=bold_red
|
||||
The color for overdue tasks.
|
||||
.br
|
||||
.B color.due=bold_yellow
|
||||
The color of due tasks.
|
||||
.br
|
||||
.B color.pri.H=bold
|
||||
The color of priority:H tasks.
|
||||
.br
|
||||
.B color.pri.M=on_yellow
|
||||
The color of priority:M tasks.
|
||||
.br
|
||||
.B color.pri.L=on_green
|
||||
The color of priority:L tasks.
|
||||
.br
|
||||
.B color.pri.none=white on_blue
|
||||
The color of priority: tasks.
|
||||
.br
|
||||
.B color.active=bold_cyan
|
||||
The color of active tasks.
|
||||
.br
|
||||
.B color.tagged=yellow
|
||||
The color of tagged tasks.
|
||||
.br
|
||||
.B color.recurring=on_red
|
||||
The color for recurring tasks.
|
||||
.RE
|
||||
.RE
|
||||
|
||||
|
@ -218,8 +280,22 @@ Colors any task assigned to project X.
|
|||
.TP
|
||||
.B color.keyword.X=on_blue
|
||||
Colors any task where the description contains X.
|
||||
|
||||
.TP
|
||||
.B color.header=green
|
||||
Colors any of the messages printed prior to the report output.
|
||||
|
||||
.TP
|
||||
.B color.message=green
|
||||
Colors any of the messages printed after the report output.
|
||||
|
||||
.TP
|
||||
.B color.footnote=green
|
||||
Colors any of the messages printed last.
|
||||
.RE
|
||||
|
||||
.SS SHADOW FILE
|
||||
|
||||
.TP
|
||||
.B
|
||||
shadow.file=$HOME/.task/shadow.txt
|
||||
|
@ -244,6 +320,8 @@ shadow.notify=on
|
|||
When this value is set to "on", task will display a message whenever the shadow
|
||||
file is updated by some task command.
|
||||
|
||||
.SS DEFAULTS
|
||||
|
||||
.TP
|
||||
.B
|
||||
default.project=foo
|
||||
|
@ -271,7 +349,7 @@ default.command=list project:foo
|
|||
.RE
|
||||
|
||||
.RS
|
||||
Then task will run the "list project:foo" command if no command is specified. This means that
|
||||
then task will run the "list project:foo" command if no command is specified. This means that
|
||||
by merely typing
|
||||
.RE
|
||||
|
||||
|
@ -289,111 +367,111 @@ ID Project Pri Description
|
|||
.RE
|
||||
.RE
|
||||
|
||||
The built in reports can be customized by using the following configuration variables.
|
||||
The output columns, their labels and the sort order can be set using the corresponding
|
||||
variables for each report.
|
||||
.SS REPORTS
|
||||
|
||||
The reports can be customized by using the following configuration variables.
|
||||
The output columns, their labels and the sort order can be set using the
|
||||
corresponding variables for each report. Each report name is used as a
|
||||
"command" name. For example
|
||||
|
||||
.TP
|
||||
.B
|
||||
report.long.description
|
||||
Lists all task, all data, matching the specified criteria
|
||||
.B task overdue
|
||||
|
||||
.TP
|
||||
.B
|
||||
report.long.labels=ID,Project,Pri,Added,Started,Due,Recur,Age,Tags,Description
|
||||
.RE
|
||||
.br
|
||||
.B
|
||||
report.long.columns=id,project,priority,entry,start,due,recur,age,tags,description
|
||||
.br
|
||||
.B
|
||||
report.long.sort=due+,priority-,project+
|
||||
.B report.X.description
|
||||
The description for report X when running the "task help" command.
|
||||
|
||||
.TP
|
||||
.B
|
||||
report.list.description
|
||||
Lists all tasks matching the specified criteria
|
||||
.B report.X.columns
|
||||
The columns that will be used when generating the report X. Valid columns are:
|
||||
id, uuid, project, priority, entry, start, due, recur, recur_ind, age, age_compact,
|
||||
active, tags, description, description_only. The IDs are separated by commas.
|
||||
|
||||
.TP
|
||||
.B
|
||||
report.list.labels=ID,Project,Pri,Due,Active,Age,Description
|
||||
.RE
|
||||
.br
|
||||
.B
|
||||
report.list.columns=id,project,priority,due,active,age,description
|
||||
.br
|
||||
.B
|
||||
report.list.sort=due+,priority-,project+
|
||||
|
||||
.B report.X.labels
|
||||
The labels for each column that will be used when generating report X. The labels
|
||||
are a comma separated list.
|
||||
|
||||
.TP
|
||||
.B
|
||||
report.ls.description
|
||||
Minimal listing of all tasks matching the specified criteria
|
||||
.B report.X.sort
|
||||
The sort order of the tasks in the generated report X. The sort order is specified
|
||||
by using the column ids post-fixed by a "+" for ascending sort order or a "-" for
|
||||
descending sort order. The sort IDs are separated by commas
|
||||
|
||||
.TP
|
||||
.B
|
||||
report.ls.labels=ID,Project,Pri,Description
|
||||
.RE
|
||||
.br
|
||||
.B
|
||||
report.ls.columns=id,project,priority,description
|
||||
.br
|
||||
.B
|
||||
report.ls.sort=priority-,project+
|
||||
.B report.X.filter
|
||||
This adds a filter to the report X so that only tasks matching the filter criteria
|
||||
are displayed in the generated report.
|
||||
|
||||
.TP
|
||||
.B
|
||||
report.newest.description
|
||||
Shows the newest tasks
|
||||
.B report.X.limit
|
||||
An optional value to a report limiting the number of displayed tasks in the
|
||||
generated report.
|
||||
|
||||
.TP
|
||||
.B
|
||||
report.newest.labels=ID,Project,Pri,Due,Active,Age,Description
|
||||
.RE
|
||||
.br
|
||||
.B
|
||||
report.newest.columns=id,project,priority,due,active,age,description
|
||||
.br
|
||||
.B
|
||||
report.newest.sort=id-
|
||||
.br
|
||||
.B
|
||||
report.newest.limit=10
|
||||
|
||||
Task comes with a number of predefined reports in its default configuration file. These reports are:
|
||||
|
||||
.TP
|
||||
.B
|
||||
report.oldest.description
|
||||
Shows the oldest tasks
|
||||
.B long
|
||||
Lists all task, all data, matching the specified criteria.
|
||||
|
||||
.TP
|
||||
.B
|
||||
report.oldest.labels=ID,Project,Pri,Due,Active,Age,Description
|
||||
.RE
|
||||
.br
|
||||
.B
|
||||
report.oldest.columns=id,project,priority,due,active,age,description
|
||||
.br
|
||||
.B
|
||||
report.oldest.sort=id+
|
||||
.br
|
||||
.B
|
||||
report.oldest.limit=10
|
||||
.B list
|
||||
Lists all tasks matching the specified criteria.
|
||||
|
||||
.TP
|
||||
.B ls
|
||||
Minimal listing of all tasks matching the specified criteria.
|
||||
|
||||
.TP
|
||||
.B newest
|
||||
Shows the newest tasks.
|
||||
|
||||
.TP
|
||||
.B oldest
|
||||
Shows the oldest tasks.
|
||||
|
||||
.TP
|
||||
.B overdue
|
||||
Lists overdue tasks matching the specified criteria.
|
||||
|
||||
.TP
|
||||
.B active
|
||||
Lists active tasks matching the specified criteria.
|
||||
|
||||
.TP
|
||||
.B completed
|
||||
Lists completed tasks matching the specified criteria.
|
||||
|
||||
.TP
|
||||
.B recurring
|
||||
Lists recurring tasks matching the specified criteria.
|
||||
|
||||
.TP
|
||||
.B waiting
|
||||
Lists all waiting tasks matching the specified criteria.
|
||||
|
||||
.TP
|
||||
.B all
|
||||
Lists all tasks matching the specified criteria.
|
||||
|
||||
.TP
|
||||
.B next
|
||||
Lists all tasks with upcoming due dates matching the specified criteria.
|
||||
|
||||
.SH "CREDITS & COPYRIGHTS"
|
||||
task was written by P. Beckingham <paul@beckingham.net>.
|
||||
.br
|
||||
Copyright (C) 2006 \- 2009 P. Beckingham
|
||||
|
||||
This man page was originally written by Federico Hernandez. It is based on the task man page, which
|
||||
was originally written by P.C. Shyamshankar.
|
||||
This man page was originally written by Federico Hernandez.
|
||||
|
||||
task is distributed under the GNU General Public License. See
|
||||
http://www.gnu.org/licenses/gpl-2.0.txt for more information.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR task(1)
|
||||
.BR task(1),
|
||||
.BR task-tutorial(5)
|
||||
|
||||
For more information regarding task, the following may be referenced:
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>30-Second Tutorial</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title"><a name="simple">30-second Tutorial</a></h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
For the excessively lazy.
|
||||
Add two tasks:
|
||||
</p>
|
||||
|
||||
<pre><code>% task add Read task documents later
|
||||
% task add priority:H Pay bills</code></pre>
|
||||
|
||||
<p>
|
||||
Easy. See that second one has a High priority? Now let's look at those tasks:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ls
|
||||
|
||||
ID Project Pri Description
|
||||
2 H Pay bills
|
||||
1 Read task documents later</code></pre>
|
||||
|
||||
<p>
|
||||
They are ordered by priority. Let's mark number 2 as done:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 2 done
|
||||
% task ls
|
||||
|
||||
ID Project Pri Description
|
||||
1 Read task documents later</code></pre>
|
||||
|
||||
<p>
|
||||
Gone. Now let's delete that remaining task, because, well,
|
||||
why bother now we are already using task:
|
||||
</p>
|
||||
|
||||
<pre><code>% task delete 1
|
||||
% task ls
|
||||
No matches</code></pre>
|
||||
|
||||
<p>
|
||||
Easy. But now consider checking out what task can really do...
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,541 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Advanced Usage</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title"><a name="advanced">Advanced Usage</a></h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
Here are the other commands, in some detail.
|
||||
</p>
|
||||
|
||||
<strong>% task</strong>
|
||||
<p>
|
||||
With no arguments, this command will generate a help message that
|
||||
lists all these commands.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
However, if the following configuration variable is specified:
|
||||
</p>
|
||||
|
||||
<pre><code>default.command=list pri:H</code></pre>
|
||||
|
||||
<p>
|
||||
Then this command will be run whenever task is run without arguments.
|
||||
This means that your most common task command can be run simply
|
||||
with the command:
|
||||
</p>
|
||||
|
||||
<pre><code>% task
|
||||
[task list project:foo]
|
||||
|
||||
ID Project Pri Description
|
||||
1 foo H Design the thing
|
||||
2 foo Build the thing</code></pre>
|
||||
|
||||
<strong>% task projects</strong>
|
||||
<p>
|
||||
This report generates a list of all the different projects that you
|
||||
are using along with a count of the pending tasks for each project.
|
||||
For example:
|
||||
</p>
|
||||
|
||||
<pre><code>% task projects
|
||||
|
||||
Project Tasks
|
||||
Errands 1
|
||||
Birthdays 3
|
||||
Car 2</code></pre>
|
||||
|
||||
|
||||
<strong>% task summary</strong>
|
||||
<p>
|
||||
This report lists all the projects and a summary of their task
|
||||
status.
|
||||
</p>
|
||||
|
||||
<pre><code>% task summary
|
||||
|
||||
Project Remaining Avg age Complete 0% 100%
|
||||
Errands 1 3 days 50% XXXXXXXXXXXXXXXX
|
||||
Birthdays 3 7 mths 0%
|
||||
Car 2 2 wks 25% XXXXXXXXX</code></pre>
|
||||
|
||||
<p>
|
||||
This shows the project, the remaining tasks, the average age of each
|
||||
task, the percentage completed (remaining vs total) and a bar
|
||||
indicating that percentage.
|
||||
</p>
|
||||
|
||||
<strong>% task <id> append ...</strong>
|
||||
<p>
|
||||
Appends the additional description to an existing task.
|
||||
</p>
|
||||
|
||||
<strong>% task annotate <id> additional note...</strong>
|
||||
<p>
|
||||
Allows an annotation to be attached to an existing task. Each
|
||||
annotation has a time stamp, and when displayed, the annotations
|
||||
are shown under the task description. For example:
|
||||
</p>
|
||||
|
||||
<pre><code>% task add Go to the supermarket
|
||||
% task annotate 1 need milk
|
||||
% task ls
|
||||
|
||||
ID Project Pri Due Active Age Description
|
||||
1 Go to the supermarket
|
||||
3/23/2009 need milk</code></pre>
|
||||
<p>
|
||||
The date of the annotation uses the "dateformat" configuration
|
||||
variable.
|
||||
</p>
|
||||
|
||||
<strong>% task duplicate 1 /foo/bar/g +tag priority:H</strong>
|
||||
<p>
|
||||
This duplicates task 1, then applies the modifications specified,
|
||||
which change all "foo" to "bar" in the description and annotations,
|
||||
adds the tag "tag", and sets the priority to "H".
|
||||
</p>
|
||||
|
||||
<strong>% task delete <id></strong>
|
||||
<p>
|
||||
There are two ways of getting rid of tasks - mark them as done, or
|
||||
delete them.
|
||||
</p>
|
||||
|
||||
<strong>% task undelete <id></strong>
|
||||
<p>
|
||||
If a task was inadvertently deleted, it may be undeleted, provided that no
|
||||
reports have been run since the deletion. Ideally, the undelete command is
|
||||
run immediately after the erroneous delete command.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If a report is run (such as "task list"), then task performs a garbage
|
||||
collection that removes deleted tasks, and the task cannot be undeleted.
|
||||
</p>
|
||||
|
||||
<strong>% task done <id></strong>
|
||||
<p>
|
||||
This is how a task is marked as done.
|
||||
</p>
|
||||
|
||||
<strong>% task undo <id></strong>
|
||||
<p>
|
||||
If a task was recently marked as done, and no report has been run, it
|
||||
may be possible to cancel the completed status of the task as though
|
||||
"task done ..." was never run.
|
||||
</p>
|
||||
|
||||
<strong>% task list ...</strong>
|
||||
<p>
|
||||
The list report will show the active status, and age of the task in
|
||||
addition to the columns that "task ls" shows. It is just a more
|
||||
detailed list.
|
||||
</p>
|
||||
|
||||
<strong>% task long ...</strong>
|
||||
<p>
|
||||
The long report will show the entry date and start date of a task,
|
||||
in addition to the columns that the "task list" shows.
|
||||
</p>
|
||||
|
||||
<strong>% task start <id></strong>
|
||||
<p>
|
||||
This marks a task as started (and therefore active), which is shown
|
||||
in the "list" report:
|
||||
</p>
|
||||
|
||||
<pre><code>% task list
|
||||
|
||||
ID Project Pri Due Active Age Description
|
||||
12 Errand L Remember to deposit check
|
||||
...
|
||||
|
||||
% task start 12
|
||||
% task list
|
||||
|
||||
ID Project Pri Due Active Age Description
|
||||
12 Errand L * 3 days Remember to deposit check
|
||||
...</code></pre>
|
||||
|
||||
<strong>% task active</strong>
|
||||
<p>
|
||||
Shows all active tasks, that is, the tasks for which the
|
||||
"task start ..." command was run, as shown above.
|
||||
</p>
|
||||
|
||||
<strong>% task stop <id></strong>
|
||||
<p>
|
||||
Marks a task as inactive, by removing the start time.
|
||||
</p>
|
||||
|
||||
<strong>% task overdue</strong>
|
||||
<p>
|
||||
Simply lists all the task that have a due date that is past, in
|
||||
"list" format.
|
||||
</p>
|
||||
|
||||
<strong>% task history</strong>
|
||||
<p>
|
||||
This report shows you an overview of how many tasks were added,
|
||||
completed and deleted, by month. It looks like this:
|
||||
</p>
|
||||
|
||||
<pre><code>% task history
|
||||
|
||||
Year Month Added Completed Deleted Net
|
||||
2008 March 21 16 0 5
|
||||
April 13 11 1 1
|
||||
May 8 14 3 -9</code></pre>
|
||||
|
||||
<p>
|
||||
This shows that for the three months that task has been used, March
|
||||
and April saw the total number of tasks increase, but in May the
|
||||
number decreased as more task were completed than added.
|
||||
</p>
|
||||
|
||||
<strong>% task ghistory</strong>
|
||||
<p>
|
||||
The ghistory report is a "graphical" version of the history
|
||||
report. It shows a colored bar graph and legend.
|
||||
</p>
|
||||
|
||||
<strong>% task timesheet 2</strong>
|
||||
<p>
|
||||
The timesheet report shows a list of tasks completed and started
|
||||
during a one-week period. In the example above, 2 weeks of tasks
|
||||
are shown.
|
||||
</p>
|
||||
<p>
|
||||
By default, the report starts on a Monday. To override this
|
||||
value, add an entry to your .taskrc file like this:
|
||||
<pre><code>weekstart=Sunday</code></pre>
|
||||
</p>
|
||||
|
||||
<strong>% task calendar</strong>
|
||||
<p>
|
||||
This report shows a calendar of the current month, with any task
|
||||
due or overdue dates marked on it. Color is used to mark these
|
||||
dates.
|
||||
</p>
|
||||
|
||||
<pre><code>% task calendar
|
||||
|
||||
May 2008
|
||||
|
||||
Su Mo Tu We Th Fr Sa
|
||||
1 2 3
|
||||
4 5 6 7 8 9 10
|
||||
11 12 13 14 15 16 17
|
||||
18 19 20 21 22 23 24
|
||||
25 26 27 28 29 30 31</code></pre>
|
||||
|
||||
<strong>% task next</strong>
|
||||
<p>
|
||||
This report shows you the tasks you should probable work on next.
|
||||
Task will scan all the tasks and will pick two task from each
|
||||
project to report. Those two tasks will be chosen in order of
|
||||
overdue, due soon, High, Medium or Low priority. Essentially task
|
||||
chooses the two most important task for each project and displays
|
||||
them ordered in the usual way.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you wish to show a different number of tasks per project, modify
|
||||
the entry in .taskrc:
|
||||
</p>
|
||||
|
||||
<pre><code>next=2</code></pre>
|
||||
|
||||
<p>
|
||||
To be your preferred number.
|
||||
</p>
|
||||
|
||||
<strong>% task <id> ...</strong>
|
||||
<p>
|
||||
When a task id is specified, everything applies to just that task.
|
||||
Suppose we needed to correct a task:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ls
|
||||
|
||||
ID Project Pri Description
|
||||
12 Errand L Remember to deposit chekc
|
||||
...
|
||||
|
||||
% task 12 Remember to deposit bonus check
|
||||
% task ls
|
||||
|
||||
ID Project Pri Description
|
||||
12 Errand L Remember to deposit bonus check
|
||||
...</code></pre>
|
||||
|
||||
<strong>% task oldest [limit]</strong>
|
||||
<p>
|
||||
Lists the oldest tasks. The number of tasks shown is set by
|
||||
the configuration variable:
|
||||
<pre><code>report.oldest.limit=10</code></pre>
|
||||
This value can be overridden at run time by specifying the
|
||||
number of tasks on the command line:
|
||||
<pre><code>task oldest 5</code></pre>
|
||||
</p>
|
||||
|
||||
<strong>% task newest [limit]</strong>
|
||||
<p>
|
||||
Lists the newest tasks. The number of tasks shown is set by
|
||||
the configuration variable:
|
||||
<pre><code>report.newest.limit=10</code></pre>
|
||||
This value can be overridden at run time by specifying the
|
||||
number of tasks on the command line:
|
||||
<pre><code>task newest 5</code></pre>
|
||||
</p>
|
||||
|
||||
<strong>% task <id> /from/to/</strong>
|
||||
<p>
|
||||
If a task has been entered with a typo, it can be easily corrected
|
||||
by this command. For example:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ls
|
||||
|
||||
ID Project Pri Description
|
||||
12 Errand L Remember to deposit chekc
|
||||
...
|
||||
|
||||
% task 12 /chekc/check/
|
||||
% task ls
|
||||
|
||||
ID Project Pri Description
|
||||
12 Errand L Remember to deposit check
|
||||
...</code></pre>
|
||||
|
||||
<p>
|
||||
This command makes a single correction to the first occurrence of
|
||||
"from" in a task description.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If a task is annotated, the annotation can also be modified using
|
||||
this command.
|
||||
</p>
|
||||
|
||||
<strong>% task <id> /from/to/g</strong>
|
||||
<p>
|
||||
The "g" modifier to the substitution command causes every occurrence
|
||||
of "from" to be replaced with "to", in both the description and any
|
||||
annotations.
|
||||
</p>
|
||||
|
||||
<strong>% task tags</strong>
|
||||
<p>
|
||||
This command will generate a list of all the tags that are currently
|
||||
in use by task.
|
||||
</p>
|
||||
|
||||
<strong>% task info <id></strong>
|
||||
<p>
|
||||
This command gives detailed information about a single task. It
|
||||
will tell you when the task was entered, when started, its status,
|
||||
tags, and more.
|
||||
</p>
|
||||
|
||||
<strong>% task stats</strong>
|
||||
<p>
|
||||
This command generates a list of statistics about your task usage,
|
||||
such as the average time it takes to complete a task, how often new
|
||||
tasks are added, and more.
|
||||
</p>
|
||||
|
||||
<strong>% task completed</strong>
|
||||
<p>
|
||||
This generates a list of all tasks that have been completed, sorted
|
||||
by their completion date.
|
||||
</p>
|
||||
|
||||
<strong>% task export <file name></strong>
|
||||
<p>
|
||||
This instructs task to write out a CSV format dump of all tasks,
|
||||
both pending and completed, to the file specified. This is how you
|
||||
might view tasks in a spreadsheet.
|
||||
</p>
|
||||
|
||||
<strong>% task colors</strong>
|
||||
<p>
|
||||
This command displays all the colors that task supports.
|
||||
</p>
|
||||
|
||||
<strong>% task version</strong>
|
||||
<p>
|
||||
This can be used to show the version number of task, and to display
|
||||
all the current configuration settings, as read from the .taskrc
|
||||
file.
|
||||
</p>
|
||||
|
||||
<strong>% task rc:<file> ...</strong>
|
||||
<p>
|
||||
By specifying rc:<file>, it is possible to force task to use an alternate
|
||||
.taskrc file. By default, task looks in your home directory, so these two
|
||||
commands are essentially identical:
|
||||
</p>
|
||||
|
||||
<pre><code>% task list
|
||||
% task rc:~/.taskrc list</code></pre>
|
||||
|
||||
<p>
|
||||
What this override allows, is the possibility of keeping your task lists
|
||||
completely separate, say for work and home. This can be accomplished with
|
||||
the following commands (valid for bash):
|
||||
</p>
|
||||
|
||||
<pre><code>% alias htask="task rc:/home/me/.taskrc_home"
|
||||
% alias wtask="task rc:/home/me/.taskrc_work"
|
||||
% htask list
|
||||
...
|
||||
% wtask list
|
||||
...</code></pre>
|
||||
|
||||
<strong>% task <id> "new description"</strong>
|
||||
<p>
|
||||
Not strictly a command, the replacement of the description can
|
||||
be achieved by quoting the entire description. The quotes are
|
||||
necessary in case one of the description words looks like a task
|
||||
command.
|
||||
</p>
|
||||
|
||||
<strong>% task <id> edit</strong>
|
||||
<p>
|
||||
This command allows you to use your text editor to edit all aspects
|
||||
of a task. The specified task will be written to a file, and your
|
||||
text editor will be invoked. If you modify the task in the text
|
||||
editor, task will update accordingly.
|
||||
</p>
|
||||
<p>
|
||||
Task will first check to see if you have defined a text editor
|
||||
in the 'editor' configuration variable. If not, task will
|
||||
check to see if you defined a text editor in the VISUAL
|
||||
environment variable. If not task will check to see if you
|
||||
defined a text editor in the EDITOR environment variable.
|
||||
If all those fail, task launches vi.
|
||||
</p>
|
||||
|
||||
<strong>% task <id> fg:... bg:...</strong>
|
||||
<p>
|
||||
Not strictly a command, the setting of the fg and bg (foreground
|
||||
and background) attributes determines the colors used to represent
|
||||
the task. Valid foreground colors are:
|
||||
</p>
|
||||
|
||||
<pre><code> bold underline bold_underline
|
||||
black bold_black underline_black bold_underline_black
|
||||
red bold_red underline_red bold_underline_red
|
||||
green bold_green underline_green bold_underline_green
|
||||
yellow bold_yellow underline_yellow bold_underline_yellow
|
||||
blue bold_blue underline_blue bold_underline_blue
|
||||
magenta bold_magenta underline_magenta bold_underline_magenta
|
||||
cyan bold_cyan underline_cyan bold_underline_cyan
|
||||
white bold_white underline_white bold_underline_white</code></pre>
|
||||
|
||||
<p>
|
||||
Note that these are not just colors, but combinations of colors and
|
||||
attributes. Valid background colors are:
|
||||
</p>
|
||||
|
||||
<pre><code>on_black on_bright_black
|
||||
on_red on_bright_red
|
||||
on_green on_bright_green
|
||||
on_yellow on_bright_yellow
|
||||
on_blue on_bright_blue
|
||||
on_magenta on_bright_magenta
|
||||
on_cyan on_bright_cyan
|
||||
on_white on_bright_white</code></pre>
|
||||
|
||||
<p>
|
||||
Note also that this capability does depend on whether your terminal
|
||||
program can display these colors.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
127
html/color.html
127
html/color.html
|
@ -1,127 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Color Usage</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title"><a name="color">Colors</a></h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
Task supports color in several places. In cases where you may
|
||||
specify a color, a foreground, a background, or a combination
|
||||
foreground and background color may be used. The following are
|
||||
valid foreground colors:
|
||||
</p>
|
||||
|
||||
<pre><code> bold underline bold_underline
|
||||
black bold_black underline_black bold_underline_black
|
||||
red bold_red underline_red bold_underline_red
|
||||
green bold_green underline_green bold_underline_green
|
||||
yellow bold_yellow underline_yellow bold_underline_yellow
|
||||
blue bold_blue underline_blue bold_underline_blue
|
||||
magenta bold_magenta underline_magenta bold_underline_magenta
|
||||
cyan bold_cyan underline_cyan bold_underline_cyan
|
||||
white bold_white underline_white bold_underline_white</code></pre>
|
||||
|
||||
<p>
|
||||
and the following are valid background colors:
|
||||
</p>
|
||||
|
||||
<pre><code>on_black on_bright_black
|
||||
on_red on_bright_red
|
||||
on_green on_bright_green
|
||||
on_yellow on_bright_yellow
|
||||
on_blue on_bright_blue
|
||||
on_magenta on_bright_magenta
|
||||
on_cyan on_bright_cyan
|
||||
on_white on_bright_white</code></pre>
|
||||
|
||||
<p>
|
||||
Depending on your terminal color choices, task can display all
|
||||
the colors it supports with the command:
|
||||
</p>
|
||||
|
||||
<img src="images/color.png" />
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
445
html/config.html
445
html/config.html
|
@ -1,445 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Task Configuration</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title"><a name="config">Configuring Task</a></h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
Task recognizes several entries in the .taskrc file for
|
||||
configuration purposes. Valid entries are of the form:
|
||||
</p>
|
||||
|
||||
<pre><code>name=value</code></pre>
|
||||
|
||||
<p>
|
||||
Valid examples are:
|
||||
</p>
|
||||
|
||||
<dt>data.location</dt>
|
||||
<dd>
|
||||
This is a path to the directory containing all the task files.
|
||||
By default, it is set up to be ~/.task, for example:
|
||||
/Users/paul/.task
|
||||
</dd>
|
||||
|
||||
<dt>confirmation</dt>
|
||||
<dd>
|
||||
May be "yes" or "no", and determines whether task will ask for
|
||||
confirmation before deleting a task.
|
||||
</dd>
|
||||
|
||||
<dt>echo.command</dt>
|
||||
<dd>
|
||||
May be "yes" or "no", and causes task to display the ID and
|
||||
description of any task when you run the start, stop, do, undo,
|
||||
delete and undelete commands. The default value is "yes".
|
||||
</dd>
|
||||
|
||||
<dt>nag</dt>
|
||||
<dd>
|
||||
This may be a string of text, or blank. It is used as a prompt
|
||||
when a task is completed that is not considered high priority.
|
||||
The "task next" command lists important tasks, and completing
|
||||
one of those does not generate this nagging. Default value is:
|
||||
|
||||
<strong>Note: try to stick to high priority tasks. See "task next".</strong>
|
||||
</dd>
|
||||
|
||||
<dt>next</dt>
|
||||
<dd>
|
||||
Is a number, defaulting to 2, which is the number of tasks for
|
||||
each project that are shown in the "task next" command.
|
||||
</dd>
|
||||
|
||||
<dt>curses</dt>
|
||||
<dd>
|
||||
Determines whether task uses ncurses to establish the size of
|
||||
the window you are using, for text wrapping.
|
||||
</dd>
|
||||
|
||||
<dt>blanklines</dt>
|
||||
<dd>
|
||||
May be "on" or "off". Prevents the display of unnecessary blank
|
||||
lines so that task makes better use screen real estate on small-
|
||||
screened devices.
|
||||
</dd>
|
||||
|
||||
<dt>dateformat</dt>
|
||||
<dd>
|
||||
<p>
|
||||
This is a string of characters that define how task formats dates.
|
||||
The default value is:
|
||||
</p>
|
||||
|
||||
<pre><code>m/d/Y</code></pre>
|
||||
|
||||
<p>
|
||||
which means dates look like:
|
||||
</p>
|
||||
|
||||
<pre><code>6/7/2008</code></pre>
|
||||
|
||||
<p>
|
||||
The string should contain the characters:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th class="table_h">Character</th>
|
||||
<th class="table_h">Meaning</th>
|
||||
<th class="table_h">Example</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">m</td>
|
||||
<td class="table_d">minimal-digit month</td>
|
||||
<td class="table_d">1, 12</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">d</td>
|
||||
<td class="table_d">minimal-digit day</td>
|
||||
<td class="table_d">1, 30</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">y</td>
|
||||
<td class="table_d">two-digit year</td>
|
||||
<td class="table_d">08</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">M</td>
|
||||
<td class="table_d">two-digit month</td>
|
||||
<td class="table_d">01, 12</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">D</td>
|
||||
<td class="table_d">two-digit day</td>
|
||||
<td class="table_d">01, 30</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">Y</td>
|
||||
<td class="table_d">four-digit year</td>
|
||||
<td class="table_d">2008</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The string may also contain other characters to act as spacers,
|
||||
or formatting. Other values could include (but are not limited to):
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<table>
|
||||
<tr>
|
||||
<th class="table_h">dateformat</td>
|
||||
<th class="table_h">How it looks</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">d/m/Y</td>
|
||||
<td class="table_d">7/6/2008</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">YMD</td>
|
||||
<td class="table_d">20080607</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">m-d-y</td>
|
||||
<td class="table_d">6-7-08</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt>monthsperline</dt>
|
||||
<dd>
|
||||
Determines how many months the "task calendar" command
|
||||
renders across the screen. Defaults to however many will
|
||||
fit. If more months that will fit are specified, task will
|
||||
only show as many that will fit.
|
||||
</dd>
|
||||
|
||||
<dt>weekstart</dt>
|
||||
<dd>
|
||||
The day of the week that represents the first day of the week.
|
||||
Defaults to "Monday".
|
||||
</dd>
|
||||
|
||||
<dt>editor</dt>
|
||||
<dd>
|
||||
Specifies which text editor you wish to use for when the
|
||||
|
||||
<pre><code>task edit <ID></code></pre>
|
||||
|
||||
command is used. Task will first look for this configuration
|
||||
variable. If found, it is used. Otherwise task will look
|
||||
for the VISUAL or EDITOR environment variables, before it
|
||||
defaults to using 'vi'.
|
||||
</dd>
|
||||
|
||||
<dt>defaultwidth</dt>
|
||||
<dd>
|
||||
The width of tables used when ncurses support is not available.
|
||||
Defaults to 80.
|
||||
</dd>
|
||||
|
||||
<dt>due</dt>
|
||||
<dd>
|
||||
|
||||
This is the number of days into the future that define when a
|
||||
task is considered due, and is colored accordingly.
|
||||
Defaults to 7.
|
||||
</dd>
|
||||
|
||||
<dt>color</dt>
|
||||
<dd>
|
||||
May be "on" or "off". Determines whether task uses color.
|
||||
When "off", task will use dashes (-----) to underline column
|
||||
headings.
|
||||
</dd>
|
||||
|
||||
<dt>
|
||||
color.overdue<br />
|
||||
color.due<br />
|
||||
color.pri.H<br />
|
||||
color.pri.M<br />
|
||||
color.pri.L<br />
|
||||
color.pri.none<br />
|
||||
color.active<br />
|
||||
color.tagged<br />
|
||||
color.recurring
|
||||
</dt>
|
||||
<dd>
|
||||
These are the coloration rules. They correspond to a particular
|
||||
attribute of a task, such as it being due, or being active, and
|
||||
specifies the automatic coloring of that task. The value may
|
||||
be one optional foreground color (see below) and one optional
|
||||
background color. For example, the value may be:
|
||||
<br />
|
||||
<strong>bold_red on_bright_yellow</strong>
|
||||
</dd>
|
||||
|
||||
<dt>color.tag.X</dt>
|
||||
<dd>
|
||||
Colors any task that has the tag X.
|
||||
</dd>
|
||||
|
||||
<dt>color.project.X</dt>
|
||||
<dd>
|
||||
Colors any task assigned to project X.
|
||||
</dd>
|
||||
|
||||
<dt>color.keyword.X</dt>
|
||||
<dd>
|
||||
Colors any task where the description contains X.
|
||||
</dd>
|
||||
|
||||
<dt>default.project</dt>
|
||||
<dd>
|
||||
Provides a default project name for the "task add ..." command.
|
||||
</dd>
|
||||
|
||||
<dt>default.priority</dt>
|
||||
<dd>
|
||||
Provides a default priority for the "task add ..." command.
|
||||
</dd>
|
||||
|
||||
<dt>default.command</dt>
|
||||
<dd>
|
||||
<p>
|
||||
Provides a default command that is run every time task is
|
||||
invoked with no arguments. For example, if set to:
|
||||
</p>
|
||||
|
||||
<pre><code>default.command=list project:foo</code></pre>
|
||||
|
||||
<p>
|
||||
Then task will run the "list project:foo" command if no
|
||||
command is specified. This means that by merely typing:
|
||||
</p>
|
||||
|
||||
<pre><code>% task
|
||||
[task list project:foo]
|
||||
|
||||
ID Project Pri Description
|
||||
1 foo H Design the thing
|
||||
2 foo Build the thing</code></pre>
|
||||
|
||||
<p>
|
||||
Note that the value of this variable is simply the command
|
||||
line that you would ordinarily type, but without the
|
||||
preceding "task" program name.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt>shadow.file</dt>
|
||||
<dd>
|
||||
<p>
|
||||
If specified, designates a file path that will be autoamtically
|
||||
written to by task, whenever the task database changes. In other
|
||||
words, it is automatically kept up to date.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The shadow.command configuration variable is used to determine
|
||||
which report is written to the shadow file. There is no color
|
||||
used in the shadow file.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This feature can be useful in maintaining a current file for
|
||||
use by the "Samurize" program.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt>shadow.command</dt>
|
||||
<dd>
|
||||
<p>
|
||||
This is the command that is run to maintain the shadow file,
|
||||
determined by the shadow.file configuration variable. The
|
||||
format is identical to that of default.command - please see
|
||||
the documentation for default.command.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If this command is not specified, task will use the default.command
|
||||
value instead. If that is not specified, the command "list" is used.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt>shadow.notify</dt>
|
||||
<dd>
|
||||
When this value is set to "on", task will display a message
|
||||
whenever the shadow file is updated by some task command.
|
||||
</dd>
|
||||
|
||||
<dt>locking</dt>
|
||||
<dd>
|
||||
<p>
|
||||
Determines whether task uses file locking when accessing the pending.data
|
||||
and completed.data files. Default to "on". Solaris users who store
|
||||
the task data files on an NFS mount may need to set locking to "off".
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Note that setting this value to "off" is dangerous. It means that
|
||||
another program may write to the task.pending file when task is
|
||||
attempting to do the same.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt>import.synonym.id</dt>
|
||||
<dt>import.synonym.uuid</dt>
|
||||
<dt>import.synonym.status</dt>
|
||||
<dt>import.synonym.tags</dt>
|
||||
<dt>import.synonym.entry</dt>
|
||||
<dt>import.synonym.start</dt>
|
||||
<dt>import.synonym.due</dt>
|
||||
<dt>import.synonym.recur</dt>
|
||||
<dt>import.synonym.end</dt>
|
||||
<dt>import.synonym.project</dt>
|
||||
<dt>import.synonym.priority</dt>
|
||||
<dt>import.synonym.fg</dt>
|
||||
<dt>import.synonym.bg</dt>
|
||||
<dt>import.synonym.description</dt>
|
||||
<dd>
|
||||
If any of these configuration variables are found, they influence
|
||||
data import by specifying a single additional field name synonym.
|
||||
If a data import is failing because certain column names are not
|
||||
being recognized, then this is how the field mapping can be
|
||||
controlled.
|
||||
</dd>
|
||||
|
||||
<p>
|
||||
Note that the command:
|
||||
</p>
|
||||
|
||||
<pre><code>task version</code></pre>
|
||||
|
||||
<p>
|
||||
will display the configuration variables found in the .taskrc file,
|
||||
and will warn you of any variables that are not recognized.
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
178
html/custom.html
178
html/custom.html
|
@ -1,178 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Custom Reports</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title">Custom Reports</h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
Task allows you to customize reports, to a limited degree.
|
||||
The "list", "long", "ls", "oldest" and "newest" reports are
|
||||
all now custom reports, whereas in previous releases of task
|
||||
they were not mutable. This means they can be modified,
|
||||
renamed, or deleted.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
More importantly, you can define your own. Here are the
|
||||
three necessary items in the .taskrc file that define a new
|
||||
report:
|
||||
</p>
|
||||
|
||||
<code><pre>report.mine.description=Just the essentials
|
||||
report.mine.columns=id,project,priority,description
|
||||
report.mine.sort=priority-,project+</pre></code>
|
||||
|
||||
<p>
|
||||
This defines a report, called "mine", that has four columns:
|
||||
id, project, priority and description. It will be sorted on
|
||||
two columns: by descending priority then ascending project.
|
||||
The description that shows up in the task command usage page
|
||||
is "Just the essentials". Because this report is called
|
||||
"mine", it can be run with the command:
|
||||
</p>
|
||||
|
||||
<code><pre>% task mine</pre></code>
|
||||
|
||||
<p>
|
||||
An optional filter can also be specified like this:
|
||||
</p>
|
||||
|
||||
<code><pre>report.mine.filter=priority:H +bug</pre></code>
|
||||
|
||||
<p>
|
||||
This adds a filter so that only tasks with priority "H" and
|
||||
with the "bug" tag are included in the report. This filter
|
||||
definition is optional.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
An optional limit can also be specified, which limits the
|
||||
number of tasks shown in the report. If a limit is not
|
||||
specified, then the number of tasks is not limited.
|
||||
</p>
|
||||
|
||||
<code><pre>report.mine.limit=10</pre></code>
|
||||
|
||||
<p>
|
||||
Here is a list of all the possible columns that may be included
|
||||
in a report:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It is also possible to override the default columns names, if
|
||||
the following line is added to your .taskrc file:
|
||||
</p>
|
||||
|
||||
<pre><code>report.mine.labels=ID,Project,Priority,Description of task</code></pre>
|
||||
|
||||
<p>
|
||||
Note that there must be the same number of labels as there are
|
||||
columns to label, and they must appear in the same sequence.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>id
|
||||
<li>uuid
|
||||
<li>project
|
||||
<li>priority
|
||||
<li>entry
|
||||
<li>start
|
||||
<li>due
|
||||
<li>age
|
||||
<li>active
|
||||
<li>tags
|
||||
<li>recur
|
||||
<li>description_only
|
||||
<li>description
|
||||
<li>tag_indicator
|
||||
<li>recurrence_indicator
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Custom reports will show up in the task command line usage.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
160
html/date.html
160
html/date.html
|
@ -1,160 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Date Handling</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title">Date Handling</h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
Task reads dates from the command line, and displays dates in the reports.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In order to do this in a flexible way, task obeys a configuration variable that
|
||||
determines the expected and desired date format. See the
|
||||
<a href="config.html">Configuring Task</a> page for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In addition to exactly specifying the date, such as:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ... due:7/10/2008</code></pre>
|
||||
|
||||
<p>
|
||||
task supports a flexible variety of alternatives. For example:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ... due:today</code></pre>
|
||||
|
||||
<p>
|
||||
Similarly:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ... due:yesterday
|
||||
% task ... due:tomorrow</code></pre>
|
||||
|
||||
<p>
|
||||
Here are some other forms that are accepted. The day number, followed by an
|
||||
ordinal:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ... due:23rd</code></pre>
|
||||
|
||||
<p>
|
||||
End of month:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ... due:eom</code></pre>
|
||||
|
||||
<p>
|
||||
End of year:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ... due:eoy</code></pre>
|
||||
|
||||
<p>
|
||||
End of week (Friday):
|
||||
</p>
|
||||
|
||||
<pre><code>% task ... due:eow</code></pre>
|
||||
|
||||
<p>
|
||||
Next Friday:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ... due:Friday</code></pre>
|
||||
|
||||
<p>
|
||||
Note that next Friday means seven days from now if today is Friday, otherwise
|
||||
it means the next occurring Friday. Most of these forms may be specified using
|
||||
abbreviations, provided they are unique. For example:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ... due:fri</code></pre>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
239
html/faq.html
239
html/faq.html
|
@ -1,239 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Frequently Asked Questions</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title">Frequently Asked Questions</h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
(Actually, that's a misnomer. These are really Repeatedly Asked
|
||||
Questions.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>
|
||||
Q: When I redirect the output of task to a file, I lose all
|
||||
the colors. How do I fix this?
|
||||
</b>
|
||||
<br />
|
||||
A: Task knows (or thinks it knows) when the output is not going
|
||||
directly to a terminal, and strips out all the color control
|
||||
characters. Prevent this with the following entry in your
|
||||
.taskrc file:
|
||||
<pre><code>_forcecolor=on</code></pre>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
<b>
|
||||
Q: How do I backup my task data files? Where are they?
|
||||
</b>
|
||||
<br />
|
||||
A: Task writes all pending tasks to the file ~/.task/pending.data
|
||||
and all completed and deleted tasks to ~/.task/completed.data.
|
||||
They are text files, so they can just be copied to another
|
||||
location for safekeeping. Don't forget there is also the
|
||||
~/.taskrc file that contains your task configuration data.
|
||||
To be sure, and to future-proof your backup, consider backing
|
||||
up all the files in the ~/.task directory.
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
<b>
|
||||
Q: How can I separate my work tasks from my home tasks?
|
||||
Specifically, can I keep them completely separate?
|
||||
</b>
|
||||
<br />
|
||||
A: You can do this by creating an alternate .taskrc file,
|
||||
then using shell aliases. Here is are example Bash
|
||||
commands to achieve this:
|
||||
|
||||
<pre><code>% cp ~/.taskrc ~/.taskrc_home
|
||||
% (now edit .taskrc_home to change the value of data.location)
|
||||
% alias wtask="task"
|
||||
% alias htask="task rc:~/.taskrc_home"</code></pre>
|
||||
|
||||
This gives you two commands, 'wtask' and 'htask' that
|
||||
operate using two different sets of task data files.
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
<b>
|
||||
Q: Can I revert to a previous version of task? How?
|
||||
</b>
|
||||
<br />
|
||||
A: Yes, you can revert to a previous version of task,
|
||||
simply by downloading an
|
||||
<a href="versions.html">older version</a> and
|
||||
installing it. If you find a bug in task, then this
|
||||
may be the only way to work around the bug, until a
|
||||
new release is made.
|
||||
</p>
|
||||
<p>
|
||||
Note that it is possible that the task file format will
|
||||
change. For example, the format changed between versions
|
||||
1.5.0 and 1.6.0. Task will automatically upgrade the file
|
||||
but if you need to revert to a previous version of task,
|
||||
there is the file format to consider. This is yet another
|
||||
good reason to back up your task data files!
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
<b>
|
||||
Q: I'm using Ubuntu 9.04, and I want task to word-wrap
|
||||
descriptions. How do I do this?
|
||||
</b>
|
||||
<br />
|
||||
A: You need to install ncurses, by doing this:
|
||||
<code><pre>% sudo apt-get install libncurses5-dev</pre></code>
|
||||
Then you need to rebuild task from scratch, starting with
|
||||
<code><pre>% cd task-X.X.X
|
||||
% ./configure
|
||||
...</pre></code>
|
||||
The result should be a task program that knows the width
|
||||
of the terminal window, and wraps accordingly.
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
<b>
|
||||
Q: How do I build task under Cygwin?
|
||||
</b>
|
||||
<br />
|
||||
A: Task is built the same way everywhere. But under Cygwin, you'll
|
||||
need to make sure you have the following packages available
|
||||
first:
|
||||
|
||||
<ul>
|
||||
<li>gcc
|
||||
<li>make
|
||||
<li>libncurses-devel
|
||||
<li>libncurses8
|
||||
</ul>
|
||||
|
||||
The gcc and make packages allow you to compile the code, and
|
||||
are therefore required, but the ncurses packages are optional.
|
||||
Ncurses will allow task to determine the width of the window, and
|
||||
therefore use the whole width and wrap text accordingly, for a
|
||||
more aesthetically pleasing display.
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
<b>
|
||||
Q: Do colors work under Cygwin?
|
||||
</b>
|
||||
<br />
|
||||
A: They do, but only in a limited way. You can use regular
|
||||
foreground colors (black, red, green ...) and you can
|
||||
regular background colors (on_black, on_red, on_green ...),
|
||||
but underline and bold are not supported.
|
||||
<br />
|
||||
<br />
|
||||
If you run the command:
|
||||
<code><pre>% task colors</pre></code>
|
||||
Task will display all the colors it can use, and you will
|
||||
see which ones you can use.
|
||||
<br />
|
||||
<br />
|
||||
See the <a href="color.html">color</a> documentation for
|
||||
more details on which colors can be used.
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<!--
|
||||
<p>
|
||||
<b>
|
||||
Q:
|
||||
</b>
|
||||
<br />
|
||||
A:
|
||||
</p>
|
||||
<hr>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
132
html/filter.html
132
html/filter.html
|
@ -1,132 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Task Filters</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title">Task Filters</h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
A task filter is a means of reducing a task report to a
|
||||
subset that may consist of all tasks that have a specific
|
||||
project, priority, tag, or part of the description.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A task filter consists of additional command line options,
|
||||
that are specified in the same way as when a task is added.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
All task reports can make use of filters.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, the report:
|
||||
</p>
|
||||
|
||||
<code><pre>% task list</pre></code>
|
||||
|
||||
<p>
|
||||
Lists all tasks.
|
||||
</p>
|
||||
|
||||
<code><pre>% task list the</pre></code>
|
||||
|
||||
<p>
|
||||
Lists only tasks with "the" in the task description.
|
||||
</p>
|
||||
|
||||
<code><pre>% task list project:Home priority:H</pre></code>
|
||||
|
||||
<p>
|
||||
Lists only tasks with both the "Home" project and "H" priority.
|
||||
</p>
|
||||
|
||||
<code><pre>% task list +shopping</pre></code>
|
||||
|
||||
<p>
|
||||
Lists only tasks with the "shopping" tag.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
409
html/git.html
409
html/git.html
|
@ -1,409 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>git</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title"><a name="simple">Using git</a></h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
First you need to tell git who you are. These commands will
|
||||
write to ~/.gitconfig, and will be used to identify you when
|
||||
you commit changes. Plus, I like color.
|
||||
</p>
|
||||
|
||||
<pre><code>% git config --global user.name "John Doe"
|
||||
% git config --global user.email "john@doe.com"
|
||||
% git config --global color.ui=always</code></pre>
|
||||
|
||||
<p>
|
||||
Now we will clone the repository, which involves downloading
|
||||
about 2MB of files. Git repositories are very compact. We
|
||||
will clone the repository from github. This takes a minute or
|
||||
so.
|
||||
</p>
|
||||
|
||||
<pre><code>% cd
|
||||
% git clone git://github.com/pbeckingham/task.git task.git
|
||||
% cd task.git</code></pre>
|
||||
|
||||
<p>
|
||||
You just pulled the entire history of task changes since it
|
||||
was uploaded to github. That will be missing about a year and
|
||||
a half of prior changes, which were in Subversion. Let's
|
||||
build task:
|
||||
</p>
|
||||
|
||||
<pre><code>% autoreconf
|
||||
...
|
||||
% ./configure --prefix=/usr/local
|
||||
...
|
||||
% make
|
||||
...</code></pre>
|
||||
|
||||
<p>
|
||||
The task binary will be in the src directory. If you run:
|
||||
</p>
|
||||
|
||||
<pre><code>% sudo make install</code></pre>
|
||||
|
||||
<p>
|
||||
Then task will be copied to /usr/local/bin, according the
|
||||
--prefix argument used above. /usr/local is the default
|
||||
prefix, so that argument wasn't necessary, but illustrates
|
||||
it's use.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Meanwhile, you have just created a local copy of the
|
||||
repository. You can do anything to this copy except push to
|
||||
github. Only the repository owner can push to github, or
|
||||
additional users identified by the owner (with additional
|
||||
monthly github fee). In order to get your changes back to
|
||||
github, they have to go through the owner, either in the form
|
||||
of a patch via email, or by creating your own github account,
|
||||
pushing to you own task repository clone (github calls it a
|
||||
fork), then asking the owner to pull directly from your
|
||||
repository.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You only need to clone once, unless you feel like starting
|
||||
over, or creating additional clones. Ordinarily, you update
|
||||
your local copy by pulling changes from github with:
|
||||
</p>
|
||||
|
||||
<pre><code>% git pull</code></pre>
|
||||
|
||||
<p>
|
||||
Right now, nothing new should be pulled, because you just
|
||||
cloned. Sometimes you'll see changes that have either been
|
||||
made by the owner, or merged in from others, by the owner.
|
||||
Let's take a look at the commit history:
|
||||
</p>
|
||||
|
||||
<pre><code>% git log</code></pre>
|
||||
|
||||
<p>
|
||||
You see a whole series of commits. Each commit is a set of
|
||||
file changes that were made somewhere. Let's look at branches.
|
||||
Try this:
|
||||
</p>
|
||||
|
||||
<pre><code>% git branch
|
||||
* master</code></pre>
|
||||
|
||||
<p>
|
||||
This is telling you that you have only one branch, called
|
||||
master. The asterisk tells you that this is your current
|
||||
branch, which is redundant because you only have one. But
|
||||
there are other branches on github. See those with:
|
||||
</p>
|
||||
|
||||
<pre><code>% git branch -a
|
||||
* master
|
||||
remotes/origin/1.6.1
|
||||
remotes/origin/1.7.0
|
||||
remotes/origin/HEAD -> origin/master
|
||||
remotes/origin/master</code></pre>
|
||||
|
||||
<p>
|
||||
A remote is what git calls another repository. The origin
|
||||
remote is the repository that this clone originated from.
|
||||
This output tells you that there is a 1.6.1 branch on github,
|
||||
a 1.7.0 branch on github, and a master branch on github. It's
|
||||
not obvious, but your local master (the first one shown) is
|
||||
tracking remotes/origin/master, which means changes on the
|
||||
remote will get merged to the local tracking branch on pull.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The convention used by task is to create a new branch whenever
|
||||
work begins on a new version. When that version is released,
|
||||
the branch is merged to master, but retained. At time of
|
||||
writing, 1.6.1 is the currently released version of task, and
|
||||
so remotes/origin/1.6.1 and remotes/origin/master are
|
||||
currently identical, with all new development happening on the
|
||||
1.7.0 branch. When 1.7.0 is released, it will get merged to
|
||||
master, and the 1.6.1 branch will be deleted. Nothing will be
|
||||
lost, because 1.6.1 is already merged to master. Let's look
|
||||
at tags:
|
||||
</p>
|
||||
|
||||
<pre><code>% git tag</code></pre>
|
||||
...
|
||||
v1.4.3
|
||||
v1.5.0
|
||||
v1.6.0
|
||||
v1.6.1
|
||||
|
||||
<p>
|
||||
Those tags are just labels that represent the last commit for
|
||||
that version. You may notice that a change in the tag naming
|
||||
convention, that occurred when the owner realized that git
|
||||
will not allow a tag and a branch of the same name at the same
|
||||
time, so now there is a "v" in the tags.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Let's make a branch called 1.7.0 that tracks changes to
|
||||
remotes/origin/1.7.0. That means you can pull 1.7.0 changes
|
||||
from github into your local branch, to keep up to date.
|
||||
</p>
|
||||
|
||||
<pre><code>% git checkout -b 1.7.0 origin/1.7.0
|
||||
Branch 1.7.0 set up to track remote branch 1.7.0 from origin.
|
||||
Switched to a new branch '1.7.0'
|
||||
|
||||
% git branch -a
|
||||
* 1.7.0
|
||||
master
|
||||
remotes/origin/1.6.1
|
||||
remotes/origin/1.7.0
|
||||
remotes/origin/HEAD -> origin/master
|
||||
remotes/origin/master</code></pre>
|
||||
|
||||
<p>
|
||||
Now you can see that 1.7.0 is your current branch (*). That
|
||||
means you are looking at the 1.7.0 codebase. Let us now
|
||||
assume you intend to make a change, and submit the patch. We
|
||||
will add Solaris 8 as a supported OS. This will affect two
|
||||
files. First check status:
|
||||
</p>
|
||||
|
||||
<pre><code>% git status
|
||||
# On branch 1.7.0
|
||||
nothing to commit (working directory clean)</code></pre>
|
||||
|
||||
<p>
|
||||
No changes. That's what we expect. Now make the changes (any
|
||||
editor will suffice, but assume vi):
|
||||
</p>
|
||||
|
||||
<pre><code>% vi NEWS
|
||||
% vi html/task.html</code></pre>
|
||||
|
||||
<p>
|
||||
Now we expect to see changes. Status says:
|
||||
</p>
|
||||
|
||||
<pre><code>% git status
|
||||
# On branch 1.7.0
|
||||
# Changed but not updated:
|
||||
# (use "git add <file>..." to update what will be committed)
|
||||
# (use "git checkout -- <file>..." to discard changes in working directory)
|
||||
#
|
||||
# modified: NEWS
|
||||
# modified: html/task.html
|
||||
#
|
||||
no changes added to commit (use "git add" and/or "git commit -a")</code></pre>
|
||||
|
||||
<p>
|
||||
Git sees that those two files have changed, but as git states,
|
||||
they are not added to the commit. Git allows you to stage
|
||||
changes, then commit the staged changes - a two-step process
|
||||
that gives you complete control. Git also allows you to
|
||||
commit all changes and bypass the staging, but that's a
|
||||
shortcut that is risky, because you can inadvertently commit
|
||||
things you didn't want to. Let's see what git thinks changed:
|
||||
</p>
|
||||
|
||||
<pre><code>% git diff
|
||||
diff --git a/NEWS b/NEWS
|
||||
index 74adecd..30d4f8f 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -12,6 +12,7 @@ Task has been built and tested on the following configurations:
|
||||
- Ubuntu 8.10 Intrepid Ibex
|
||||
- Ubuntu 9.04 Jaunty Jackalope
|
||||
- Arch Linux
|
||||
+ - Solaris 8
|
||||
- Solaris 10
|
||||
- Cygwin 1.5.25-14
|
||||
|
||||
diff --git a/html/task.html b/html/task.html
|
||||
index 66ee777..a2254f6 100644
|
||||
--- a/html/task.html
|
||||
+++ b/html/task.html
|
||||
@@ -193,6 +193,7 @@
|
||||
<li>Ubuntu 8.10 Intrepid Ibex
|
||||
<li>Ubuntu 9.04 Jaunty Jackalope
|
||||
<li>Arch Linux
|
||||
+ <li>Solaris 8
|
||||
<li>Solaris 10
|
||||
<li>Cygwin 1.5.25-14
|
||||
</ul></code></pre>
|
||||
|
||||
<p>
|
||||
Git has correctly spotted the changes. The "git diff" command
|
||||
always tells you the difference between the last commit and
|
||||
the current state. Now we will stage the two changes:
|
||||
</p>
|
||||
|
||||
<pre><code>% git add NEWS html/task.html
|
||||
% git diff</code></pre>
|
||||
|
||||
<p>
|
||||
No changes are reported. That's because if files are staged,
|
||||
then diff shows the difference between the staged files and
|
||||
the current state. We staged all changes, hence no diff. If
|
||||
we wanted to see the difference between the last commit and
|
||||
the staged files, try this:
|
||||
</p>
|
||||
|
||||
<pre><code>% git diff --cached
|
||||
(same as unstaged diff)</code></pre>
|
||||
|
||||
<p>
|
||||
Now the status shows that the files are staged:
|
||||
</p>
|
||||
|
||||
<pre><code>% git status
|
||||
# On branch 1.7.0
|
||||
# Changes to be committed:
|
||||
# (use "git reset HEAD <file>..." to unstage)
|
||||
#
|
||||
# modified: NEWS
|
||||
# modified: html/task.html
|
||||
#</code></pre>
|
||||
|
||||
<p>
|
||||
Now a commit command will commit the staged files:
|
||||
</p>
|
||||
|
||||
<pre><code>% git commit -m "Added Solaris 8 as a supported platform"
|
||||
[1.7.0 03308eb] Added Solaris 8 as a suported platform
|
||||
2 files changed, 2 insertions(+), 0 deletions(-)</code></pre>
|
||||
|
||||
<p>
|
||||
Now make a patch:
|
||||
</p>
|
||||
|
||||
<pre><code>% git format-patch HEAD^
|
||||
0001-Added-Solaris-8-as-a-supported-platform.patch</code></pre>
|
||||
|
||||
<p>
|
||||
HEAD is a label that means the current head of the branch, or
|
||||
in other words, what was last committed. HEAD^ means the
|
||||
commit before that. HEAD~2 is the one before that, HEAD~3
|
||||
etc. When we say create a patch of HEAD^, it means the same
|
||||
as:
|
||||
</p>
|
||||
|
||||
<pre><code>% git diff HEAD^</code></pre>
|
||||
|
||||
<p>
|
||||
Which means show the difference between the previous commit
|
||||
and the current commit, but the patch has extra identifying
|
||||
information in it. Take a look at that patch file. If you
|
||||
ran:
|
||||
</p>
|
||||
|
||||
<pre><code>% git format-patch HEAD~10</code></pre>
|
||||
|
||||
<p>
|
||||
Git will create 10 patch files, one for each commit. To get
|
||||
the patch applied to the repository, email it to the owner.
|
||||
The owner will then apply the patch with:
|
||||
</p>
|
||||
|
||||
<pre><code>owner> git apply 0001-Added-Solaris-8-as-a-supported-platform.patch</code></pre>
|
||||
|
||||
<p>
|
||||
Then push the changes with:
|
||||
</p>
|
||||
|
||||
<pre><code>owner> git push</code></pre>
|
||||
|
||||
<p>
|
||||
And that makes them available on github, which means in turn
|
||||
that the next time you run:
|
||||
</p>
|
||||
|
||||
<pre><code>% git pull</code></pre>
|
||||
|
||||
<p>
|
||||
Your changes will have come full circle.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 65 KiB |
157
html/import.html
157
html/import.html
|
@ -1,157 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Data Import</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title">Data Import</h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
Tasks can be imported from files with this command:
|
||||
|
||||
<pre><code>% task import file</code></pre>
|
||||
|
||||
A variety of different file types are recognized by task, namely:
|
||||
|
||||
<ul>
|
||||
<li>Tasks exported from task prior to version 1.5.0.
|
||||
<li>Tasks exported from task version 1.5.0 and later. The file
|
||||
format changed with 1.5.0.
|
||||
<li>todo.sh files.
|
||||
<li>CSV files with a variety of recognized column names.
|
||||
<li>Plain text files, with one task listed per line.
|
||||
<li>Task command line format.
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Task makes a good effort to determine which of these formats a
|
||||
file is. It does this by reading the file, and looking for
|
||||
familiar patterns. For example, the easiest files to recognize
|
||||
are those exported from task itself, because they all have a
|
||||
header line that comes in only three variations. Other formats
|
||||
are a little harder to identify, but they all have their own
|
||||
identifying characteristics.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The most complex import is when a CSV file is recognized.
|
||||
Task needs a field header line in order to map columns to task
|
||||
data items. For example, the if the following file is
|
||||
imported:
|
||||
</p>
|
||||
|
||||
<pre><code>number,status,task
|
||||
1,pending,task one
|
||||
2,pending,task two</code></pre>
|
||||
|
||||
<p>
|
||||
Task will map the "number" field to task's "id" field, etc,
|
||||
based on name. Task has a list of synonyms that it uses to
|
||||
map fields, but you can specify your own override with any of
|
||||
the following configuration variables:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>import.synonym.id
|
||||
<li>import.synonym.uuid
|
||||
<li>import.synonym.status
|
||||
<li>import.synonym.tags
|
||||
<li>import.synonym.entry
|
||||
<li>import.synonym.start
|
||||
<li>import.synonym.due
|
||||
<li>import.synonym.recur
|
||||
<li>import.synonym.end
|
||||
<li>import.synonym.project
|
||||
<li>import.synonym.priority
|
||||
<li>import.synonym.fg
|
||||
<li>import.synonym.bg
|
||||
<li>import.synonym.description
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Please note that it is wise to backup your task data files
|
||||
before an import.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
213
html/links.html
213
html/links.html
|
@ -1,213 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Task on the Web</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h1 class="title">Task on the Web</h1>
|
||||
<p>
|
||||
Task links from around the web...
|
||||
</p>
|
||||
|
||||
<dt>
|
||||
February 2009, <a href="http://lifehacker.com/5155450/todotxt-cli-manages-your-tasks-from-the-command-line">Todo.txt CLI Manages Your Tasks from the Command Line</a>
|
||||
</dt>
|
||||
<dd>
|
||||
Gina Trapani generously mentions task in an article about the newly updated, todo.sh 2.0.
|
||||
</dd>
|
||||
<br>
|
||||
|
||||
<dt>
|
||||
February, 2009, <a href="http://forum.worklifecreativity.net/index.php/topic,219.0.html">My command line based task management tools</a>
|
||||
</dt>
|
||||
<dd>
|
||||
Richard Querin talks about his task management tools.
|
||||
Richard generously provides the Debian packages for task.
|
||||
</dd>
|
||||
<br>
|
||||
|
||||
<dt>
|
||||
February, 2009, <a href="http://wiki.archlinux.org/index.php/Common_Apps">Common Apps</a>
|
||||
</dt>
|
||||
<dd>
|
||||
<a href="http://wiki.archlinux.org">Archlinux.org</a> mentions task on a page which is
|
||||
a point of reference for people looking for software to fill a particular need.
|
||||
</dd>
|
||||
<br>
|
||||
|
||||
<dt>
|
||||
November 2008, <a href="http://github.com/pbeckingham/task/tree/master/">Task repository on GitHub</a>
|
||||
</dt>
|
||||
<dd>
|
||||
For developers: the task git repository on github.com is now public.
|
||||
</dd>
|
||||
<br>
|
||||
|
||||
<dt>
|
||||
October 2008, <a href="http://blog.rfquerin.org/2008/10/07/using-task-and-dropbox-to-manage-your-to-do-list/">Using Task and Dropbox to manage your To-Do list</a>
|
||||
</dt>
|
||||
<dd>
|
||||
by Richard Querin. Richard discusses the ease of setting up task to
|
||||
use DropBox to share todo lists between work and home.
|
||||
</dd>
|
||||
<br>
|
||||
|
||||
<dt>
|
||||
September 2008, <a href="http://stasantons.blogspot.com/2008/09/task-program-visually-simple.html">Task visualization</a>
|
||||
</dt>
|
||||
<dd>
|
||||
by Stas Antons. Stas - a colleague of mine - presents a visualization
|
||||
of the simplicity of task.
|
||||
</dd>
|
||||
<br>
|
||||
|
||||
<dt>
|
||||
June 2008, <a href="http://blog.rfquerin.org/2008/06/17/building-debian-packages-for-task/">Building Debian Packages For Task</a>
|
||||
</dt>
|
||||
<dd>
|
||||
by Richard Querin. Richard has been providing Debian packages for the
|
||||
various task releases, and discusses how he got up to speed.
|
||||
</dd>
|
||||
<br>
|
||||
|
||||
<dt>
|
||||
June 2008, <a href="http://blog.rfquerin.org/2008/06/06/task-101-an-attempt-at-a-cygwin-build-how-to/">Task 1.0.1 - an attempt at a Cygwin Build How-To</a>
|
||||
</dt>
|
||||
<dd>
|
||||
by Richard Querin. Richard shows us how to build task using Cygwin, after
|
||||
a cry for help on the todo.txt mailing list.
|
||||
</dd>
|
||||
<br>
|
||||
|
||||
<dt>
|
||||
June 2008, <a href="http://www.youtube.com/watch?v=D2Kn4DMOVSw">The second task movie</a>
|
||||
</dt>
|
||||
<dd>
|
||||
This YouTube movie was made to illustrate some of the features of the task
|
||||
program, back when task 1.0.0 was released. While task has grown
|
||||
significantly since then, the commands shown are still valid. It will
|
||||
soon be time for a new movie!
|
||||
<p>
|
||||
|
||||
This movie has a voice-over that explains what is going on.
|
||||
<p>
|
||||
|
||||
For a higher-quality version, download the whole
|
||||
<a href="http://www.beckingham.net/todo2.mov">movie file (10MB)</a>.
|
||||
</dd>
|
||||
<br>
|
||||
|
||||
<dt>
|
||||
December 2006, <a href="http://www.youtube.com/watch?v=l68LCl6BYvs">The first task movie</a>
|
||||
</dt>
|
||||
<dd>
|
||||
This original YouTube task movie was made to illustrate the features of the
|
||||
then-unreleased task program. The idea was to get some feedback and see
|
||||
whether anyone was interested in a new implementation of todo.sh, that added
|
||||
features that are not easily possible with a shell implementation.
|
||||
<p>
|
||||
|
||||
This movie has no voice-over, and you may notice that it exactly duplicates
|
||||
the commands used in the original todo.sh movie (below). That is, until it
|
||||
deviates because of new task commands.
|
||||
</dd>
|
||||
<br>
|
||||
|
||||
<dt>
|
||||
June 2006, <a href="http://www.youtube.com/watch?v=daJ1Hs_y738">The original todo.sh movie</a>
|
||||
</dt>
|
||||
<dd>
|
||||
by Gina Trapani. This is the original YouTube todo.sh movie, made to
|
||||
illustrate the power and simplicity of the original todo.sh program.
|
||||
</dd>
|
||||
<br>
|
||||
|
||||
<dt>
|
||||
June 2006, <a href="http://todotxt.com/">Todo.sh, the inspiration for task</a>
|
||||
</dt>
|
||||
<dd>
|
||||
by Gina Trapani. The website that introduced me to the power and
|
||||
simplicity of the original todo.sh program. Contains useful links
|
||||
and resources - take a look!
|
||||
</dd>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
219
html/recur.html
219
html/recur.html
|
@ -1,219 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Recurring Tasks</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title">Recurring Tasks</h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
Task supports recurring tasks, which is a task that keeps falling due, on a
|
||||
regular schedule. An example of this may be "pay rent". Here is how
|
||||
recurring tasks work in task:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Ordinarily, a task is a single item that is entered in the pending state, and
|
||||
remains so until it is either completed or deleted. This is an example of a
|
||||
single instance task.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A recurring task is different. When a recurring task is entered, it remains
|
||||
hidden from view, but acts as a root task for a task instances that are
|
||||
generated on a regular basis. Consider the example:
|
||||
</p>
|
||||
|
||||
<pre><code>% task add Pay rent due:7/1/2008 recur:monthly</code></pre>
|
||||
|
||||
<p>
|
||||
If today's date is 7/10, for example, then that due date is in the past, and
|
||||
you might expect there to be an already overdue task for 7/1/2008, and another
|
||||
due on 8/1/2008. This means that from that root, task has created two
|
||||
instances with different due dates.
|
||||
</p>
|
||||
|
||||
<pre><code>% task list
|
||||
|
||||
ID Project Pri Due Active Age Description
|
||||
1 7/1/2008 1 min Pay rent
|
||||
2 8/1/2008 1 min Pay rent
|
||||
|
||||
2 tasks</code></pre>
|
||||
|
||||
<p>
|
||||
Task creates any overdue tasks, then creates one additional due task. These
|
||||
new task instances are then completed or deleted as you normally would.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the example above, a new task instance is created every month, and this will
|
||||
repeat indefinitely. Task also supports an end date. Suppose you are taking
|
||||
every Friday off work for the summer. You'll need to submit your TPS report on
|
||||
Thursdays instead:
|
||||
</p>
|
||||
|
||||
<pre><code>% task add TPS report due:thursday recur:weekly until:8/31/2008</code></pre>
|
||||
|
||||
<p>
|
||||
This create a weekly recurring task that expires on 8/31/2008. What this means
|
||||
is that after all those task instances have been created, then completed or
|
||||
deleted, the root task will expire and disappear. Task will tell you what it
|
||||
is doing when this happens.
|
||||
</p>
|
||||
|
||||
<h4>Deletion</h4>
|
||||
<p>
|
||||
When a recurring task is deleted, you will be asked if you would also like to
|
||||
delete all recurring task instances:
|
||||
</p>
|
||||
|
||||
<pre><code>% task del 1
|
||||
Permanently delete task? (y/n) y
|
||||
This is a recurring task. Do you want to delete all pending
|
||||
recurrences of this same task? (y/n) y</code></pre>
|
||||
|
||||
<h4>Modification</h4>
|
||||
<p>
|
||||
When a recurring task is modified, all the other recurring task instances will
|
||||
be modified. For example, if you raise the priority of one of the recurring
|
||||
task instances, all will be modified.
|
||||
</p>
|
||||
|
||||
<h4>Recurrence Periods</h4>
|
||||
<p>
|
||||
In the above examples, the recurrence period was specified as "monthly" and
|
||||
"weekly". Task supports several ways of specifying this:
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th class="table_h">Period</th>
|
||||
<th class="table_h">Meaning</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">daily, day, 1d, 2d ...</td>
|
||||
<td class="table_d">Every day, or a number of days</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">weekdays</td>
|
||||
<td class="table_d">
|
||||
Monday, Tuesday, Wednesday, Thursday and Friday,
|
||||
skipping weekend days
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">weekly, 1w, 2w ...</td>
|
||||
<td class="table_d">Every week, or a number of weeks</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">biweekly, fortnight</td>
|
||||
<td class="table_d">Every two weeks</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">monthly, 1m, 2m ...</td>
|
||||
<td class="table_d">Every month, or a number of months</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">bimonthly</td>
|
||||
<td class="table_d">Every two months</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">quarterly, 1q, 2q ...</td>
|
||||
<td class="table_d">Every three months, a quarter, or a number of quarters</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">semiannual</td>
|
||||
<td class="table_d">Every six months</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">annual, yearly, 1y, 2y ...</td>
|
||||
<td class="table_d">Every year, or a number of years</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="table_d">biannual, biyearly, 2y</td>
|
||||
<td class="table_d">Every two-years</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Task Usage</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h1 class="title">ID Sequences</h1>
|
||||
<div class="content">
|
||||
<p>
|
||||
Some task commands require an ID to be specified. For example:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 3 done</code></pre>
|
||||
|
||||
<p>
|
||||
This marks a single task as done. But if you wanted to mark
|
||||
several tasks as done, you could use:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 3,4,5 done</code></pre>
|
||||
|
||||
<p>
|
||||
Which would mark tasks 3, 4 and 5 as all done. In this example,
|
||||
the three IDs are consecutive, which means you could also have
|
||||
entered:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 3-5 done</code></pre>
|
||||
|
||||
<p>
|
||||
Or in a more complex example:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 1,3-5,12 23-25 done</code></pre>
|
||||
|
||||
<p>
|
||||
This would mark tasks 1, 3, 4, 5, 12, 23, 24 and 25 as done.
|
||||
Note that this example uses two sequences, separated by a space.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You must be careful though. Task tries very carefully to do
|
||||
the right thing when it interprets the command line, but must
|
||||
still impose some rules so that it can unambiguously read the
|
||||
command. If you use one or more sequences, then they must
|
||||
appear on the command line adjacent to each other. If they
|
||||
are separated by something else, then task assumes the second
|
||||
and subsequent set is not a sequence. Here is an example
|
||||
of this:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 3 Order part number 4-123</code></pre>
|
||||
|
||||
<p>
|
||||
Clearly the 4-123 is a part number, and not a sequence.
|
||||
Task is being asked to modify the description of task 3 to be
|
||||
"Order part number 4-123". Note that the ID is separated
|
||||
from the part number by something other than a sequence.
|
||||
Here is a bad example that task will misinterpret:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 3 4-123 is back-ordered, try again next week</code></pre>
|
||||
|
||||
<p>
|
||||
The intent here is that task 3 have its description modified to be
|
||||
"4-123 is back-ordered, try again next week", but will be
|
||||
misinterpreted as tasks 3, 4, 5, 6 ... 123 will all be modified
|
||||
to have the description "is back-ordered, try again next week".
|
||||
The solution is to quote the whole description:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 3 "4-123 is back-ordered, try again next week"</code></pre>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
140
html/setup.html
140
html/setup.html
|
@ -1,140 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Task Setup</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title"><a name="setup">Quick Setup</a></h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
Build the task program according to the directions in the INSTALL
|
||||
file. This transcript illustrates a typical installation:
|
||||
</p>
|
||||
|
||||
<pre><code>% ls
|
||||
task-1.6.0.tar.gz
|
||||
% gunzip task-1.6.0.tar.gz
|
||||
% tar xf task-1.6.0.tar
|
||||
% cd task-1.6.0
|
||||
% ./configure
|
||||
...
|
||||
% make
|
||||
...
|
||||
% make install # (may require sudo, depending on --prefix)</code></pre>
|
||||
|
||||
<p>
|
||||
(For those of you using <a href="http://www.cygwin.com">Cygwin</a>,
|
||||
you need to make sure you have the "gcc" and "make" packages
|
||||
available, which are found in the "devel" category. For more
|
||||
task features, also make sure you have "libncurses-devel" and
|
||||
"lincurse8".)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You need to make sure that the installed task program is in your
|
||||
PATH environment variable.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Task reads a configuration file - called .taskrc in your home
|
||||
directory - and stores pending and completed tasks in in a directory
|
||||
specified in the configuration file.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The simplest way to get a configuration file and task directory is
|
||||
to run task. On startup, task will check to see if it can find the
|
||||
configuration file and task directory, and if not found, will ask
|
||||
you whether it may create both.
|
||||
</p>
|
||||
|
||||
<pre><code>% task version
|
||||
|
||||
A configuration file could not be found in /Users/paul/.taskrc
|
||||
|
||||
Would you like a sample .taskrc created, so task can proceed? (y/n) y
|
||||
Done.
|
||||
|
||||
[then task will show version information]</code></pre>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
128
html/shadow.html
128
html/shadow.html
|
@ -1,128 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Task Shadow Files</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title">Task Shadow Files</h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
A shadow file is a text file containing a copy of a task
|
||||
report. It is automatically maintained by task whenever
|
||||
something changes in the task database.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This means there is always a current version of the task
|
||||
report kept in a text file. Products such as
|
||||
<a href="http://www.samurize.com">Samurize</a>,
|
||||
<a href="http://www.mulle-kybernetik.com/software/MkConsole/">MkConsole</a>,
|
||||
or
|
||||
<a href="http://projects.tynsoe.org/en/geektool/">GeekTool</a>
|
||||
can display this file on the computer desktop, so that it
|
||||
is readily visible.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To use a shadow file, edit your .taskrc configuration file,
|
||||
and add three entries as shown:
|
||||
</p>
|
||||
|
||||
<pre><code>shadow.file=/path/to/file
|
||||
shadow.command=list pri:H
|
||||
shadow.notify=on</code></pre>
|
||||
|
||||
<p>
|
||||
In this example the shadow file contains a report equivalent
|
||||
to running "task list pri:H". Note that the third entry
|
||||
causes a message to be displayed whenever task updates the
|
||||
shadow file. It is optional.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You can use any task command that generates a report, and of
|
||||
course, you can specify any file name, provided the directory
|
||||
it resides in already exists.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
130
html/shell.html
130
html/shell.html
|
@ -1,130 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Interacting with the Shell</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title"><a name="shell">Interacting with the Shell</a></h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
Certain characters are interpreted by the shell. For example, the
|
||||
"&". If you wish to include the & in a task description,
|
||||
you need to escape it, so the shell doesn't interpret it. For
|
||||
example:
|
||||
</p>
|
||||
|
||||
<pre><code>% task add Buy bread & milk</code></pre>
|
||||
|
||||
<p>
|
||||
This command is an error because of the &. The shell will
|
||||
consider this to be two commands:
|
||||
</p>
|
||||
|
||||
<pre><code>% task add Buy bread &
|
||||
% milk</code></pre>
|
||||
|
||||
<p>
|
||||
The shell treats the & character as an indicator that the
|
||||
command is complete and should be run in the background. Then the
|
||||
shell considers "milk" to be a command all by itself. Which it is
|
||||
not. One way to get around this is to individually escape the &
|
||||
character:
|
||||
</p>
|
||||
|
||||
<pre><code>% task add Buy bread \& milk</code></pre>
|
||||
|
||||
<p>
|
||||
Another is to quote the entire description, with either ' or "
|
||||
characters:
|
||||
</p>
|
||||
|
||||
<pre><code>% task add "Buy bread & milk"</code></pre>
|
||||
|
||||
<p>
|
||||
Task itself interprets the commands, and it too can make mistakes.
|
||||
For example, any colon : character will be interpreted by task as a
|
||||
delimiter between an attribute name and its value. Currently there
|
||||
is no workaround for this.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
355
html/simple.html
355
html/simple.html
|
@ -1,355 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Simple Usage</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title"><a name="simple">Simple Usage</a></h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
Let us begin by adding some tasks:
|
||||
</p>
|
||||
|
||||
<pre><code>% task add Book plane ticket
|
||||
% task add Rent a tux
|
||||
% task add Reserve a rental car
|
||||
% task add Reserve a hotel room</code></pre>
|
||||
|
||||
<p>
|
||||
That's it. You'll notice immediately that task has a very
|
||||
minimalist interface. Let us take a look at those tasks:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ls
|
||||
|
||||
ID Project Pri Description
|
||||
1 Book plane ticket
|
||||
2 Rent a tux
|
||||
3 Reserve a rental car
|
||||
4 Send John a birthday card</code></pre>
|
||||
|
||||
<p>
|
||||
The 'ls' command provides the most minimal list of tasks. Each
|
||||
task has been given an id number, and you can see that there are no
|
||||
projects or priorities assigned. Wait a minute - I own a tux, I
|
||||
don't need to rent one. Let us delete task 2:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 2 delete
|
||||
Permanently delete task? (y/n) y</code></pre>
|
||||
|
||||
<p>
|
||||
Task wants you to confirm deletions. To remove the confirmation,
|
||||
edit your .taskrc file and change the line:
|
||||
</p>
|
||||
|
||||
<pre><code>confirmation=yes</code></pre>
|
||||
|
||||
<p>
|
||||
to have a value of "no".
|
||||
</p>
|
||||
|
||||
<p>
|
||||
While the use of projects and priorities are not essential to
|
||||
benefitting from task, they can be very useful when the list of
|
||||
tasks grows large. Let's assign a project to these tasks:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 1 project:Wedding
|
||||
% task 3 project:Wedding
|
||||
% task 4 project:Family
|
||||
% task ls
|
||||
|
||||
ID Project Pri Description
|
||||
3 Family Send John a birthday card
|
||||
2 Wedding Reserve a rental car
|
||||
1 Wedding Book plane ticket</code></pre>
|
||||
|
||||
<p>
|
||||
Notice that the id numbers have changed. When tasks get deleted,
|
||||
or have their attributes changed (project, for example), the ids are
|
||||
prone to change. But the id numbers will remain valid until the
|
||||
next 'ls' command is run. You should only use the ids from the most
|
||||
recent 'ls' command. The ids change, because task is always trying
|
||||
to use small numbers so that it is easy for you to enter them
|
||||
correctly. Now that projects are assigned, we can look at just the
|
||||
Wedding project tasks:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Subprojects are supported. If you have a project "Wedding", you can
|
||||
specify that a task is a subproject "Transport" of "Wedding" by
|
||||
assigning the project "Wedding.Transport". Let's do this:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 2 project:Wedding.Transport
|
||||
% task ls
|
||||
|
||||
ID Project Pri Description
|
||||
3 Family Send John a birthday card
|
||||
2 Wedding.Transport Reserve a rental car
|
||||
1 Wedding Book plane ticket</code></pre>
|
||||
|
||||
<p>
|
||||
Task matches the leftmost part of the project when searching, so
|
||||
projects may be abbreviated:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ls project:Wedding.Tra
|
||||
|
||||
ID Project Pri Description
|
||||
2 Wedding.Transport Reserve a rental car</code></pre>
|
||||
|
||||
<p>
|
||||
This way of matching projects can be used to see all tasks under
|
||||
the "Wedding" project and all subprojects:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ls project:Wedding
|
||||
|
||||
ID Project Pri Description
|
||||
2 Wedding.Transport Reserve a rental car
|
||||
1 Wedding Book plane ticket</code></pre>
|
||||
|
||||
<p>
|
||||
Let's reassign 2 back to the "Wedding" project:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 2 project:Wedding</code></pre>
|
||||
|
||||
<p>
|
||||
Now that projects are assigned, we can look at just the
|
||||
Wedding project tasks:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ls project:Wedding
|
||||
|
||||
ID Project Pri Description
|
||||
1 Wedding Book plane ticket
|
||||
2 Wedding Reserve a rental car</code></pre>
|
||||
|
||||
<p>
|
||||
Any command arguments after the 'ls' are used for filtering the
|
||||
output. We could also have requested:
|
||||
</p>
|
||||
|
||||
<pre><code>% task ls ticket plane
|
||||
|
||||
ID Project Pri Description
|
||||
1 Wedding Book plane ticket</code></pre>
|
||||
|
||||
<p>
|
||||
Now let's prioritize. Priorities can be H, M or L (High, Medium,
|
||||
Low).
|
||||
</p>
|
||||
|
||||
<pre><code>% task ls
|
||||
|
||||
ID Project Pri Description
|
||||
3 Family Send John a birthday card
|
||||
2 Wedding Reserve a rental car
|
||||
1 Wedding Book plane ticket
|
||||
|
||||
% task 1 priority:H
|
||||
% task 2 prior:M
|
||||
% task 3 pr:H
|
||||
Ambiguous attribute 'pr' - could be either of project, priority
|
||||
% task 3 pri:H
|
||||
% task ls
|
||||
|
||||
ID Project Pri Description
|
||||
3 Family H Send John a birthday card
|
||||
1 Wedding H Book plane ticket
|
||||
2 Wedding M Reserve a rental car</code></pre>
|
||||
|
||||
<p>
|
||||
Notice that task supports the abbreviation of words such as
|
||||
priority, project. Priority can be abbreviated to pri, but not pr,
|
||||
because it is ambiguous. Now that tasks have been prioritized, you
|
||||
can see that the tasks are being sorted by priority, with the
|
||||
highest priority tasks at the top.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These attributes can all be provided when the task is added, instead
|
||||
of applying them afterwards, as shown. The following command shows
|
||||
how to set all the attributes at once:
|
||||
</p>
|
||||
|
||||
<pre><code>% task add project:Wedding priority:H Book plane ticket<code></pre>
|
||||
|
||||
<p>
|
||||
The 'ls' command provides the least information for each task. The
|
||||
'list' command provides more:
|
||||
</p>
|
||||
|
||||
<pre><code>% task list
|
||||
|
||||
ID Project Pri Due Active Age Description
|
||||
3 Family H 4 mins Send John a birthday card
|
||||
1 Wedding H 5 mins Book plane ticket
|
||||
2 Wedding M 5 mins Reserve a rental car</code></pre>
|
||||
|
||||
<p>
|
||||
Notice that a task can have a due date, and can be active. The
|
||||
task lists are sorted by due date, then priority. Let's add due
|
||||
dates:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 3 due:6/25/2008
|
||||
% task 1 due:7/31/2008
|
||||
% task list
|
||||
|
||||
ID Project Pri Due Active Age Description
|
||||
3 Family H 6/25/2008 6 mins Send John a birthday card
|
||||
1 Wedding H 7/31/2008 7 mins Book plane ticket
|
||||
2 Wedding M 7 mins Reserve a rental car</code></pre>
|
||||
|
||||
<p>
|
||||
If today's date is 6/23/2008, then task 3 is due in 2 days. It will
|
||||
be colored yellow if your terminal supports color. To change this
|
||||
color, edit your .taskrc file, and change the line to one of these
|
||||
alternatives:
|
||||
</p>
|
||||
|
||||
<pre><code>color.due=red
|
||||
color.due=on_blue
|
||||
color.due=red on_blue
|
||||
color.due=bold_red on_blue</code></pre>
|
||||
|
||||
<p>
|
||||
Where color is one of the following:
|
||||
</p>
|
||||
|
||||
<pre><code>black
|
||||
blue
|
||||
red
|
||||
green
|
||||
cyan
|
||||
magenta
|
||||
yellow
|
||||
white</code></pre>
|
||||
|
||||
<p>
|
||||
All colors are specified in this way. Take a look in .taskrc for
|
||||
all the other color rules that you control.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Tagging tasks is a good way to group them, aside from specifying a
|
||||
project. To add a tag to a task:
|
||||
</p>
|
||||
|
||||
<pre><code>% task <id> +tag<code></pre>
|
||||
|
||||
<p>
|
||||
The plus sign indicates that this is a tag. Any number of tags may
|
||||
be applied to a task, and then used for searching. Tags are just
|
||||
single words that are labels.
|
||||
</p>
|
||||
|
||||
<pre><code>% task list
|
||||
|
||||
ID Project Pri Due Active Age Description
|
||||
3 Family H 6/25/2008 8 mins Send John a birthday card
|
||||
1 Wedding H 7/31/2008 9 mins Book plane ticket
|
||||
2 Wedding M 9 mins Reserve a rental car
|
||||
|
||||
% task 1 +phone
|
||||
% task 2 +phone
|
||||
% task 3 +shopping
|
||||
% task 3 +john
|
||||
|
||||
% task list +phone
|
||||
|
||||
ID Project Pri Due Active Age Description
|
||||
1 Wedding H 7/31/2008 9 mins Book plane ticket
|
||||
2 Wedding M 9 mins Reserve a rental car</code></pre>
|
||||
|
||||
<p>
|
||||
To remove a tag from a task, use the minus sign:
|
||||
</p>
|
||||
|
||||
<pre><code>% task 3 -john</code></pre>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Tab Completion</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h2 class="title"><a name="simple">Tab Completion</a></h2>
|
||||
<div class="content">
|
||||
<p>
|
||||
There is a Bash tab completion script distributed with task,
|
||||
called task_completion.sh.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To install it, copy it to your
|
||||
|
||||
<code>/etc/bash_completion.d</code>
|
||||
|
||||
directory (in case you want to have it available system-wide)
|
||||
and then
|
||||
|
||||
<pre><code>source /etc/bash_completion</code></pre>
|
||||
|
||||
or source it from your home directory's bashrc files.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
126
html/task.css
126
html/task.css
|
@ -1,126 +0,0 @@
|
|||
body {
|
||||
text-align: center;
|
||||
margin: 0; padding: 1em;
|
||||
}
|
||||
|
||||
#container {
|
||||
width: 740px;
|
||||
text-align: left;
|
||||
margin: 0 auto; padding: 0;
|
||||
}
|
||||
|
||||
#header {
|
||||
height: 60px;
|
||||
margin: 0 0 15px; padding: 0;
|
||||
}
|
||||
|
||||
#page {}
|
||||
|
||||
#content {
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
#header a:link,
|
||||
#header a:visited {
|
||||
color:#000;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
font: bold 400% georgia, serif;
|
||||
letter-spacing: -1px;
|
||||
margin: 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#header h2 {
|
||||
font: normal 12px verdana, arial, sans-serif;
|
||||
margin: 2.5em 0 0 0.8em;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#content {}
|
||||
|
||||
#content h1,
|
||||
#content h2,
|
||||
#content h3,
|
||||
#content h4,
|
||||
#content h5 {
|
||||
font-family: "lucidamac bold", "lucida grande", arial, sans-serif;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
#content h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
#content h2 {
|
||||
font-size: 22px;
|
||||
border-bottom: 1px dotted #000;
|
||||
}
|
||||
|
||||
#content h3 {
|
||||
font-size: 20px;
|
||||
border-bottom: 1px dotted #bbb;
|
||||
}
|
||||
|
||||
#content h4 {
|
||||
font-size: 18px;
|
||||
border-bottom: 1px dotted #bbb;
|
||||
}
|
||||
|
||||
#content h5 {
|
||||
font-size: 18px;
|
||||
background: #ffd;
|
||||
border-bottom: 1px dotted #bbb;
|
||||
}
|
||||
|
||||
#content p {
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
#content ul,
|
||||
#content ol {
|
||||
}
|
||||
|
||||
#content code {
|
||||
font: normal 12px "bitstream vera sans mono", monaco "lucida console", "courier new", courier, serif;
|
||||
}
|
||||
|
||||
#content pre {
|
||||
color: #63FF00;
|
||||
background: #000;
|
||||
overflow: auto;
|
||||
font: normal 12px "bitstream vera sans mono", monaco "lucida console", "courier new", courier, serif;
|
||||
margin: 0.9em 0; padding: 8px;
|
||||
}
|
||||
|
||||
dt {
|
||||
font: bold 14px "lucida grande", verdana, arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
dd {
|
||||
}
|
||||
|
||||
body {
|
||||
font: normal 12px "lucida grande", verdana, arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.small {
|
||||
font: normal 10px verdana, arial, sans-serif;
|
||||
}
|
||||
|
||||
.table_h {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.table_d {
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
input,
|
||||
textarea { font: normal 12px "bitstream vera sans", verdana, sans-serif; }
|
||||
|
||||
abbr { border: none; }
|
||||
cite { font-style: normal; }
|
||||
a img { border: none; padding: 0; margin: 0; }
|
||||
|
277
html/task.html
277
html/task.html
|
@ -1,277 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Latest Release</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h1 class="title">Task</h1>
|
||||
<p>
|
||||
Task is an open source, command-line, TODO list manager.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Here you will find information on how to acquire, build, configure,
|
||||
use and become proficient with the task program.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="setup.html">Quick Setup</a>
|
||||
<li><a href="30second.html">30-second Tutorial</a>
|
||||
<li><a href="simple.html">Simple Usage</a>
|
||||
<li><a href="advanced.html">Advanced Usage</a>
|
||||
<li><a href="shell.html">Interacting with the Shell</a>
|
||||
<li><a href="config.html">Configuring Task</a>
|
||||
<li><a href="color.html">Color</a>
|
||||
<li><a href="recur.html">Recurring Tasks</a>
|
||||
<li><a href="date.html">Date Handling</a>
|
||||
<li><a href="versions.html">Old Versions</a>
|
||||
<li><a href="filter.html">Filters</a>
|
||||
<li><a href="shadow.html">Shadow Files</a>
|
||||
<li><a href="custom.html">Custom Reports</a>
|
||||
<li><a href="import.html">Data Import</a>
|
||||
<li><a href="faq.html">Frequently Asked Questions</a>
|
||||
<li><a href="sequence.html">ID Sequences</a>
|
||||
<li><a href="tab_completion.html">Tab Completion</a>
|
||||
<li><a href="git.html">How to use git and contribute to task</a>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
More documents are being written, and will be added here.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Alternatively, watch the
|
||||
<a href="http://www.youtube.com/watch?v=D2Kn4DMOVSw">task movie</a>
|
||||
which illustrates many of task's features.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For the latest news, discussion of proposed task features, and
|
||||
somewhere to voice your opinions, join us at
|
||||
<a href="http://groups.google.com/group/taskprogram">http://groups.google.com/group/taskprogram</a>.
|
||||
|
||||
<table border=0 style="background-color: #fff; padding: 5px;" cellspacing=0>
|
||||
<tr>
|
||||
<td>
|
||||
<img src="http://groups.google.com/groups/img/3nb/groups_bar.gif"
|
||||
height=26 width=132 alt="Google Groups">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-left: 5px">
|
||||
<b>Subscribe to taskprogram</b>
|
||||
</td>
|
||||
</tr>
|
||||
<form action="http://groups.google.com/group/taskprogram/boxsubscribe">
|
||||
<tr>
|
||||
<td style="padding-left: 5px;">
|
||||
Email:
|
||||
<input type=text name=email>
|
||||
<input type=submit name="sub" value="Subscribe">
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
<tr>
|
||||
<td align=right>
|
||||
<a href="http://groups.google.com/group/taskprogram">Visit this group</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<br />
|
||||
<h2 class="title">Get the Latest Stable Release</h2>
|
||||
|
||||
<div class="content">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Source:</td>
|
||||
<td><a href="http://www.beckingham.net/task-1.7.0.tar.gz">task-1.7.0.tar.gz</a></td>
|
||||
</tr>
|
||||
<!--
|
||||
<tr>
|
||||
<td>Mac OS X 10.5 (Leopard) Intel-only:</td>
|
||||
<td><a href="http://www.beckingham.net/task-1.7.0.pkg">task-1.7.0.pkg</a></td>
|
||||
</tr>
|
||||
-->
|
||||
<tr>
|
||||
<td>
|
||||
Ubuntu 9.04:
|
||||
(Thanks to <a href="http://www.ultrafredde.com">Federico Hernandez</a>):
|
||||
</td>
|
||||
<td><a href="http://www.beckingham.net/task_1.7.0-0ubuntu1_i386.deb">task_1.7.0-0ubuntu1_i386.deb</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Red Hat:
|
||||
(Thanks to <a href="http://www.ultrafredde.com">Federico Hernandez</a>):
|
||||
</td>
|
||||
<td><a href="http://www.beckingham.net/task-1.7.0-2.fc10.i386.rpm">task-1.7.0-2.fc10.i386.rpm</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Git - get the whole source and history:</td>
|
||||
<td><a href="http://github.com/pbeckingham/task">http://github.com/pbeckingham/task</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h4>New in version 1.7.0 (5/14/2009)</h4>
|
||||
<ul>
|
||||
<li>Improved the errors when parsing a corrupt or unrecognized pending.data
|
||||
or completed.data file (thanks to T. Charles Yun).
|
||||
<li>Added details to the "info" report about recurring tasks (thanks to T.
|
||||
Charles Yun).
|
||||
<li>Now writes a sample "defaultwidth" configuration variable to the default
|
||||
.taskrc file (thanks to T. Charles Yun).
|
||||
<li>Task allows commands that require an ID to now be given a sequence, which
|
||||
is a set of IDs. This allows commands like "task delete 1 2 5-10,12".
|
||||
<li>Fixed bug in the ghistory report, which caused it to only show a new
|
||||
month if a task was added during that month.
|
||||
<li>New command "duplicate" which allows an existing task to be duplicated,
|
||||
and also have modifications applied (thanks to David J Patrick).
|
||||
<li>The "append", and "done" commands now allow modifications to be applied
|
||||
to the task(s) (thanks to David J Patrick).
|
||||
<li>Improved word wrapping in various output.
|
||||
<li>Fixed bug that added an extra line between header and graph in the
|
||||
ghistory report.
|
||||
<li>Added simple 'taskprogram' mailing list subscribe form to the web site.
|
||||
<li>For custom reports that define a "limit" to the number of rows of output
|
||||
such as "oldest" and "newest", task allows an override value. For
|
||||
example "task oldest 5" will display the 5 oldest tasks.
|
||||
<li>Modified the "stats" report so that it has the same aesthetics as the
|
||||
other reports.
|
||||
<li>New "timesheet" command displays tasks completed and started, per week,
|
||||
and can display multiple weeks.
|
||||
<li>New tab completion script, task_completion.sh, for bash users, is installed
|
||||
to /usr/local/share/task (thanks to Federico Hernandez).
|
||||
<li>Applied patch to allow task to build on Arch Linux (thanks to Johan Friis).
|
||||
<li>Applied patch to fix a UUID bug on Solaris 8 (thanks to Steven de Brouwer).
|
||||
<li>The task man page is now installed. Try "man task" (thanks to Federico
|
||||
Hernandez and P.C. Shyamshankar).
|
||||
<li>Fixed bug that causes task to create a default .task directory, even if
|
||||
data.location specified otherwise (thanks to Federico Hernandez).
|
||||
<li>New "edit" command that fires up a text editor (uses 'editor' configuration
|
||||
variable, $VISUAL or $EDITOR environment variable) and allows direct
|
||||
editing of all editable task details.
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
(Find out <a href="versions.html">what was new in prior versions</a>)
|
||||
</p>
|
||||
|
||||
<h2>Troubleshooting</h2>
|
||||
<p>
|
||||
Task has been built from source and tested in the following environments:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>OS X 10.4 Tiger
|
||||
<li>OS X 10.5 Leopard
|
||||
<li>Fedora Core 8
|
||||
<li>Fedora Core 9
|
||||
<li>Fedora Core 10
|
||||
<li>Ubuntu 7 Feisty Fawn
|
||||
<li>Ubuntu 8 Hardy Heron
|
||||
<li>Ubuntu 8.10 Intrepid Ibex
|
||||
<li>Ubuntu 9.04 Jaunty Jackalope
|
||||
<li>Arch Linux
|
||||
<li>Slackware 12-12.2
|
||||
<li>Solaris 8
|
||||
<li>Solaris 10
|
||||
<li>Cygwin 1.5.25-14
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you have difficulties building task, have found a bug, have a
|
||||
suggestion for improvement, or a feature request, please send mail to
|
||||
<a href="mailto:task@beckingham.net">task@beckingham.net</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Take a look at the <a href="faq.html">FAQ</a>
|
||||
for tips and workarounds to problems.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,486 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Task Prior Versions</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div id="toolbar">
|
||||
<a href="task.html">Home</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="30second.html">30-second Tutorial</a>
|
||||
<a href="simple.html">Simple</a>
|
||||
<a href="advanced.html">Advanced</a>
|
||||
<a href="shell.html">Shell</a>
|
||||
<a href="config.html">Configuration</a>
|
||||
<a href="color.html">Colors</a>
|
||||
<a href="recur.html">Recurrence</a>
|
||||
<a href="date.html">Date Handling</a>
|
||||
<a href="faq.html">FAQ</a>
|
||||
<a href="versions.html">Old Versions</a>
|
||||
<a href="links.html">Task on the Web</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<h1 class="title">Task Prior Versions</h1>
|
||||
<br />
|
||||
|
||||
<div class="content">
|
||||
<h4>New in version 1.6.1 (4/24/2009)</h4>
|
||||
<p>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Source:</td>
|
||||
<td><a href="http://www.beckingham.net/task-1.6.1.tar.gz">task-1.6.1.tar.gz</a></td>
|
||||
</tr>
|
||||
<!--
|
||||
<tr>
|
||||
<td>Mac OS X 10.5 (Leopard) Intel-only:</td>
|
||||
<td><a href="http://www.beckingham.net/task-1.6.1.pkg">task-1.6.1.pkg</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Debian:
|
||||
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>):
|
||||
</td>
|
||||
<td><a href="http://www.beckingham.net/task_1.6.1-1_i386.deb">task_1.6.1-1_i386.deb</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Red Hat:
|
||||
(Thanks to <a href="http://www.ultrafredde.com">Federico Hernandez</a>):
|
||||
</td>
|
||||
<td><a href="http://www.beckingham.net/task-1.6.1-1.FC10.i386.rpm">task-1.6.1-1.FC10.i386.rpm</a></td>
|
||||
</tr>
|
||||
-->
|
||||
<tr>
|
||||
<td>Git - get the whole source and history:</td>
|
||||
<td><a href="http://github.com/pbeckingham/task">http://github.com/pbeckingham/task</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<ul>
|
||||
<li>Fixed bug that caused new, first-time .taskrc files to be written without
|
||||
including the custom report labels (thanks to P.C. Shyamshankar).
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h4>New in version 1.6.0 (4/13/2009)</h4>
|
||||
<p>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Source:</td>
|
||||
<td><a href="http://www.beckingham.net/task-1.6.0.tar.gz">task-1.6.0.tar.gz</a></td>
|
||||
</tr>
|
||||
<!--
|
||||
<tr>
|
||||
<td>Mac OS X 10.5 (Leopard) Intel-only:</td>
|
||||
<td><a href="http://www.beckingham.net/task-1.6.0.pkg">task-1.6.0.pkg</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Debian:
|
||||
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>):
|
||||
</td>
|
||||
<td><a href="http://www.beckingham.net/task_1.6.0-1_i386.deb">task_1.6.0-1_i386.deb</a></td>
|
||||
</tr>
|
||||
-->
|
||||
<tr>
|
||||
<td>
|
||||
Red Hat:
|
||||
(Thanks to <a href="http://www.ultrafredde.com">Federico Hernandez</a>):
|
||||
</td>
|
||||
<td><a href="http://www.beckingham.net/task-1.6.0-1.FC10.i386.rpm">task-1.6.0-1.FC10.i386.rpm</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Git - get the whole source and history:</td>
|
||||
<td><a href="http://github.com/pbeckingham/task">http://github.com/pbeckingham/task</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<ul>
|
||||
<li>Added support for new "append" command that adds more description text to
|
||||
an existing task.
|
||||
<li>Added support for the "weekdays" recurrence, which means a task can recur
|
||||
five times a week, and not on weekends (thanks to Chris Pride).
|
||||
<li>UTF8 text is now supported in task project names, tags and descriptions.
|
||||
<li>Fixed bug that caused the y/n confirmation on task deletion to ignore the
|
||||
Enter key and fail to re-prompt (thanks to Bruce Dillahunty).
|
||||
<li>When the "echo.command" configuration variable is set to "yes", it causes
|
||||
commands that modify tasks to display which task was affected (thanks to
|
||||
Bruce Dillahunty).
|
||||
<li>A task can now be annotated with the command "task <id> annotate ...", and
|
||||
a timestamped annotation will appear in reports.
|
||||
<li>A 'description_only' column is now available for use in custom reports,
|
||||
and it excludes annotations.
|
||||
<li>A task can now be upgraded to a recurring task by adding a recurrence
|
||||
frequency, a due date, and an optional until date.
|
||||
<li>When a recurring task is modified, all other instances of the recurring
|
||||
task are also modified.
|
||||
<li>Custom reports now support user-specified column labels (thanks to T.
|
||||
Charles Yun).
|
||||
<li>Task can now import tasks from a variety of data formats, including task
|
||||
export files from versions 1.4.3 and earlier, versions 1.5.0 and later,
|
||||
todo.sh 2.x, CSV, plain text and task command line. See online docs for
|
||||
full details.
|
||||
<li>Export was including 'id' in the column header even though it was not
|
||||
included in the data.
|
||||
<li>The task file format has changed slightly. Please back up your task
|
||||
data files before upgrading to 1.6.0.
|
||||
<li>Added new column 'recurrence_indicator' that displays an 'R' if the task
|
||||
is a recurring task. This column can be added to any custom report.
|
||||
<li>Added new column 'tag_indicator' that displays a '+' if the task
|
||||
has any tags. This column can be added to any custom report.
|
||||
<li>Fixed bug where sometimes a task description was concatenated oddly if
|
||||
there was a colon somewhere in the description.
|
||||
<li>Fixed bug that caused recurring annual tasks to exhibit a creeping due
|
||||
date, because of an assumption of 365 days per year, which failed to
|
||||
consider leap years (thanks to T. Charles Yun).
|
||||
<li>Annotations can now be modified with the substitution commands /from/to/.
|
||||
<li>Substitutions can now be made global with /from/to/g and all occurrences
|
||||
of "from" will be replaced with "to".
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<h4>New in version 1.5.0 (3/15/2009)</h4>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Source:</td>
|
||||
<td><a href="http://www.beckingham.net/task-1.5.0.tar.gz">task-1.5.0.tar.gz</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mac OS X 10.5 (Leopard) Intel-only:</td>
|
||||
<td><a href="http://www.beckingham.net/task-1.5.0.pkg">task-1.5.0.pkg</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Debian:
|
||||
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>):
|
||||
</td>
|
||||
<td><a href="http://www.beckingham.net/task_1.5.0-1_i386.deb">task_1.5.0-1_i386.deb</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Red Hat:
|
||||
(Thanks to <a href="http://www.ultrafredde.com">Federico Hernandez</a>):
|
||||
</td>
|
||||
<td><a href="http://www.beckingham.net/task-1.5.0-1.i386.rpm">task-1.5.0-1.i386.rpm</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<ul>
|
||||
<li>Removed deprecated TUTORIAL file.
|
||||
<li>Removed support for the "showage" configuration variable.
|
||||
<li>"task stop" can remove the start time from a started task.
|
||||
<li>"task ghistory" now displays a differently aligned graph, allowing
|
||||
easier comparison by month of tasks added versus completed and deleted.
|
||||
<li>"task version" command now reports unrecognized configuration variables,
|
||||
which may be spelling mistakes or deprecated variables.
|
||||
<li>"configure --enable-debug" now supported to suppress compiler optimization
|
||||
to allow debugging.
|
||||
<li>Allow lower case priorities, and automatically upper case them.
|
||||
<li>Added support for "due" configuration variable which defines the number
|
||||
of days in the future when a task is considered due.
|
||||
<li>Added support for custom reports, comprised of a set of column names and
|
||||
sort order, with optional filtering in the configuration file. This
|
||||
means user-defined reports can be written, and the reports currently
|
||||
in the configuration file can be renamed. Several of task's built in
|
||||
reports have been converted to user-defined reports.
|
||||
<li>New online documentation for custom reports.
|
||||
<li>New algorithm for determining when the "nag" message is displayed.
|
||||
<li>Fixed bug where task hangs with a certain combination of recurring tasks
|
||||
and shadow files.
|
||||
<li>Fixed bug with the task sort algorithm, which led to an unstable sequence
|
||||
when there were only a handful of tasks.
|
||||
<li>Performance enhanced by eliminating unnecessary sorting.
|
||||
<li>Task now has a large (and growing) test suite and bug regression tests
|
||||
to help ensure higher quality releases.
|
||||
<li>Fixed bug that caused large performance hit during table rendering.
|
||||
<li>Fixed bug that concatenated a modified description without spaces.
|
||||
<li>Added new column 'recur' that displays the recurrence period of any
|
||||
recurring tasks. This column can be added to any custom report.
|
||||
<li>Added support for "color.recurring" configuration variable which
|
||||
specifies the color of recurring tasks.
|
||||
<li>Added support for "locking" configuration variable that controls whether
|
||||
file locking is used.
|
||||
<li>Task export feature now includes recurrence information, removes nested
|
||||
quotes, and limits output to pending tasks.
|
||||
<li>Task no longer includes deleted tasks in the summary report (thanks to
|
||||
Benjamin Tegarden).
|
||||
<li>Fixed bug that prevented the summary report from properly reporting
|
||||
recently completed tasks.
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<h4>New in version 1.4.3 (11/1/2008)</h4>
|
||||
<a href="http://www.beckingham.net/task-1.4.3.tar.gz">task-1.4.3.tar.gz</a>
|
||||
<br />
|
||||
Mac OS X 10.5 (Leopard) Intel-only:
|
||||
<a href="http://www.beckingham.net/task-1.4.3.pkg">task-1.4.3.pkg</a>
|
||||
<br />
|
||||
Debian package: <a href="http://www.beckingham.net/task_1.4.3-1_i386.deb">task_1.4.3-1_i386.deb</a>
|
||||
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Fixed misleading task count at bottom of "info" report.
|
||||
<li>Added support for a shadow file that contains a plain text task report,
|
||||
with the "shadow.file" and "shadow.command" configuration variables.
|
||||
The shadow file is automatically updated whenever the task database
|
||||
changes. Useful for integrating with "Samurize".
|
||||
<li>Task now displays a message whenever a shadow file is updated, if the
|
||||
"shadow.notify" configuration variable is set "on".
|
||||
<li>Fixed bug whereby adding a task with a \n, \r or \f did not fail properly.
|
||||
<li>Removed "task usage" command.
|
||||
<li>Added documentation for Shadow files.
|
||||
<li>Added documentation for task filters.
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<h4>New in version 1.4.2 (9/18/2008)</h4>
|
||||
<a href="http://www.beckingham.net/task-1.4.2.tar.gz">task-1.4.2.tar.gz</a>
|
||||
<br />
|
||||
Mac OS X 10.5 (Leopard) Intel-only:
|
||||
<a href="http://www.beckingham.net/task-1.4.2.pkg">task-1.4.2.pkg</a>
|
||||
<br />
|
||||
Debian package: <a href="http://www.beckingham.net/task_1.4.2-1_i386.deb">task_1.4.2-1_i386.deb</a>
|
||||
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>)
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>"task undo" can now retract a "task done" command, provided no
|
||||
reports have been run.
|
||||
<li>Task now correctly sorts on entire strings, instead of just the
|
||||
first character (thanks to Andy Lester).
|
||||
<li>Task now uses dashes (-----) to underline column headings when
|
||||
color is disabled (thanks to Vincent Fleuranceau).
|
||||
<li>Task now allows mixed case attribute names (pri:, PRI:, Pri: ...)
|
||||
and commands (add, ADD, Add ...) (thanks to Vincent Fleuranceau).
|
||||
<li>Task now supports a default project and priority for new tasks, via
|
||||
the new "default.project" and "default.priority" configuration variables
|
||||
(thanks to Vincent Fleuranceau).
|
||||
<li>Task supports improved word-wrapping to the terminal width.
|
||||
<li>Task now supports "default.command" configuration variable (for example
|
||||
it could contain "list due:tomorrow") which is the command that is run
|
||||
whenever task is invoked with no arguments.
|
||||
<li>Task supports modifying the existing description of a task, with the
|
||||
following syntax: task <id> "new description ...".
|
||||
<li>Fixed bug so that relative dates in filters (task list due:eom,
|
||||
task list due:tomorrow, task list due:23rd ...) are now properly
|
||||
supported.
|
||||
<li>Fixed bug so that source now properly includes <string.h> in
|
||||
order to build clean using gcc 4.3 (thanks to H. İbrahim Güngör)
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<h4>New in version 1.4.1 (7/18/2008)</h4>
|
||||
<a href="http://www.beckingham.net/task-1.4.1.tar.gz">task-1.4.1.tar.gz</a>
|
||||
<br />
|
||||
Mac OS X 10.5 (Leopard) Intel-only:
|
||||
<a href="http://www.beckingham.net/task-1.4.1.pkg">task-1.4.1.pkg</a>
|
||||
<br />
|
||||
Debian package: <a href="http://www.beckingham.net/task_1.4.1-1_i386.deb">task_1.4.1-1_i386.deb</a>
|
||||
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>)
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Fixed bug: Descriptions could not be altered with "task 123 New description"
|
||||
<li>Tweak: For "task calendar" month names are now centered over the month
|
||||
<li>Removed TUTORIAL file contents in favor of online version
|
||||
<li>New Mac Intel-only Leopard (10.5) binary package
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<h4>New in version 1.4.0 (7/10/2008)</h4>
|
||||
Source: <a href="http://www.beckingham.net/task-1.4.0.tar.gz">task-1.4.0.tar.gz</a>
|
||||
<br />
|
||||
Debian package: <a href="http://www.beckingham.net/task_1.4.0-1_i386.deb">task_1.4.0-1_i386.deb</a>
|
||||
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>)
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Added new <a href="recur.html">recurring tasks</a> feature
|
||||
<li>Added "task undelete" feature to restore a (very) recently deleted
|
||||
task
|
||||
<li>Added averages to the "task history" report
|
||||
<li>Added bar chart history report "task ghistory"
|
||||
<li>Added support for rc:<file> to allow override of the default
|
||||
~/.taskrc file
|
||||
<li>Added support for relative due: dates, such as "tomorrow", "friday",
|
||||
"23rd", "eom"
|
||||
<li>Added support for task filtering on all reports
|
||||
<li>Automatically shuts off color, ncurses when output is not to a tty
|
||||
<li>Added support for the ~ character in .taskrc data.location, for flexibility
|
||||
<li>Allows colons on the description, provided what is to the left of the colon
|
||||
is not a standard attribute name
|
||||
<li>Fixed bug where Esc[0m sequences were being emitted for no good reason
|
||||
<li>Fixed bug where table headers are underlined when color is turned off
|
||||
<li>Fixed bug where adding a blank priority resulted in an assigned garbage value
|
||||
<li>Fixed bug parsing date "07/08/2008" when using dateformat "m/d/Y"
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<h4>New in version 1.3.1</h4>
|
||||
Source: <a href="http://www.beckingham.net/task-1.3.1.tar.gz">task-1.3.1.tar.gz</a>
|
||||
<br />
|
||||
Debian package: <a href="http://www.beckingham.net/task_1.3.1-1_i386.deb">task_1.3.1-1_i386.deb</a>
|
||||
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>)
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>New configuration variable "defaultwidth" determines the width
|
||||
of windows in the absense of ncurses support
|
||||
<li>Fixed bug where "showage" configuration variable was not being
|
||||
oberved by the "task long" report
|
||||
<li>Fixed bug causing segmentation faults (mostly for Ubuntu users)
|
||||
when various commands are run
|
||||
<li>Fixed bug so that task now will recreate a missing ~/.taskrc file,
|
||||
OR a missing ~/.task directory
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<h4>New in version 1.3.0</h4>
|
||||
Source: <a href="http://www.beckingham.net/task-1.3.0.tar.gz">task-1.3.0.tar.gz</a>
|
||||
<br />
|
||||
Debian package: <a href="http://www.beckingham.net/task_1.3.0-0_i386.deb">task_1.3.0-0_i386.deb</a>
|
||||
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>)
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>"task calendar" now displays multiple months per line, adjustable
|
||||
by the "monthsperline" configuration variable. Feature added by
|
||||
Damian Glenny
|
||||
<li>Displays shorter message when a command is entered incorrectly,
|
||||
and the full usage for "task help"
|
||||
<li>"task export" can now filter tasks like the reports
|
||||
<li>"task oldest" shows the oldest tasks
|
||||
<li>"task newest" shows the newest tasks
|
||||
<li>Fixed bug where task generates a segmentation fault for several
|
||||
commands, when no "dateformat" configuration variable was present
|
||||
<li>Fixed bug whereby if you have more than one task with a due date,
|
||||
7 days gets added to the entry date of task 2..n
|
||||
<li>Fixed bug whereby "1 wks" was being improperly pluralized
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<h4>New in version 1.2.0</h4>
|
||||
Source: <a href="http://www.beckingham.net/task-1.2.0.tar.gz">task-1.2.0.tar.gz</a>
|
||||
<br />
|
||||
Debian package: <a href="http://www.beckingham.net/task_1.2.0-1_i386.deb">task_1.2.0-1_i386.deb</a>
|
||||
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>)
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Subprojects supported - please see documentation below, or TUTORIAL
|
||||
file
|
||||
<li>"dateformat" configuration variable now properly used to parse as
|
||||
well as render dates
|
||||
<li>"task list x" now performs a caseless comparison between "x" and
|
||||
the task description
|
||||
<li>"showage" configuration variable determines whether the "Age" column
|
||||
should appear on the "task list" and "task next" reports
|
||||
<li>Improvements to the TUTORIAL file and this page
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<h4>New in version 1.1.0</h4>
|
||||
Source: <a href="http://www.beckingham.net/task-1.1.0.tar.gz">task-1.1.0.tar.gz</a>
|
||||
<br />
|
||||
Debian package: <a href="http://www.beckingham.net/task_1.1.0-1_i386.deb">task_1.1.0-1_i386.deb</a>
|
||||
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>)
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>"blanklines" configuration variable to stop displaying unnecessary
|
||||
white space and thus work better on small-screen devices
|
||||
<li>"dateformat" configuration now determines how dates are formatted
|
||||
<li>Better formatting of "task tags" output
|
||||
<li>This home page set up, with TUTORIAL
|
||||
<li>Added tags to the "task long" report
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<h4>New in version 1.0.1</h4>
|
||||
Source: <a href="http://www.beckingham.net/task-1.0.1.tar.gz">task-1.0.1.tar.gz</a>
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Fixed bug where the UUID generator not properly terminating strings
|
||||
<li>Fixed bug where srandom/srand not called prior to custom UUID generation
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<h4>Version 1.0.0</h4>
|
||||
Source: <a href="http://www.beckingham.net/task-1.0.0.tar.gz">task-1.0.0.tar.gz</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Task 1.0.0 was the first publicly available version of task.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<div class="content">
|
||||
<p>
|
||||
Copyright 2006-2009, P. Beckingham. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="right" valign="top" width="200px">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9709799404235424";
|
||||
/* Task Main */
|
||||
google_ad_slot = "8660617875";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||
pageTracker._initData();
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
157
i18n/strings.de-DE
Normal file
157
i18n/strings.de-DE
Normal file
|
@ -0,0 +1,157 @@
|
|||
# This is an example strings.en-US file.
|
||||
#
|
||||
# The task program has a built-in set of default strings, which are UTF8 encoded
|
||||
# for the en-US locale. A file such as this is used to override those defaults.
|
||||
# This means that a strings file is merely a delta applied to the built-in
|
||||
# strings, so an empty string file means you get en-US.
|
||||
#
|
||||
# To use another string file, add the following entry to your .taskrc file:
|
||||
#
|
||||
# locale=sv-SE # Swedish string set
|
||||
|
||||
# 1xx task shell
|
||||
100 Unbekannter Fehler #Unknown Error.
|
||||
101 Konnte nicht Datenverzeichnis HOME aus passwd Datei lesen #Could not read home directory from the passwd file.
|
||||
102 (j/n) #(y/n)
|
||||
103 Ungültige ID in Sequenz #Invalid ID in sequence
|
||||
104 Ungültige ID in Bereich #Invalid ID in range
|
||||
105 Invertierter Sequenzbereich hoch-niedrig #Inverted sequence range high-low
|
||||
106 ID Bereich zu gross #ID Range too large
|
||||
107 Keine Sequenz #Not a sequence.
|
||||
108 Task interaktiv nur möglich mit vorhandenem ncurses #Interactive task is only available when built with ncurses support.
|
||||
109 Leerer Eintrag in der Eingabe #Empty record in input
|
||||
110 Unbekanntes Zeichen am Zeilenende #Unrecognized characters at end of line
|
||||
111 Datensatz nicht als Format 4 erkannt #Record not recognized as format 4
|
||||
112 Kann leere Zeichenkette nicht ersetzen #Cannot substitute an empty string
|
||||
113 Nicht erkanntes Zeichen am Ende der Ersetzung #Unrecognized character(s) at end of substitution
|
||||
114 Fehlformulierte Ersetzung #Malformed substitution
|
||||
115 Etiketten dürfen keine Kommas enthalten #Tags are not permitted to contain commas
|
||||
|
||||
# 2xx Commands - must be sequential
|
||||
200 aktiv #active
|
||||
201 hinzufen #add
|
||||
202 beizufügen #append
|
||||
203 anmerkung #annotate
|
||||
204 kalender #calendar
|
||||
205 farben #colors
|
||||
206 fertiggestellt #completed
|
||||
207 löschen #delete
|
||||
208 erledigt #done
|
||||
209 duplizieren #duplicate
|
||||
210 editieren #edit
|
||||
211 export #export
|
||||
212 hilfe #help
|
||||
213 geschichte #history
|
||||
214 ggeschichte #ghistory
|
||||
215 import #import
|
||||
216 info #info
|
||||
|
||||
218 überfällig #overdue
|
||||
219 projekte #projects
|
||||
220 start #start
|
||||
221 statistik #stats
|
||||
222 stop #stop
|
||||
223 zusammenfassung #summary
|
||||
224 etikett #tags
|
||||
225 zeitdatenblatt#timesheet
|
||||
|
||||
227 rücksetzen #undo
|
||||
228 version #version
|
||||
|
||||
# 3xx Attributes - must be sequential
|
||||
300 projekt #project
|
||||
301 priorität #priority
|
||||
302 vordergrund #fg
|
||||
303 hintergrund #bg
|
||||
304 fällig #due
|
||||
305 eintrag #entry
|
||||
306 start #start
|
||||
307 stop #end
|
||||
308 wiederkehrend #recur
|
||||
309 bis #until
|
||||
310 mask #mask
|
||||
311 imask #imask
|
||||
|
||||
# 35x Attribute modifiers - must be sequential
|
||||
350 davor #before
|
||||
351 danach #after
|
||||
352 nict #not
|
||||
353 kein #none
|
||||
354 beliebig #any
|
||||
355 synth #synth
|
||||
356 unter #under
|
||||
357 über #over
|
||||
358 erstes #first
|
||||
359 letztes #last
|
||||
360 dieses #this
|
||||
361 nächste #next
|
||||
362 ist #is
|
||||
363 istnicht #isnt
|
||||
364 hat #has
|
||||
365 hatnicht #hasnt
|
||||
366 beginntmit #startswith
|
||||
367 endetmit #endswith
|
||||
|
||||
# 4xx Columns
|
||||
|
||||
# 5xx Colors
|
||||
500 fett #bold
|
||||
501 unterstrichen #underline
|
||||
502 fett_unterstrichen #bold_underline
|
||||
503 schwarz #black
|
||||
504 rot #red
|
||||
505 grün #green
|
||||
506 gelb #yellow
|
||||
507 blau #blue
|
||||
508 magenta #magenta
|
||||
509 cyan #cyan
|
||||
510 weiss #white
|
||||
511 fett_schwarz #bold_black
|
||||
512 fett_rot #bold_red
|
||||
513 fett_grün #bold_green
|
||||
514 fett_gelb #bold_yellow
|
||||
515 fett_blau #bold_blue
|
||||
516 fett_magenta #bold_magenta
|
||||
517 fett_cyan #bold_cyan
|
||||
518 fett_weiss #bold_white
|
||||
519 unterstrichen_schwarz #underline_black
|
||||
520 unterstrichen_rot #underline_red
|
||||
521 unterstrichen_grün #underline_green
|
||||
522 unterstrichen_gelb #underline_yellow
|
||||
523 unterstrichen_blau #underline_blue
|
||||
524 unterstrichen_magenta #underline_magenta
|
||||
525 unterstrichen_cyan #underline_cyan
|
||||
526 unterstrichen_weiss #underline_white
|
||||
527 fett_unterstrichen_schwarz #bold_underline_black
|
||||
528 fett_unterstrichen_rot #bold_underline_red
|
||||
529 fett_unterstrichen_grün #bold_underline_green
|
||||
530 fett_unterstrichen_gelb #bold_underline_yellow
|
||||
531 fett_unterstrichen_blau #bold_underline_blue
|
||||
532 fett_unterstrichen_magenta #bold_underline_magenta
|
||||
533 fett_unterstrichen_cyan #bold_underline_cyan
|
||||
534 fett_unterstrichen_weiss #bold_underline_white
|
||||
535 auf_schwarz #on_black
|
||||
536 auf_rot #on_red
|
||||
537 auf_grün #on_green
|
||||
538 auf_gelb #on_yellow
|
||||
539 auf_blau #on_blue
|
||||
540 auf_magenta #on_magenta
|
||||
541 auf_cyan #on_cyan
|
||||
542 auf_weiss #on_white
|
||||
543 auf_signal_schwarz #on_bright_black
|
||||
544 auf_signal_rot #on_bright_red
|
||||
545 auf_signal_grün #on_bright_green
|
||||
546 auf_signal_gelb #on_bright_yellow
|
||||
547 auf_signal_blau #on_bright_blue
|
||||
548 auf_signal_magenta #on_bright_magenta
|
||||
549 auf_signal_cyan #on_bright_cyan
|
||||
550 auf_signal_weiss #on_bright_white
|
||||
551 aus #off
|
||||
552 Unbekannte Farbe #Unknown color name
|
||||
|
||||
# 6xx Config
|
||||
|
||||
# 7xx TDB
|
||||
|
||||
# 8xx Reports
|
||||
|
159
i18n/strings.en-US
Normal file
159
i18n/strings.en-US
Normal file
|
@ -0,0 +1,159 @@
|
|||
# This is an example strings.en-US file.
|
||||
#
|
||||
# The task program has a built-in set of default strings, which are UTF8 encoded
|
||||
# for the en-US locale. A file such as this is used to override those defaults.
|
||||
# This means that a strings file is merely a delta applied to the built-in
|
||||
# strings, so an empty string file means you get en-US.
|
||||
#
|
||||
# To use another string file, add the following entry to your .taskrc file:
|
||||
#
|
||||
# locale=sv-SE # Swedish string set
|
||||
|
||||
# 1xx task shell
|
||||
100 Unknown Error.
|
||||
101 Could not read home directory from the passwd file.
|
||||
102 (y/n)
|
||||
103 Invalid ID in sequence
|
||||
104 Invalid ID in range
|
||||
105 Inverted sequence range high-low
|
||||
106 ID Range too large
|
||||
107 Not a sequence.
|
||||
108 Interactive task is only available when built with ncurses support.
|
||||
109 Empty record in input
|
||||
110 Unrecognized characters at end of line
|
||||
111 Record not recognized as format 4
|
||||
112 Cannot substitute an empty string
|
||||
113 Unrecognized character(s) at end of substitution
|
||||
114 Malformed substitution
|
||||
115 Tags are not permitted to contain commas
|
||||
116 You must specify a command, or a task ID to modify
|
||||
|
||||
# 2xx Commands - must be sequential
|
||||
200 active
|
||||
201 add
|
||||
202 append
|
||||
203 annotate
|
||||
204 calendar
|
||||
205 colors
|
||||
206 completed
|
||||
207 delete
|
||||
208 done
|
||||
209 duplicate
|
||||
210 edit
|
||||
211 export
|
||||
212 help
|
||||
213 history
|
||||
214 ghistory
|
||||
215 import
|
||||
216 info
|
||||
|
||||
218 overdue
|
||||
219 projects
|
||||
220 start
|
||||
221 stats
|
||||
222 stop
|
||||
223 summary
|
||||
224 tags
|
||||
225 timesheet
|
||||
|
||||
227 undo
|
||||
228 version
|
||||
229 shell
|
||||
|
||||
# 3xx Attributes - must be sequential
|
||||
300 project
|
||||
301 priority
|
||||
302 fg
|
||||
303 bg
|
||||
304 due
|
||||
305 entry
|
||||
306 start
|
||||
307 end
|
||||
308 recur
|
||||
309 until
|
||||
310 mask
|
||||
311 imask
|
||||
|
||||
# 35x Attribute modifiers - must be sequential
|
||||
350 before
|
||||
351 after
|
||||
352 not
|
||||
353 none
|
||||
354 any
|
||||
355 synth
|
||||
356 under
|
||||
357 over
|
||||
358 first
|
||||
359 last
|
||||
360 this
|
||||
361 next
|
||||
362 is
|
||||
363 isnt
|
||||
364 has
|
||||
365 hasnt
|
||||
366 startswith
|
||||
367 endswith
|
||||
|
||||
# 4xx Columns
|
||||
|
||||
# 5xx Colors
|
||||
500 bold
|
||||
501 underline
|
||||
502 bold_underline
|
||||
503 black
|
||||
504 red
|
||||
505 green
|
||||
506 yellow
|
||||
507 blue
|
||||
508 magenta
|
||||
509 cyan
|
||||
510 white
|
||||
511 bold_black
|
||||
512 bold_red
|
||||
513 bold_green
|
||||
514 bold_yellow
|
||||
515 bold_blue
|
||||
516 bold_magenta
|
||||
517 bold_cyan
|
||||
518 bold_white
|
||||
519 underline_black
|
||||
520 underline_red
|
||||
521 underline_green
|
||||
522 underline_yellow
|
||||
523 underline_blue
|
||||
524 underline_magenta
|
||||
525 underline_cyan
|
||||
526 underline_white
|
||||
527 bold_underline_black
|
||||
528 bold_underline_red
|
||||
529 bold_underline_green
|
||||
530 bold_underline_yellow
|
||||
531 bold_underline_blue
|
||||
532 bold_underline_magenta
|
||||
533 bold_underline_cyan
|
||||
534 bold_underline_white
|
||||
535 on_black
|
||||
536 on_red
|
||||
537 on_green
|
||||
538 on_yellow
|
||||
539 on_blue
|
||||
540 on_magenta
|
||||
541 on_cyan
|
||||
542 on_white
|
||||
543 on_bright_black
|
||||
544 on_bright_red
|
||||
545 on_bright_green
|
||||
546 on_bright_yellow
|
||||
547 on_bright_blue
|
||||
548 on_bright_magenta
|
||||
549 on_bright_cyan
|
||||
550 on_bright_white
|
||||
551 off
|
||||
552 Unknown color name
|
||||
|
||||
# 6xx Config
|
||||
|
||||
# 7xx TDB
|
||||
|
||||
# 8xx Reports
|
||||
|
11
i18n/strings.es-ES
Normal file
11
i18n/strings.es-ES
Normal file
|
@ -0,0 +1,11 @@
|
|||
# 1xx task shell
|
||||
100 Error desconocido.
|
||||
|
||||
# 2xx Commands
|
||||
# 3xx Attributes
|
||||
# 4xx Columns
|
||||
# 5xx Colors
|
||||
# 6xx Config
|
||||
# 7xx TDB
|
||||
# 8xx Reports
|
||||
|
11
i18n/strings.fr-FR
Normal file
11
i18n/strings.fr-FR
Normal file
|
@ -0,0 +1,11 @@
|
|||
# 1xx task shell
|
||||
100 Erreur inconnue.
|
||||
|
||||
# 2xx Commands
|
||||
# 3xx Attributes
|
||||
# 4xx Columns
|
||||
# 5xx Colors
|
||||
# 6xx Config
|
||||
# 7xx TDB
|
||||
# 8xx Reports
|
||||
|
11
i18n/strings.nl-NL
Normal file
11
i18n/strings.nl-NL
Normal file
|
@ -0,0 +1,11 @@
|
|||
# 1xx task shell
|
||||
100 Onbekende fout.
|
||||
|
||||
# 2xx Commands
|
||||
# 3xx Attributes
|
||||
# 4xx Columns
|
||||
# 5xx Colors
|
||||
# 6xx Config
|
||||
# 7xx TDB
|
||||
# 8xx Reports
|
||||
|
157
i18n/strings.sv-SE
Normal file
157
i18n/strings.sv-SE
Normal file
|
@ -0,0 +1,157 @@
|
|||
# This is an example strings.en-US file.
|
||||
#
|
||||
# The task program has a built-in set of default strings, which are UTF8 encoded
|
||||
# for the en-US locale. A file such as this is used to override those defaults.
|
||||
# This means that a strings file is merely a delta applied to the built-in
|
||||
# strings, so an empty string file means you get en-US.
|
||||
#
|
||||
# To use another string file, add the following entry to your .taskrc file:
|
||||
#
|
||||
# locale=sv-SE # Swedish string set
|
||||
|
||||
# 1xx task shell
|
||||
100 Okänt fel. #Unknown Error.
|
||||
101 Kunde inte läsa hemkatalogen från passwd filen. #Could not read home directory from the passwd file.
|
||||
102 (j/n) #(y/n)
|
||||
103 Ogiltig ID i sekvens #Invalid ID in sequence
|
||||
104 Ogiltig ID i spännvidd #Invalid ID in range
|
||||
105 Inverterad sekvens spännvidd hög-låg #Inverted sequence range high-low
|
||||
106 ID spännvidd för stor #ID Range too large
|
||||
107 Ingen sekvens. #Not a sequence.
|
||||
108 Interaktiv task är bara tillgänglig när den kompilerades med support för ncurses. #Interactive task is only available when built with ncurses support.
|
||||
109 Tom post i ingångsdata #Empty record in input
|
||||
110 Okänt tecknen på slutet av raden. #Unrecognized characters at end of line
|
||||
111 Post inte indentifierad som format 4 #Record not recognized as format 4
|
||||
112 Substitution av tom teckensträng är inte möjligt #Cannot substitute an empty string
|
||||
113 Pkänt tecken vid slutet av substitution #Unrecognized character(s) at end of substitution
|
||||
114 Ogiltig substitution #Malformed substitution
|
||||
115 Taggar får inte innehåller komman #Tags are not permitted to contain commas
|
||||
|
||||
# 2xx Commands - must be sequential
|
||||
200 aktivt #active
|
||||
201 tillägg #add
|
||||
202 bifoga #append
|
||||
203 kommentera #annotate
|
||||
204 kalender #calendar
|
||||
205 färger #colors
|
||||
206 avslutad #completed
|
||||
207 stryk #delete
|
||||
208 färdig #done
|
||||
209 kopiera #duplicate
|
||||
210 redigera #edit
|
||||
211 exportera #export
|
||||
212 hjälp #help
|
||||
213 historia #history
|
||||
214 ghistoria #ghistory
|
||||
215 importera #import
|
||||
216 info #info
|
||||
|
||||
218 försenad #overdue
|
||||
219 projekten #projects
|
||||
220 start #start
|
||||
221 statistik #stats
|
||||
222 stop #stop
|
||||
223 sammanfattning #summary
|
||||
224 taggar #tags
|
||||
225 tidsrapport #timesheet
|
||||
|
||||
227 ångra #undo
|
||||
228 version #version
|
||||
|
||||
# 3xx Attributes - must be sequential
|
||||
300 projekt #project
|
||||
301 prioritet #priority
|
||||
302 förgrund #fg
|
||||
303 bakgrund #bg
|
||||
304 väntad #due
|
||||
305 post #entry
|
||||
306 start #start
|
||||
307 slut #end
|
||||
308 periodirskt #recur
|
||||
309 innan #until
|
||||
310 mask #mask
|
||||
311 imask #imask
|
||||
|
||||
# 35x Attribute modifiers - must be sequential
|
||||
350 före #before
|
||||
351 efter #after
|
||||
352 inte #not
|
||||
353 ingen #none
|
||||
354 några #any
|
||||
355 synth #synth
|
||||
356 under #under
|
||||
357 över #over
|
||||
358 första #first
|
||||
359 sista #last
|
||||
360 detta #this
|
||||
361 nästa #next
|
||||
362 är #is
|
||||
363 ärinte #isnt
|
||||
364 har #has
|
||||
365 harinte #hasnt
|
||||
366 börjarmed #startswith
|
||||
367 slutarmed #endswith
|
||||
|
||||
# 4xx Columns
|
||||
|
||||
# 5xx Colors
|
||||
500 fet #bold
|
||||
501 understrykt #underline
|
||||
502 fet_understrykt #bold_underline
|
||||
503 svart #black
|
||||
504 röd #red
|
||||
505 grön #green
|
||||
506 gul #yellow
|
||||
507 blå #blue
|
||||
508 magenta #magenta
|
||||
509 cyan #cyan
|
||||
510 vit #white
|
||||
511 fet_svart #bold_black
|
||||
512 fet_röd #bold_red
|
||||
513 fet_grön #bold_green
|
||||
514 fet_gul #bold_yellow
|
||||
515 fet_blå #bold_blue
|
||||
516 fet_magenta #bold_magenta
|
||||
517 fet_cyan #bold_cyan
|
||||
518 fet_vit #bold_white
|
||||
519 understrykt_svart #underline_black
|
||||
520 understrykt_röd #underline_red
|
||||
521 understrykt_grön #underline_green
|
||||
522 understrykt_gul #underline_yellow
|
||||
523 understrykt_blå #underline_blue
|
||||
524 understrykt_magenta #underline_magenta
|
||||
525 understrykt_cyan #underline_cyan
|
||||
526 understrykt_vit #underline_white
|
||||
527 fet_understrykt_svart #bold_underline_black
|
||||
528 fet_understrykt_röd #bold_underline_red
|
||||
529 fet_understrykt_grön #bold_underline_green
|
||||
530 fet_understrykt_gul #bold_underline_yellow
|
||||
531 fet_understrykt_blå #bold_underline_blue
|
||||
532 fet_understrykt_magenta #bold_underline_magenta
|
||||
533 fet_understrykt_cyan #bold_underline_cyan
|
||||
534 fet_understrykt_vit #bold_underline_white
|
||||
535 på_svart #on_black
|
||||
536 på_röd #on_red
|
||||
537 på_grön #on_green
|
||||
538 på_gul #on_yellow
|
||||
539 på_blå #on_blue
|
||||
540 på_magenta #on_magenta
|
||||
541 på_cyan #on_cyan
|
||||
542 på_vit #on_white
|
||||
543 på_ljust_svart #on_bright_black
|
||||
544 på_ljust_röd #on_bright_red
|
||||
545 på_ljust_grön #on_bright_green
|
||||
546 på_ljust_gul #on_bright_yellow
|
||||
547 på_ljust_blå #on_bright_blue
|
||||
548 på_ljust_magenta #on_bright_magenta
|
||||
549 på_ljust_cyan #on_bright_cyan
|
||||
550 på_ljust_vit #on_bright_white
|
||||
551 av #off
|
||||
552 Okänt färg namn #Unknown color name
|
||||
|
||||
# 6xx Config
|
||||
|
||||
# 7xx TDB
|
||||
|
||||
# 8xx Reports
|
||||
|
5
i18n/tips.de-DE
Normal file
5
i18n/tips.de-DE
Normal file
|
@ -0,0 +1,5 @@
|
|||
%
|
||||
erster Tipp
|
||||
%
|
||||
zweiter Tipp
|
||||
%
|
5
i18n/tips.en-US
Normal file
5
i18n/tips.en-US
Normal file
|
@ -0,0 +1,5 @@
|
|||
%
|
||||
first tip
|
||||
%
|
||||
second tip
|
||||
%
|
5
i18n/tips.sv-SE
Normal file
5
i18n/tips.sv-SE
Normal file
|
@ -0,0 +1,5 @@
|
|||
%
|
||||
första tips
|
||||
%
|
||||
andra tips
|
||||
%
|
32
package-config/README
Normal file
32
package-config/README
Normal file
|
@ -0,0 +1,32 @@
|
|||
The package-config directory contains the configuration files
|
||||
for building release packages for the different operating
|
||||
systems:
|
||||
|
||||
* osx: binary packages for Mac OSX
|
||||
* fedora: rpm packages for Fedora (Linux)
|
||||
* ubuntu: deb packages for Ubuntu and (Linux)
|
||||
* cygwin_ bz2 packages for cygwin (windows)
|
||||
|
||||
Please visit the corresponding operating systems homepage
|
||||
for instructions on how to build a binary package of task
|
||||
out of the released source tarball with these configuration
|
||||
files.
|
||||
|
||||
For Fedora rpm packages you find instructions at
|
||||
http://fedoraproject.org/wiki/PackageMaintainers/CreatingPackageHowTo
|
||||
|
||||
For Ubuntu deb packages you find instructions at
|
||||
https://wiki.ubuntu.com/PackagingGuide/Complete
|
||||
|
||||
For Cygwin bz2 packages you find instructions at
|
||||
http://cygwin.com/setup.html
|
||||
|
||||
You might also ask in the forums on taskwarrior.org if you
|
||||
have further questions.
|
||||
|
||||
This file and the corresponding package build configuration files
|
||||
are released under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Please see the file COPYING in the main directory.
|
10
package-config/cygwin/CYGWIN-PATCHES/setup.hint
Normal file
10
package-config/cygwin/CYGWIN-PATCHES/setup.hint
Normal file
|
@ -0,0 +1,10 @@
|
|||
# setup.hint for task 1.7.1-1
|
||||
category: Utils
|
||||
requires: libncurses9 cygwin
|
||||
sdesc: A command-line to do list manager
|
||||
ldesc: "Task is a command-line to do list manager.
|
||||
It has support for GTD functionality and includes
|
||||
the following features: tags, colorful tabular output,
|
||||
reports and graphs, lots of manipulation commands,
|
||||
low-level API, abbreviations for all commands and
|
||||
options, multiuser file locking, recurring tasks."
|
45
package-config/cygwin/CYGWIN-PATCHES/task-1.7.1-1.README
Normal file
45
package-config/cygwin/CYGWIN-PATCHES/task-1.7.1-1.README
Normal file
|
@ -0,0 +1,45 @@
|
|||
task 1.7.1-1
|
||||
------------------------------------------
|
||||
|
||||
A command-line to do list manager that can be used
|
||||
with the gtd system.
|
||||
|
||||
Runtime requirements:
|
||||
cygwin-1.5.25 or newer
|
||||
libncurses
|
||||
|
||||
Build requirements:
|
||||
cygwin-1.5.25 or newer
|
||||
gcc-3.4.4-1 or newer
|
||||
libncurses-devel
|
||||
|
||||
Canonical homepage:
|
||||
http://taskwarrior.org
|
||||
|
||||
Canonical download:
|
||||
http://taskwarrior.org/download
|
||||
|
||||
License:
|
||||
GPLv2+
|
||||
|
||||
Language:
|
||||
C++
|
||||
|
||||
------------------------------------
|
||||
|
||||
Build instructions:
|
||||
unpack task-1.7.1-1-src.tar.bz2
|
||||
if you use setup to install this src package,
|
||||
it will be unpacked under /usr/src automatically
|
||||
cd /usr/src/task-1.7.1-1
|
||||
./configure --prefix=/usr
|
||||
make
|
||||
make install
|
||||
|
||||
------------------------------------
|
||||
|
||||
task was packaged for cygwin by
|
||||
Federico Hernandez <ultrafredde@gmail.com> and
|
||||
is licensed under the GPL
|
||||
|
||||
---- task-1.7.1-1 -- 2009-06-17 ----
|
63
package-config/cygwin/task-1.7.1-1.patch
Normal file
63
package-config/cygwin/task-1.7.1-1.patch
Normal file
|
@ -0,0 +1,63 @@
|
|||
diff -Nrup task-1.7.1-1/CYGWIN-PATCHES/setup.hint task-1.7.1-1.cygwin/CYGWIN-PATCHES/setup.hint
|
||||
--- task-1.7.1-1/CYGWIN-PATCHES/setup.hint 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ task-1.7.1-1.cygwin/CYGWIN-PATCHES/setup.hint 2009-06-17 15:47:56.304750000 +0200
|
||||
@@ -0,0 +1,10 @@
|
||||
+# setup.hint for task 1.7.1-1
|
||||
+category: Utils
|
||||
+requires: libncurses9 cygwin
|
||||
+sdesc: A command-line to do list manager
|
||||
+ldesc: "Task is a command-line to do list manager.
|
||||
+It has support for GTD functionality and includes
|
||||
+the following features: tags, colorful tabular output,
|
||||
+reports and graphs, lots of manipulation commands,
|
||||
+low-level API, abbreviations for all commands and
|
||||
+options, multiuser file locking, recurring tasks."
|
||||
diff -Nrup task-1.7.1-1/CYGWIN-PATCHES/task-1.7.1-1.README task-1.7.1-1.cygwin/CYGWIN-PATCHES/task-1.7.1-1.README
|
||||
--- task-1.7.1-1/CYGWIN-PATCHES/task-1.7.1-1.README 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ task-1.7.1-1.cygwin/CYGWIN-PATCHES/task-1.7.1-1.README 2009-06-17 15:47:44.320375000 +0200
|
||||
@@ -0,0 +1,45 @@
|
||||
+task 1.7.1-1
|
||||
+------------------------------------------
|
||||
+
|
||||
+A command-line to do list manager that can be used
|
||||
+with the gtd system.
|
||||
+
|
||||
+Runtime requirements:
|
||||
+ cygwin-1.5.25 or newer
|
||||
+ libncurses
|
||||
+
|
||||
+Build requirements:
|
||||
+ cygwin-1.5.25 or newer
|
||||
+ gcc-3.4.4-1 or newer
|
||||
+ libncurses-devel
|
||||
+
|
||||
+Canonical homepage:
|
||||
+ http://taskwarrior.org
|
||||
+
|
||||
+Canonical download:
|
||||
+ http://taskwarrior.org/download
|
||||
+
|
||||
+License:
|
||||
+ GPLv2+
|
||||
+
|
||||
+Language:
|
||||
+ C++
|
||||
+
|
||||
+------------------------------------
|
||||
+
|
||||
+Build instructions:
|
||||
+ unpack task-1.7.1-1-src.tar.bz2
|
||||
+ if you use setup to install this src package,
|
||||
+ it will be unpacked under /usr/src automatically
|
||||
+ cd /usr/src/task-1.7.1-1
|
||||
+ ./configure --prefix=/usr
|
||||
+ make
|
||||
+ make install
|
||||
+
|
||||
+------------------------------------
|
||||
+
|
||||
+task was packaged for cygwin by
|
||||
+Federico Hernandez <ultrafredde@gmail.com> and
|
||||
+is licensed under the GPL
|
||||
+
|
||||
+---- task-1.7.1-1 -- 2009-06-17 ----
|
|
@ -0,0 +1,45 @@
|
|||
task 1.7.1-1
|
||||
------------------------------------------
|
||||
|
||||
A command-line to do list manager that can be used
|
||||
with the gtd system.
|
||||
|
||||
Runtime requirements:
|
||||
cygwin-1.5.25 or newer
|
||||
libncurses
|
||||
|
||||
Build requirements:
|
||||
cygwin-1.5.25 or newer
|
||||
gcc-3.4.4-1 or newer
|
||||
libncurses-devel
|
||||
|
||||
Canonical homepage:
|
||||
http://taskwarrior.org
|
||||
|
||||
Canonical download:
|
||||
http://taskwarrior.org/download
|
||||
|
||||
License:
|
||||
GPLv2+
|
||||
|
||||
Language:
|
||||
C++
|
||||
|
||||
------------------------------------
|
||||
|
||||
Build instructions:
|
||||
unpack task-1.7.1-1-src.tar.bz2
|
||||
if you use setup to install this src package,
|
||||
it will be unpacked under /usr/src automatically
|
||||
cd /usr/src/task-1.7.1-1
|
||||
./configure --prefix=/usr
|
||||
make
|
||||
make install
|
||||
|
||||
------------------------------------
|
||||
|
||||
task was packaged for cygwin by
|
||||
Federico Hernandez <ultrafredde@gmail.com> and
|
||||
is licensed under the GPL
|
||||
|
||||
---- task-1.7.1-1 -- 2009-06-17 ----
|
64
package-config/fedora/task.spec
Normal file
64
package-config/fedora/task.spec
Normal file
|
@ -0,0 +1,64 @@
|
|||
Name: task
|
||||
Version: 1.8.0
|
||||
Release: 0%{?dist}
|
||||
Summary: A command-line to do list manager
|
||||
|
||||
Group: Applications/Productivity
|
||||
License: GPLv2+
|
||||
URL: http://taskwarrior.org
|
||||
Source0: http://taskwarrior.org/download/%{name}-%{version}.tar.gz
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
|
||||
BuildRequires: ncurses-devel
|
||||
|
||||
%description
|
||||
Task is a command-line to do list manager. It has
|
||||
support for GTD functionality and includes the
|
||||
following features: tags, colorful tabular output,
|
||||
reports and graphs, lots of manipulation commands,
|
||||
low-level API, abbreviations for all commands and
|
||||
options, multiuser file locking, recurring tasks.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
|
||||
%build
|
||||
%configure
|
||||
make %{?_smp_mflags}
|
||||
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/bash_completion.d
|
||||
install -m 644 -T scripts/bash/task_completion.sh $RPM_BUILD_ROOT%{_sysconfdir}/bash_completion.d/task
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%doc AUTHORS ChangeLog COPYING NEWS README scripts
|
||||
%{_bindir}/task
|
||||
%{_mandir}/man1/task.1.gz
|
||||
%{_mandir}/man5/taskrc.5.gz
|
||||
%{_mandir}/man5/task-tutorial.5.gz
|
||||
%{_sysconfdir}/bash_completion.d
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Jun 15 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.8.0-0
|
||||
Intial RPM for task release 1.8.0
|
||||
Installs now bash_completion file
|
||||
* Tue Jun 08 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.7.1-2
|
||||
- Fixed inclusion of manpages.
|
||||
* Tue Jun 08 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.7.1-1
|
||||
- Initial RPM for bugfix release 1.7.1.
|
||||
- Updated references to new project homepage in spec file.
|
||||
* Tue May 19 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.7.0-2
|
||||
- Changed license to GPLv2+ and removed Requires macro.
|
||||
- See https://bugzilla.redhat.com/show_bug.cgi?id=501498
|
||||
* Tue May 19 2009 Federico Hernandez <ultrafredde@gmail.com> - 1.7.0-1
|
||||
- Initial RPM.
|
24
package-config/osx/binary/README.txt
Normal file
24
package-config/osx/binary/README.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
Thank you for taking a look at task!
|
||||
|
||||
Task is a GTD, todo list, task management, command line utility with a multitude
|
||||
of features. It is a portable, well supported, very active project, and it is
|
||||
Open Source. Task has binary distributions, online documentation, demonstration
|
||||
movies, and you'll find all the details at the site:
|
||||
|
||||
http://taskwarrior.org
|
||||
|
||||
At the site you'll find a wiki, discussion forums, downloads, news and more.
|
||||
|
||||
|
||||
Your contributions are especially welcome. Whether it comes in the form of
|
||||
code patches, ideas, discussion, bug reports or just encouragement, your input
|
||||
is needed.
|
||||
|
||||
Please send your support questions and code patches to:
|
||||
|
||||
support@taskwarrior.org
|
||||
|
||||
Consider joining taskwarrior.org and participating in the future of task.
|
||||
|
||||
---
|
1
package-config/osx/task.pmdoc/01task-contents.xml
Normal file
1
package-config/osx/task.pmdoc/01task-contents.xml
Normal file
|
@ -0,0 +1 @@
|
|||
<pkg-contents spec="1.12"><f n="task" o="paul" g="staff" p="33261" pt="/Users/paul/task.git/package-config/osx/binary/task" m="false" t="file"/></pkg-contents>
|
1
package-config/osx/task.pmdoc/01task.xml
Normal file
1
package-config/osx/task.pmdoc/01task.xml
Normal file
|
@ -0,0 +1 @@
|
|||
<pkgref spec="1.12" uuid="C71026FD-E252-42CD-89C3-2F6F087AAF17"><config><identifier>com.beckingham.task180.task.pkg</identifier><version>1.8.0</version><description></description><post-install type="none"/><requireAuthorization/><installFrom mod="true">/Users/paul/task.git/package-config/osx/binary/task</installFrom><installTo mod="true" relocatable="true">/usr/local/bin</installTo><flags><followSymbolicLinks/></flags><packageStore type="internal"></packageStore><mod>parent</mod><mod>locationType</mod><mod>relocatable</mod><mod>version</mod><mod>installTo.path</mod><mod>installTo</mod></config><contents><file-list>01task-contents.xml</file-list><filter>/CVS$</filter><filter>/\.svn$</filter><filter>/\.cvsignore$</filter><filter>/\.cvspass$</filter><filter>/\.DS_Store$</filter></contents></pkgref>
|
1
package-config/osx/task.pmdoc/index.xml
Normal file
1
package-config/osx/task.pmdoc/index.xml
Normal file
|
@ -0,0 +1 @@
|
|||
<pkmkdoc spec="1.12"><properties><title>Task 1.8.0</title><build>/Users/paul/Desktop/task-1.8.0.pkg</build><organization>com.beckingham</organization><userSees ui="easy"/><min-target os="3"/><domain anywhere="true" system="true"/></properties><distribution><versions min-spec="1.000000"/><scripts></scripts></distribution><contents><choice title="task" id="choice0" starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="com.beckingham.task180.task.pkg"/><choice-reqs><requirement id="tosv" operator="ge" value="'10.5.0'" selected="no" enabled="no" hidden="unchanged" startSelected="unchanged" startEnabled="unchanged" startHidden="unchanged"/></choice-reqs></choice></contents><resources bg-scale="proportional" bg-align="center"><locale lang="en"><resource mod="true" type="license">/Users/paul/task.git/package-config/osx/binary/COPYING.txt</resource><resource mod="true" type="readme">/Users/paul/task.git/package-config/osx/binary/README.txt</resource></locale></resources><flags/><item type="file">01task.xml</item><mod>properties.title</mod><mod>properties.anywhereDomain</mod><mod>properties.systemDomain</mod></pkmkdoc>
|
22
package-config/ubuntu/debian/changelog
Normal file
22
package-config/ubuntu/debian/changelog
Normal file
|
@ -0,0 +1,22 @@
|
|||
task (1.8.0-0ubuntu1) jaunty; urgency=low
|
||||
|
||||
* Initial deb package for task release 1.8.0
|
||||
|
||||
-- Federico Hernandez <ultrafredde@gmail.com> Thu, 11 Jun 2009 23:02:28 +0200
|
||||
|
||||
task (1.7.1-0ubuntu1) jaunty; urgency=low
|
||||
|
||||
* Initial deb package for bugfix release 1.7.1
|
||||
* Updated references to new project homepage in control file.
|
||||
* dpatch not longer neededas upstream version contains fix
|
||||
for taskrc.5 bug
|
||||
|
||||
-- Federico Hernandez <ultrafredde@gmail.com> Tue, 09 Jun 2009 11:49:51 +0200
|
||||
|
||||
task (1.7.0-0ubuntu1) jaunty; urgency=low
|
||||
|
||||
* Initial release (LP: #378847)
|
||||
* Fixed bug in taskrc.5 man page from upstream project
|
||||
which made lintian complain
|
||||
|
||||
-- Federico Hernandez <ultrafredde@gmail.com> Wed, 27 May 2009 23:57:08 +0200
|
1
package-config/ubuntu/debian/compat
Normal file
1
package-config/ubuntu/debian/compat
Normal file
|
@ -0,0 +1 @@
|
|||
7
|
19
package-config/ubuntu/debian/control
Normal file
19
package-config/ubuntu/debian/control
Normal file
|
@ -0,0 +1,19 @@
|
|||
Source: task
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: Federico Hernandez <ultrafredde@gmail.com>
|
||||
XSBC-Original-Maintainer: Federico Hernandez <ultrafredde@gmail.com>
|
||||
Build-Depends: debhelper (>= 7), autotools-dev, libncurses5-dev
|
||||
Standards-Version: 3.8.0.1
|
||||
Homepage: http://taskwarrior.org
|
||||
|
||||
Package: task
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}
|
||||
Description: A command-line to do list manager
|
||||
Task is a command-line to do list manager. It has
|
||||
support for GTD functionality and includes the
|
||||
following features: tags, colorful tabular output,
|
||||
reports and graphs, lots of manipulation commands,
|
||||
low-level API, abbreviations for all commands and
|
||||
options, multiuser file locking, recurring tasks.
|
56
package-config/ubuntu/debian/copyright
Normal file
56
package-config/ubuntu/debian/copyright
Normal file
|
@ -0,0 +1,56 @@
|
|||
This package was debianized by:
|
||||
|
||||
Federico Hernandez <ultrafredde@gmail.com> on Thu, 11 Jun 2009 23:02:28 +0200
|
||||
|
||||
It was downloaded from:
|
||||
|
||||
http://taskwarrior.org
|
||||
|
||||
Upstream Authors:
|
||||
|
||||
Paul Beckingham <paul@beckingham.net>
|
||||
Damian Glenny
|
||||
Andy Lester
|
||||
H. İbrahim Güngör
|
||||
Stefan Dorn
|
||||
Michael Greb
|
||||
Benjamin Tegarden
|
||||
Chris Pride
|
||||
Richard Querin
|
||||
Federico Hernandez
|
||||
T. Charles Yun
|
||||
David J Patrick
|
||||
P.C. Shyamshankar
|
||||
Johan Friis
|
||||
Steven de Brouwer
|
||||
|
||||
Copyright:
|
||||
|
||||
Copyright 2006 - 2009, Paul Beckingham
|
||||
Copyright 2009 Federico Hernandez
|
||||
Copyright 2009 P.C. Shyamshankar
|
||||
|
||||
License:
|
||||
|
||||
This package is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this package; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License can be found in `/usr/share/common-licenses/GPL-2'.
|
||||
|
||||
The Debian packaging is:
|
||||
|
||||
Copyright (C) 2009, Federico Hernandez <ultrafredde@gmail.com>
|
||||
|
||||
and is licensed under the GPL, see above.
|
3
package-config/ubuntu/debian/docs
Normal file
3
package-config/ubuntu/debian/docs
Normal file
|
@ -0,0 +1,3 @@
|
|||
AUTHORS
|
||||
NEWS
|
||||
README
|
46
package-config/ubuntu/debian/rules
Executable file
46
package-config/ubuntu/debian/rules
Executable file
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
config.status: configure
|
||||
dh_testdir
|
||||
./configure $(CROSS) --prefix=/usr --docdir=$(DATADIR)/doc/task
|
||||
|
||||
build: build-stamp
|
||||
|
||||
build-stamp: config.status
|
||||
dh_testdir
|
||||
$(MAKE)
|
||||
touch $@
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
[ ! -f Makefile ] || $(MAKE) distclean
|
||||
dh_clean
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_prep
|
||||
$(MAKE) DESTDIR=$(CURDIR)/debian/task install
|
||||
|
||||
binary-indep: install
|
||||
|
||||
binary-arch: install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_installchangelogs
|
||||
dh_installdocs
|
||||
dh_installman
|
||||
install -D -m644 task_completion.sh $(CURDIR)/debian/task/etc/bash_completion.d/task
|
||||
rm -rf $(CURDIR)/debian/task/usr/share/doc/task-1.7.1
|
||||
dh_strip
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
dh_installdeb
|
||||
dh_shlibdeps
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install
|
3
package-config/ubuntu/debian/watch
Normal file
3
package-config/ubuntu/debian/watch
Normal file
|
@ -0,0 +1,3 @@
|
|||
version=3
|
||||
|
||||
http://taskwarrior.org/download/task-(.*)\.tar\.gz
|
|
@ -27,6 +27,7 @@
|
|||
# The routines will do completion of:
|
||||
#
|
||||
# *) task subcommands
|
||||
# *) project names
|
||||
# *) tag names
|
||||
#
|
||||
# To use these routines:
|
||||
|
@ -47,6 +48,18 @@
|
|||
# http://taskwarrior.org
|
||||
#
|
||||
|
||||
_task_get_projects() {
|
||||
task _projects
|
||||
}
|
||||
|
||||
_task_get_tags() {
|
||||
task _tags
|
||||
}
|
||||
|
||||
_task_get_config() {
|
||||
task _config
|
||||
}
|
||||
|
||||
_task()
|
||||
{
|
||||
local cur prev opts base
|
||||
|
@ -55,15 +68,29 @@ _task()
|
|||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
|
||||
opts="active add annotate append calendar color completed delete done duplicate edit export ghistory help history import info list long ls newest next oldest overdue projects start stats stop summary tags timesheet undelete undo version"
|
||||
opts="$(task _commands) $(task _ids)"
|
||||
|
||||
case "${prev}" in
|
||||
ls|list|long)
|
||||
if [[ ${cur} == +* ]] ; then
|
||||
local tags=$( task tags | egrep -v 'tags|^$'|sed 's/^/+/' )
|
||||
case "${cur}" in
|
||||
pro*:*)
|
||||
local projects=$(_task_get_projects)
|
||||
local partial_project="${cur/*:/}"
|
||||
COMPREPLY=( $(compgen -W "${projects}" -- ${partial_project}) )
|
||||
return 0
|
||||
;;
|
||||
+*)
|
||||
local tags=$(_task_get_tags | sed 's/^/+/')
|
||||
COMPREPLY=( $(compgen -W "${tags}" -- ${cur}) )
|
||||
return 0
|
||||
fi
|
||||
;;
|
||||
-*)
|
||||
local tags=$(_task_get_tags | sed 's/^/-/')
|
||||
COMPREPLY=( $(compgen -W "${tags}" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
rc.*)
|
||||
local config=$(_task_get_config | sed 's/^/rc\./')
|
||||
COMPREPLY=( $(compgen -W "${config}" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
57
scripts/vim/README
Normal file
57
scripts/vim/README
Normal file
|
@ -0,0 +1,57 @@
|
|||
|
||||
Configure VIM for Syntax Highlighting of Task Data
|
||||
|
||||
|
||||
The task data files (pending.data, completed.data and undo.data) as well as
|
||||
edits made via commands like "task 1 edit" can be color-highlighted if you
|
||||
happen to use VIM as your preferred text editor. Eventually this will happen
|
||||
automatically in newer versions of VIM, but for now you have to do a little
|
||||
bit of file shuffling.
|
||||
|
||||
|
||||
Prerequisites
|
||||
|
||||
For this to work, you need to first have syntax highlighting enabled when you
|
||||
use VIM. This happens to be the default for most VIM installations, but it is
|
||||
usually quite simple if that doesn't happen to be so in your case. Rather than
|
||||
repeat the excellent VIM documentation here, please see the appropriate VIM
|
||||
documentation itself. Generally this can be made seen by starting vim/gvim and
|
||||
issuing the following command:
|
||||
|
||||
:help syntax
|
||||
|
||||
You may prefer instead to read the help online at:
|
||||
http://vimdoc.sourceforge.net/htmldoc/syntax.html#syntax
|
||||
|
||||
|
||||
Configuring VIM to Understand Task Data
|
||||
|
||||
Once you have VIM's syntax highlighting enabled and working with other file
|
||||
types properly, configuring it for use with task is simple. You simply need to
|
||||
copy some files that came with task into your home directory so that you have:
|
||||
|
||||
~/.vim/ftdetect/task.vim
|
||||
~/.vim/syntax/taskdata.vim
|
||||
~/.vim/syntax/taskedit.vim
|
||||
|
||||
The source of these files varies depending on how you installed task. If you
|
||||
installed task via a regular package (rpm or deb) you can find these files in
|
||||
/usr/share/doc/task-VERSION/scripts/vim/. If you built task yourself from the
|
||||
tarball (using the default configure options), these will be in
|
||||
/usr/local/share/doc/task-VERSION/scripts/vim/ instead. So you should be able
|
||||
to do one of the following:
|
||||
|
||||
cp -av /usr/share/doc/task-VERSION/scripts/vim/* ~/.vim/
|
||||
|
||||
or
|
||||
|
||||
cp -av /usr/local/share/doc/task-VERSION/scripts/vim/* ~/.vim/
|
||||
|
||||
You should then be ready to go.
|
||||
---
|
||||
All three above mentioned files are
|
||||
|
||||
Copyright 2009 John Florian
|
||||
|
||||
and are available under the GNU Public License version 2 or later.
|
||||
For the full text of this license, see COPYING.
|
18
scripts/vim/ftdetect/task.vim
Normal file
18
scripts/vim/ftdetect/task.vim
Normal file
|
@ -0,0 +1,18 @@
|
|||
" Vim support file to detect task data files and single task edits
|
||||
"
|
||||
" Maintainer: John Florian <jflorian@doubledog.org>
|
||||
" Updated: Wed Jul 8 19:45:55 EDT 2009
|
||||
"
|
||||
" Copyright 2009 John Florian
|
||||
"
|
||||
" This file is available under the GNU Public License version 2 or later.
|
||||
" For the full text of this license, see COPYING.
|
||||
|
||||
|
||||
" for the raw data files
|
||||
au BufRead,BufNewFile {pending,completed,undo}.data set filetype=taskdata
|
||||
|
||||
" for 'task 42 edit'
|
||||
au BufRead,BufNewFile *.task set filetype=taskedit
|
||||
|
||||
" vim:noexpandtab
|
48
scripts/vim/syntax/taskdata.vim
Normal file
48
scripts/vim/syntax/taskdata.vim
Normal file
|
@ -0,0 +1,48 @@
|
|||
" Vim syntax file
|
||||
" Language: task data
|
||||
" Maintainer: John Florian <jflorian@doubledog.org>
|
||||
" Updated: Wed Jul 8 19:46:20 EDT 2009
|
||||
"
|
||||
" Copyright 2009 John Florian
|
||||
"
|
||||
" This file is available under the GNU Public License version 2 or later.
|
||||
" For the full text of this license, see COPYING.
|
||||
|
||||
|
||||
" For version 5.x: Clear all syntax items.
|
||||
" For version 6.x: Quit when a syntax file was already loaded.
|
||||
if version < 600
|
||||
syntax clear
|
||||
elseif exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
" Key Names for values.
|
||||
syn keyword taskdataKey description due end entry imask mask parent
|
||||
syn keyword taskdataKey priority project recur start status tags uuid
|
||||
syn match taskdataKey "annotation_\d\+"
|
||||
syn match taskdataUndo "^time.*$"
|
||||
syn match taskdataUndo "^\(old \|new \|---\)"
|
||||
|
||||
" Values associated with key names.
|
||||
"
|
||||
" Strings
|
||||
syn region taskdataString matchgroup=Normal start=+"+ end=+"+
|
||||
\ contains=taskdataEncoded,taskdataUUID,@Spell
|
||||
"
|
||||
" Special Embedded Characters (e.g., ",")
|
||||
syn match taskdataEncoded "&\a\+;" contained
|
||||
" UUIDs
|
||||
syn match taskdataUUID "\x\{8}-\(\x\{4}-\)\{3}\x\{12}" contained
|
||||
|
||||
|
||||
" The default methods for highlighting. Can be overridden later.
|
||||
hi def link taskdataEncoded Function
|
||||
hi def link taskdataKey Statement
|
||||
hi def link taskdataString String
|
||||
hi def link taskdataUUID Special
|
||||
hi def link taskdataUndo Type
|
||||
|
||||
let b:current_syntax = "taskdata"
|
||||
|
||||
" vim:noexpandtab
|
40
scripts/vim/syntax/taskedit.vim
Normal file
40
scripts/vim/syntax/taskedit.vim
Normal file
|
@ -0,0 +1,40 @@
|
|||
" Vim syntax file
|
||||
" Language: support for 'task 42 edit'
|
||||
" Maintainer: John Florian <jflorian@doubledog.org>
|
||||
" Updated: Wed Jul 8 19:46:32 EDT 2009
|
||||
"
|
||||
" Copyright 2009 John Florian
|
||||
"
|
||||
" This file is available under the GNU Public License version 2 or later.
|
||||
" For the full text of this license, see COPYING.
|
||||
|
||||
|
||||
" For version 5.x: Clear all syntax items.
|
||||
" For version 6.x: Quit when a syntax file was already loaded.
|
||||
if version < 600
|
||||
syntax clear
|
||||
elseif exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
syn match taskeditHeading "^\s*#\s*Name\s\+Editable details\s*$" contained
|
||||
syn match taskeditHeading "^\s*#\s*-\+\s\+-\+\s*$" contained
|
||||
syn match taskeditReadOnly "^\s*#\s*\(UU\)\?ID:.*$" contained
|
||||
syn match taskeditReadOnly "^\s*#\s*Status:.*$" contained
|
||||
syn match taskeditReadOnly "^\s*#\s*i\?Mask:.*$" contained
|
||||
syn match taskeditKey "^ *.\{-}:" nextgroup=taskeditString
|
||||
syn match taskeditComment "^\s*#.*$"
|
||||
\ contains=taskeditReadOnly,taskeditHeading
|
||||
syn match taskeditString ".*$" contained contains=@Spell
|
||||
|
||||
|
||||
" The default methods for highlighting. Can be overridden later.
|
||||
hi def link taskeditComment Comment
|
||||
hi def link taskeditHeading Function
|
||||
hi def link taskeditKey Statement
|
||||
hi def link taskeditReadOnly Special
|
||||
hi def link taskeditString String
|
||||
|
||||
let b:current_syntax = "taskedit"
|
||||
|
||||
" vim:noexpandtab
|
58
scripts/zsh/_task
Normal file
58
scripts/zsh/_task
Normal file
|
@ -0,0 +1,58 @@
|
|||
#compdef task
|
||||
# zsh completion for task
|
||||
#
|
||||
# Copyright 2009 P.C. Shyamshankar
|
||||
# All rights reserved.
|
||||
#
|
||||
# This script is part of the task project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; if not, write to the
|
||||
#
|
||||
# Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA
|
||||
# 02110-1301
|
||||
# USA
|
||||
#
|
||||
|
||||
typeset -g _task_cmds
|
||||
_task_cmds=($(task rubbish-command | sed -n -e 's/^\s\+task \(\w\+\) .*/\1/p' | grep -v ID))
|
||||
|
||||
# As of task 1.7.0,
|
||||
# _task_cmds=(add append annotate completed edit duplicate delete undelete info start stop done undo projects tags summary timesheet history ghistory next calendar active overdue stats import export color version help list long ls newest oldest)
|
||||
|
||||
_task() {
|
||||
_arguments -s -S \
|
||||
"*::task command:_task_commands"
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
(( $+functions[_task_commands] )) ||
|
||||
_task_commands() {
|
||||
local cmd ret=1
|
||||
if (( CURRENT == 1 )); then
|
||||
_describe -t commands 'task command' _task_cmds
|
||||
else
|
||||
local curcontext="${curcontext}"
|
||||
cmd="${_task_cmds[(r)$words[1]:*]%%:*}"
|
||||
if (( $#cmd )); then
|
||||
curcontext="${curcontext%:*:*}:task-${cmd}"
|
||||
_call_function ret _task_${cmd} || _message "No command remaining."
|
||||
else
|
||||
_message "Unknown subcommand ${cmd}"
|
||||
fi
|
||||
return ret
|
||||
fi
|
||||
}
|
761
src/Att.cpp
Normal file
761
src/Att.cpp
Normal file
|
@ -0,0 +1,761 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "text.h"
|
||||
#include "color.h"
|
||||
#include "util.h"
|
||||
#include "Date.h"
|
||||
#include "Duration.h"
|
||||
#include "Context.h"
|
||||
#include "Att.h"
|
||||
|
||||
extern Context context;
|
||||
|
||||
static const char* internalNames[] =
|
||||
{
|
||||
"entry",
|
||||
"start",
|
||||
"end",
|
||||
"parent",
|
||||
"uuid",
|
||||
"mask",
|
||||
"imask",
|
||||
"limit",
|
||||
"status",
|
||||
"description",
|
||||
};
|
||||
|
||||
static const char* modifiableNames[] =
|
||||
{
|
||||
"project",
|
||||
"priority",
|
||||
"fg",
|
||||
"bg",
|
||||
"due",
|
||||
"recur",
|
||||
"until",
|
||||
"wait",
|
||||
};
|
||||
|
||||
// Synonyms on the same line.
|
||||
static const char* modifierNames[] =
|
||||
{
|
||||
"before", "under", "below",
|
||||
"after", "over", "above",
|
||||
"none",
|
||||
"any",
|
||||
"is", "equals",
|
||||
"isnt", "not",
|
||||
"has", "contains",
|
||||
"hasnt",
|
||||
"startswith", "left",
|
||||
"endswith", "right",
|
||||
};
|
||||
|
||||
#define NUM_INTERNAL_NAMES (sizeof (internalNames) / sizeof (internalNames[0]))
|
||||
#define NUM_MODIFIABLE_NAMES (sizeof (modifiableNames) / sizeof (modifiableNames[0]))
|
||||
#define NUM_MODIFIER_NAMES (sizeof (modifierNames) / sizeof (modifierNames[0]))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Att::Att ()
|
||||
: mName ("")
|
||||
, mValue ("")
|
||||
, mMod ("")
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Att::Att (const std::string& name, const std::string& mod, const std::string& value)
|
||||
{
|
||||
mName = name;
|
||||
mValue = value;
|
||||
mMod = mod;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Att::Att (const std::string& name, const std::string& mod, int value)
|
||||
{
|
||||
mName = name;
|
||||
|
||||
std::stringstream s;
|
||||
s << value;
|
||||
mValue = s.str ();
|
||||
|
||||
mMod = mod;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Att::Att (const std::string& name, const std::string& value)
|
||||
{
|
||||
mName = name;
|
||||
mValue = value;
|
||||
mMod = "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Att::Att (const std::string& name, int value)
|
||||
{
|
||||
mName = name;
|
||||
|
||||
std::stringstream s;
|
||||
s << value;
|
||||
mValue = s.str ();
|
||||
|
||||
mMod = "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Att::Att (const Att& other)
|
||||
{
|
||||
mName = other.mName;
|
||||
mValue = other.mValue;
|
||||
mMod = other.mMod;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Att& Att::operator= (const Att& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
mName = other.mName;
|
||||
mValue = other.mValue;
|
||||
mMod = other.mMod;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Att::~Att ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// For parsing.
|
||||
bool Att::valid (const std::string& input) const
|
||||
{
|
||||
Nibbler n (input);
|
||||
std::string ignored;
|
||||
if (n.getUntilOneOf (".:", ignored))
|
||||
{
|
||||
if (ignored.length () == 0)
|
||||
return false;
|
||||
|
||||
while (n.skip ('.'))
|
||||
if (!n.getUntilOneOf (".:", ignored))
|
||||
return false;
|
||||
|
||||
if (n.skip (':') &&
|
||||
(n.getQuoted ('"', ignored) ||
|
||||
n.getUntil (' ', ignored) ||
|
||||
n.getUntilEOS (ignored) ||
|
||||
n.depleted ()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Att::validInternalName (const std::string& name)
|
||||
{
|
||||
for (unsigned int i = 0; i < NUM_INTERNAL_NAMES; ++i)
|
||||
if (name == internalNames[i])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Att::validModifiableName (const std::string& name)
|
||||
{
|
||||
for (unsigned int i = 0; i < NUM_MODIFIABLE_NAMES; ++i)
|
||||
if (name == modifiableNames[i])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Att::validNameValue (
|
||||
const std::string& name,
|
||||
const std::string& mod,
|
||||
const std::string& value)
|
||||
{
|
||||
std::string writableName = name;
|
||||
std::string writableMod = mod;
|
||||
std::string writableValue = value;
|
||||
return Att::validNameValue (writableName, writableMod, writableValue);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Att::validNameValue (
|
||||
std::string& name,
|
||||
std::string& mod,
|
||||
std::string& value)
|
||||
{
|
||||
// First, guess at the full attribute name.
|
||||
std::vector <std::string> candidates;
|
||||
for (unsigned i = 0; i < NUM_INTERNAL_NAMES; ++i)
|
||||
candidates.push_back (internalNames[i]);
|
||||
|
||||
for (unsigned i = 0; i < NUM_MODIFIABLE_NAMES; ++i)
|
||||
candidates.push_back (modifiableNames[i]);
|
||||
|
||||
std::vector <std::string> matches;
|
||||
autoComplete (name, candidates, matches);
|
||||
|
||||
if (matches.size () == 0)
|
||||
return false;
|
||||
|
||||
else if (matches.size () != 1)
|
||||
{
|
||||
std::string error = "Ambiguous attribute '" + name + "' - could be either of "; // TODO i18n
|
||||
|
||||
std::string combined;
|
||||
join (combined, ", ", matches);
|
||||
|
||||
throw error + combined;
|
||||
}
|
||||
|
||||
name = matches[0];
|
||||
|
||||
// Second, guess at the modifier name.
|
||||
if (mod != "")
|
||||
{
|
||||
candidates.clear ();
|
||||
for (unsigned i = 0; i < NUM_MODIFIER_NAMES; ++i)
|
||||
candidates.push_back (modifierNames[i]);
|
||||
|
||||
matches.clear ();
|
||||
autoComplete (mod, candidates, matches);
|
||||
|
||||
if (matches.size () == 0)
|
||||
throw std::string ("Unrecognized modifier '") + mod + "'";
|
||||
|
||||
else if (matches.size () != 1)
|
||||
{
|
||||
std::string error = "Ambiguous modifier '" + mod + "' - could be either of "; // TODO i18n
|
||||
|
||||
std::string combined;
|
||||
join (combined, ", ", matches);
|
||||
error += combined;
|
||||
|
||||
throw error + combined;
|
||||
}
|
||||
|
||||
mod = matches[0];
|
||||
}
|
||||
|
||||
// Some attributes are intended to be private, unless the command is read-
|
||||
// only, in which cased these are perfectly valid elements of a filter.
|
||||
if (context.cmd.isWriteCommand () &&
|
||||
!validModifiableName (name))
|
||||
throw std::string ("\"") +
|
||||
name +
|
||||
"\" is not an attribute you may modify directly.";
|
||||
|
||||
// Thirdly, make sure the value has the expected form or values.
|
||||
if (name == "project")
|
||||
{
|
||||
if (!noSpaces (value))
|
||||
throw std::string ("The '") + name + "' attribute may not contain spaces.";
|
||||
}
|
||||
|
||||
else if (name == "priority")
|
||||
{
|
||||
if (value != "")
|
||||
{
|
||||
value = upperCase (value);
|
||||
if (value != "H" &&
|
||||
value != "M" &&
|
||||
value != "L")
|
||||
throw std::string ("\"") +
|
||||
value +
|
||||
"\" is not a valid priority. Use H, M, L or leave blank.";
|
||||
}
|
||||
}
|
||||
|
||||
else if (name == "description")
|
||||
{
|
||||
if (context.cmd.isWriteCommand ())
|
||||
{
|
||||
if (value == "")
|
||||
throw std::string ("The '") + name + "' attribute must not be blank.";
|
||||
|
||||
if (!noVerticalSpace (value))
|
||||
throw std::string ("The '") + name + "' attribute must not contain vertical white space.";
|
||||
}
|
||||
}
|
||||
|
||||
else if (name == "fg" || name == "bg")
|
||||
{
|
||||
if (value != "")
|
||||
Text::guessColor (value);
|
||||
}
|
||||
|
||||
else if (name == "due" ||
|
||||
name == "until" ||
|
||||
name == "wait")
|
||||
{
|
||||
// Validate and convert to epoch.
|
||||
if (value != "")
|
||||
value = Date (value, context.config.get ("dateformat", "m/d/Y")).toEpochString ();
|
||||
}
|
||||
|
||||
else if (name == "recur")
|
||||
{
|
||||
// Just validate, don't convert to days.
|
||||
Duration d;
|
||||
if (value != "")
|
||||
d.parse (value);
|
||||
}
|
||||
|
||||
else if (name == "limit")
|
||||
{
|
||||
if (value == "" || !digitsOnly (value))
|
||||
throw std::string ("The '") + name + "' attribute must be an integer.";
|
||||
}
|
||||
|
||||
else if (name == "status")
|
||||
{
|
||||
value = lowerCase (value);
|
||||
|
||||
std::vector <std::string> matches;
|
||||
std::vector <std::string> candidates;
|
||||
candidates.push_back ("pending");
|
||||
candidates.push_back ("completed");
|
||||
candidates.push_back ("deleted");
|
||||
candidates.push_back ("recurring");
|
||||
candidates.push_back ("waiting");
|
||||
autoComplete (value, candidates, matches);
|
||||
|
||||
if (matches.size () == 1)
|
||||
value = matches[0];
|
||||
else
|
||||
throw std::string ("\"") +
|
||||
value +
|
||||
"\" is not a valid status. Use 'pending', 'completed', 'deleted', 'recurring' or 'waiting'.";
|
||||
}
|
||||
|
||||
else if (! validInternalName (name) &&
|
||||
! validModifiableName (name))
|
||||
throw std::string ("'") + name + "' is not a recognized attribute.";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO Obsolete
|
||||
bool Att::validMod (const std::string& mod)
|
||||
{
|
||||
for (unsigned int i = 0; i < NUM_MODIFIER_NAMES; ++i)
|
||||
if (modifierNames[i] == mod)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The type of an attribute is useful for modifier evaluation.
|
||||
std::string Att::type (const std::string& name) const
|
||||
{
|
||||
if (name == "due" ||
|
||||
name == "until" ||
|
||||
name == "start" ||
|
||||
name == "entry" ||
|
||||
name == "end" ||
|
||||
name == "wait")
|
||||
return "date";
|
||||
|
||||
else if (name == "recur")
|
||||
return "duration";
|
||||
|
||||
else if (name == "limit")
|
||||
return "number";
|
||||
|
||||
else
|
||||
return "text";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// start --> name --> . --> mod --> : --> " --> value --> " --> end
|
||||
// | ^
|
||||
// |_____________________|
|
||||
//
|
||||
void Att::parse (const std::string& input)
|
||||
{
|
||||
Nibbler n (input);
|
||||
parse (n);
|
||||
}
|
||||
|
||||
void Att::parse (Nibbler& n)
|
||||
{
|
||||
// Ensure a clean object first.
|
||||
mName = "";
|
||||
mValue = "";
|
||||
mMod = "";
|
||||
|
||||
if (n.getUntilOneOf (".:", mName))
|
||||
{
|
||||
if (mName.length () == 0)
|
||||
throw std::string ("Missing attribute name"); // TODO i18n
|
||||
|
||||
if (n.skip ('.'))
|
||||
{
|
||||
std::string mod;
|
||||
if (n.getUntil (":", mod))
|
||||
{
|
||||
if (validMod (mod))
|
||||
mMod = mod;
|
||||
else
|
||||
throw std::string ("The name '") + mod + "' is not a valid modifier"; // TODO i18n
|
||||
}
|
||||
else
|
||||
throw std::string ("Missing . or : after modifier"); // TODO i18n
|
||||
}
|
||||
|
||||
if (n.skip (':'))
|
||||
{
|
||||
// Both quoted and unquoted Att's are accepted.
|
||||
// Consider removing this for a stricter parse.
|
||||
if (n.getQuoted ('"', mValue) ||
|
||||
n.getUntil (' ', mValue))
|
||||
{
|
||||
decode (mValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw std::string ("Missing : after attribute name"); // TODO i18n
|
||||
}
|
||||
else
|
||||
throw std::string ("Missing : after attribute name"); // TODO i18n
|
||||
|
||||
/* TODO This might be too slow to include. Test.
|
||||
validNameValue (mName, mMod, mValue);
|
||||
*/
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// "this" is the attribute that has modifiers. "other" is the attribute from a
|
||||
// Record that does not have modifiers, but may have a value.
|
||||
bool Att::match (const Att& other) const
|
||||
{
|
||||
// All matches are assumed to pass, any short-circuit on non-match.
|
||||
|
||||
// If there are no mods, just perform a straight compare on value.
|
||||
if (mMod == "")
|
||||
{
|
||||
if (mValue != other.mValue)
|
||||
return false;
|
||||
}
|
||||
|
||||
// has = contains as a substring.
|
||||
else if (mMod == "has" || mMod == "contains") // TODO i18n
|
||||
{
|
||||
if (other.mValue.find (mValue) == std::string::npos)
|
||||
return false;
|
||||
}
|
||||
|
||||
// is = equal. Nop.
|
||||
else if (mMod == "is" || mMod == "equals") // TODO i18n
|
||||
{
|
||||
if (mValue != other.mValue)
|
||||
return false;
|
||||
}
|
||||
|
||||
// isnt = not equal.
|
||||
else if (mMod == "isnt" || mMod == "not") // TODO i18n
|
||||
{
|
||||
if (mValue == other.mValue)
|
||||
return false;
|
||||
}
|
||||
|
||||
// any = any value, but not empty value.
|
||||
else if (mMod == "any") // TODO i18n
|
||||
{
|
||||
if (other.mValue == "")
|
||||
return false;
|
||||
}
|
||||
|
||||
// none = must have empty value.
|
||||
else if (mMod == "none") // TODO i18n
|
||||
{
|
||||
if (other.mValue != "")
|
||||
return false;
|
||||
}
|
||||
|
||||
// startswith = first characters must match.
|
||||
else if (mMod == "startswith" || mMod == "left") // TODO i18n
|
||||
{
|
||||
if (other.mValue.length () < mValue.length ())
|
||||
return false;
|
||||
|
||||
if (mValue != other.mValue.substr (0, mValue.length ()))
|
||||
return false;
|
||||
}
|
||||
|
||||
// endswith = last characters must match.
|
||||
else if (mMod == "endswith" || mMod == "right") // TODO i18n
|
||||
{
|
||||
if (other.mValue.length () < mValue.length ())
|
||||
return false;
|
||||
|
||||
if (mValue != other.mValue.substr (
|
||||
other.mValue.length () - mValue.length (),
|
||||
std::string::npos))
|
||||
return false;
|
||||
}
|
||||
|
||||
// hasnt = does not contain as a substring.
|
||||
else if (mMod == "hasnt") // TODO i18n
|
||||
{
|
||||
if (other.mValue.find (mValue) != std::string::npos)
|
||||
return false;
|
||||
}
|
||||
|
||||
// before = under = below = <
|
||||
else if (mMod == "before" || mMod == "under" || mMod == "below")
|
||||
{
|
||||
std::string which = type (mName);
|
||||
if (which == "duration")
|
||||
{
|
||||
Duration literal (mValue);
|
||||
Duration variable ((time_t)::atoi (other.mValue.c_str ()));
|
||||
if (!(variable < literal))
|
||||
return false;
|
||||
}
|
||||
else if (which == "date")
|
||||
{
|
||||
Date literal (mValue.c_str (), context.config.get ("dateformat", "m/d/Y"));
|
||||
Date variable ((time_t)::atoi (other.mValue.c_str ()));
|
||||
if (other.mValue == "" || ! (variable < literal))
|
||||
return false;
|
||||
}
|
||||
else if (which == "number")
|
||||
{
|
||||
if (::atoi (mValue.c_str ()) >= ::atoi (other.mValue.c_str ()))
|
||||
return false;
|
||||
}
|
||||
else if (which == "text")
|
||||
{
|
||||
if (mValue <= other.mValue)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// after = over = above = >
|
||||
else if (mMod == "after" || mMod == "over" || mMod == "above")
|
||||
{
|
||||
std::string which = type (mName);
|
||||
if (which == "duration")
|
||||
{
|
||||
Duration literal (mValue);
|
||||
Duration variable ((time_t)::atoi (other.mValue.c_str ()));
|
||||
if (! (variable > literal))
|
||||
return false;
|
||||
}
|
||||
else if (which == "date")
|
||||
{
|
||||
Date literal (mValue.c_str (), context.config.get ("dateformat", "m/d/Y"));
|
||||
Date variable ((time_t)::atoi (other.mValue.c_str ()));
|
||||
if (! (variable > literal))
|
||||
return false;
|
||||
}
|
||||
else if (which == "number")
|
||||
{
|
||||
if (::atoi (mValue.c_str ()) <= ::atoi (other.mValue.c_str ()))
|
||||
return false;
|
||||
}
|
||||
else if (which == "text")
|
||||
{
|
||||
if (mValue >= other.mValue)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// name : " value "
|
||||
std::string Att::composeF4 () const
|
||||
{
|
||||
std::string output = "";
|
||||
|
||||
if (mName != "" && mValue != "")
|
||||
{
|
||||
std::string value = mValue;
|
||||
encode (value);
|
||||
enquote (value);
|
||||
|
||||
output += mName + ":" + value;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Att::mod (const std::string& input)
|
||||
{
|
||||
if (input != "" && !validMod (input))
|
||||
throw std::string ("The name '") + input + "' is not a valid modifier"; // TODO i18n
|
||||
|
||||
mMod = input;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Att::mod () const
|
||||
{
|
||||
return mMod;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Att::name () const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Att::name (const std::string& name)
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Att::value () const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Att::value (const std::string& value)
|
||||
{
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Att::value_int () const
|
||||
{
|
||||
return ::atoi (mValue.c_str ());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Att::value_int (int value)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << value;
|
||||
mValue = s.str ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Add quotes.
|
||||
void Att::enquote (std::string& value) const
|
||||
{
|
||||
value = '"' + value + '"';
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Remove quotes. Instead of being picky, just remove them all. There should
|
||||
// be none within the value, and this will correct for one possible corruption
|
||||
// that hand-editing the pending.data file could cause.
|
||||
void Att::dequote (std::string& value) const
|
||||
{
|
||||
std::string::size_type quote;
|
||||
while ((quote = value.find ('"')) != std::string::npos)
|
||||
value.replace (quote, 1, "");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Encode values prior to serialization.
|
||||
// \t -> &tab;
|
||||
// " -> "
|
||||
// , -> ,
|
||||
// [ -> &open;
|
||||
// ] -> &close;
|
||||
// : -> :
|
||||
void Att::encode (std::string& value) const
|
||||
{
|
||||
std::string::size_type i;
|
||||
|
||||
while ((i = value.find ('\t')) != std::string::npos)
|
||||
value.replace (i, 1, "&tab;"); // no i18n
|
||||
|
||||
while ((i = value.find ('"')) != std::string::npos)
|
||||
value.replace (i, 1, """); // no i18n
|
||||
|
||||
while ((i = value.find (',')) != std::string::npos)
|
||||
value.replace (i, 1, ","); // no i18n
|
||||
|
||||
while ((i = value.find ('[')) != std::string::npos)
|
||||
value.replace (i, 1, "&open;"); // no i18n
|
||||
|
||||
while ((i = value.find (']')) != std::string::npos)
|
||||
value.replace (i, 1, "&close;"); // no i18n
|
||||
|
||||
while ((i = value.find (':')) != std::string::npos)
|
||||
value.replace (i, 1, ":"); // no i18n
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Decode values after parse.
|
||||
// \t <- &tab;
|
||||
// " <- "
|
||||
// , <- ,
|
||||
// [ <- &open;
|
||||
// ] <- &close;
|
||||
// : <- :
|
||||
void Att::decode (std::string& value) const
|
||||
{
|
||||
std::string::size_type i;
|
||||
|
||||
while ((i = value.find ("&tab;")) != std::string::npos) // no i18n
|
||||
value.replace (i, 5, "\t");
|
||||
|
||||
while ((i = value.find (""")) != std::string::npos) // no i18n
|
||||
value.replace (i, 6, "\"");
|
||||
|
||||
while ((i = value.find (",")) != std::string::npos) // no i18n
|
||||
value.replace (i, 7, ",");
|
||||
|
||||
while ((i = value.find ("&open;")) != std::string::npos) // no i18n
|
||||
value.replace (i, 6, "[");
|
||||
|
||||
while ((i = value.find ("&close;")) != std::string::npos) // no i18n
|
||||
value.replace (i, 7, "]");
|
||||
|
||||
while ((i = value.find (":")) != std::string::npos) // no i18n
|
||||
value.replace (i, 7, ":");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
84
src/Att.h
Normal file
84
src/Att.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_ATT
|
||||
#define INCLUDED_ATT
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Nibbler.h"
|
||||
|
||||
class Att
|
||||
{
|
||||
public:
|
||||
Att ();
|
||||
Att (const std::string&, const std::string&, const std::string&);
|
||||
Att (const std::string&, const std::string&, int);
|
||||
Att (const std::string&, const std::string&);
|
||||
Att (const std::string&, int);
|
||||
Att (const Att&);
|
||||
Att& operator= (const Att&);
|
||||
~Att ();
|
||||
|
||||
bool valid (const std::string&) const;
|
||||
static bool validInternalName (const std::string&);
|
||||
static bool validModifiableName (const std::string&);
|
||||
static bool validNameValue (const std::string&, const std::string&, const std::string&);
|
||||
static bool validNameValue (std::string&, std::string&, std::string&);
|
||||
static bool validMod (const std::string&);
|
||||
std::string type (const std::string&) const;
|
||||
void parse (const std::string&);
|
||||
void parse (Nibbler&);
|
||||
bool match (const Att&) const;
|
||||
|
||||
std::string composeF4 () const;
|
||||
|
||||
void mod (const std::string&);
|
||||
std::string mod () const;
|
||||
|
||||
std::string name () const;
|
||||
void name (const std::string&);
|
||||
|
||||
std::string value () const;
|
||||
void value (const std::string&);
|
||||
|
||||
int value_int () const;
|
||||
void value_int (int);
|
||||
|
||||
private:
|
||||
void enquote (std::string&) const;
|
||||
void dequote (std::string&) const;
|
||||
void encode (std::string&) const;
|
||||
void decode (std::string&) const;
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
std::string mValue;
|
||||
std::string mMod;
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
234
src/Cmd.cpp
Normal file
234
src/Cmd.cpp
Normal file
|
@ -0,0 +1,234 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <algorithm>
|
||||
#include "Cmd.h"
|
||||
#include "Context.h"
|
||||
#include "util.h"
|
||||
#include "text.h"
|
||||
#include "i18n.h"
|
||||
#include "main.h"
|
||||
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Cmd::Cmd ()
|
||||
: command ("")
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Cmd::Cmd (const std::string& input)
|
||||
{
|
||||
parse (input);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Cmd::~Cmd ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Determines whether the string represents a unique command name or custom
|
||||
// report name.
|
||||
bool Cmd::valid (const std::string& input)
|
||||
{
|
||||
load ();
|
||||
|
||||
std::vector <std::string> matches;
|
||||
autoComplete (lowerCase (context.canonicalize (input)), commands, matches);
|
||||
return matches.size () == 1 ? true : false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Determines whether the string represents a valid custom report name.
|
||||
bool Cmd::validCustom (const std::string& input)
|
||||
{
|
||||
load ();
|
||||
|
||||
std::vector <std::string> matches;
|
||||
autoComplete (lowerCase (context.canonicalize (input)), customReports, matches);
|
||||
return matches.size () == 1 ? true : false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Cmd::parse (const std::string& input)
|
||||
{
|
||||
load ();
|
||||
|
||||
std::string candidate = lowerCase (context.canonicalize (input));
|
||||
|
||||
std::vector <std::string> matches;
|
||||
autoComplete (candidate, commands, matches);
|
||||
if (1 == matches.size ())
|
||||
command = matches[0];
|
||||
|
||||
else if (0 == matches.size ())
|
||||
command = "";
|
||||
|
||||
else
|
||||
{
|
||||
std::string error = "Ambiguous command '" + candidate + "' - could be either of "; // TODO i18n
|
||||
|
||||
std::string combined;
|
||||
join (combined, ", ", matches);
|
||||
throw error + combined;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Cmd::load ()
|
||||
{
|
||||
if (commands.size () == 0)
|
||||
{
|
||||
commands.push_back ("_projects");
|
||||
commands.push_back ("_tags");
|
||||
commands.push_back ("_commands");
|
||||
commands.push_back ("_ids");
|
||||
commands.push_back ("_config");
|
||||
commands.push_back (context.stringtable.get (CMD_ADD, "add"));
|
||||
commands.push_back (context.stringtable.get (CMD_APPEND, "append"));
|
||||
commands.push_back (context.stringtable.get (CMD_ANNOTATE, "annotate"));
|
||||
commands.push_back (context.stringtable.get (CMD_CALENDAR, "calendar"));
|
||||
commands.push_back (context.stringtable.get (CMD_COLORS, "colors"));
|
||||
commands.push_back (context.stringtable.get (CMD_DELETE, "delete"));
|
||||
commands.push_back (context.stringtable.get (CMD_DONE, "done"));
|
||||
commands.push_back (context.stringtable.get (CMD_DUPLICATE, "duplicate"));
|
||||
commands.push_back (context.stringtable.get (CMD_EDIT, "edit"));
|
||||
commands.push_back (context.stringtable.get (CMD_EXPORT, "export"));
|
||||
commands.push_back (context.stringtable.get (CMD_HELP, "help"));
|
||||
commands.push_back (context.stringtable.get (CMD_HISTORY, "history"));
|
||||
commands.push_back (context.stringtable.get (CMD_GHISTORY, "ghistory"));
|
||||
commands.push_back (context.stringtable.get (CMD_IMPORT, "import"));
|
||||
commands.push_back (context.stringtable.get (CMD_INFO, "info"));
|
||||
commands.push_back (context.stringtable.get (CMD_PROJECTS, "projects"));
|
||||
#ifdef FEATURE_SHELL
|
||||
commands.push_back (context.stringtable.get (CMD_SHELL, "shell"));
|
||||
#endif
|
||||
commands.push_back (context.stringtable.get (CMD_START, "start"));
|
||||
commands.push_back (context.stringtable.get (CMD_STATS, "stats"));
|
||||
commands.push_back (context.stringtable.get (CMD_STOP, "stop"));
|
||||
commands.push_back (context.stringtable.get (CMD_SUMMARY, "summary"));
|
||||
commands.push_back (context.stringtable.get (CMD_TAGS, "tags"));
|
||||
commands.push_back (context.stringtable.get (CMD_TIMESHEET, "timesheet"));
|
||||
commands.push_back (context.stringtable.get (CMD_UNDO, "undo"));
|
||||
commands.push_back (context.stringtable.get (CMD_VERSION, "version"));
|
||||
|
||||
// Now load the custom reports.
|
||||
std::vector <std::string> all;
|
||||
context.config.all (all);
|
||||
|
||||
foreach (i, all)
|
||||
{
|
||||
if (i->substr (0, 7) == "report.")
|
||||
{
|
||||
std::string report = i->substr (7, std::string::npos);
|
||||
std::string::size_type columns = report.find (".columns");
|
||||
if (columns != std::string::npos)
|
||||
{
|
||||
report = report.substr (0, columns);
|
||||
|
||||
// Make sure a custom report does not clash with a built-in
|
||||
// command.
|
||||
if (std::find (commands.begin (), commands.end (), report) != commands.end ())
|
||||
throw std::string ("Custom report '") + report +
|
||||
"' conflicts with built-in task command.";
|
||||
|
||||
// A custom report is also a command.
|
||||
customReports.push_back (report);
|
||||
commands.push_back (report);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Cmd::allCustomReports (std::vector <std::string>& all) const
|
||||
{
|
||||
all = customReports;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Cmd::allCommands (std::vector <std::string>& all) const
|
||||
{
|
||||
all.clear ();
|
||||
foreach (command, commands)
|
||||
if (command->substr (0, 1) != "_")
|
||||
all.push_back (*command);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Commands that do not directly modify the data files.
|
||||
bool Cmd::isReadOnlyCommand ()
|
||||
{
|
||||
if (command == "_projects" ||
|
||||
command == "_tags" ||
|
||||
command == "_commands" ||
|
||||
command == "_ids" ||
|
||||
command == "_config" ||
|
||||
command == context.stringtable.get (CMD_CALENDAR, "calendar") ||
|
||||
command == context.stringtable.get (CMD_COLORS, "colors") ||
|
||||
command == context.stringtable.get (CMD_EXPORT, "export") ||
|
||||
command == context.stringtable.get (CMD_HELP, "help") ||
|
||||
command == context.stringtable.get (CMD_HISTORY, "history") ||
|
||||
command == context.stringtable.get (CMD_GHISTORY, "ghistory") ||
|
||||
command == context.stringtable.get (CMD_INFO, "info") ||
|
||||
command == context.stringtable.get (CMD_PROJECTS, "projects") ||
|
||||
command == context.stringtable.get (CMD_SHELL, "shell") ||
|
||||
command == context.stringtable.get (CMD_STATS, "stats") ||
|
||||
command == context.stringtable.get (CMD_SUMMARY, "summary") ||
|
||||
command == context.stringtable.get (CMD_TAGS, "tags") ||
|
||||
command == context.stringtable.get (CMD_TIMESHEET, "timesheet") ||
|
||||
command == context.stringtable.get (CMD_VERSION, "version") ||
|
||||
validCustom (command))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Commands that directly modify the data files.
|
||||
bool Cmd::isWriteCommand ()
|
||||
{
|
||||
if (command == context.stringtable.get (CMD_ADD, "add") ||
|
||||
command == context.stringtable.get (CMD_APPEND, "append") ||
|
||||
command == context.stringtable.get (CMD_ANNOTATE, "annotate") ||
|
||||
command == context.stringtable.get (CMD_DELETE, "delete") ||
|
||||
command == context.stringtable.get (CMD_DONE, "done") ||
|
||||
command == context.stringtable.get (CMD_DUPLICATE, "duplicate") ||
|
||||
command == context.stringtable.get (CMD_EDIT, "edit") ||
|
||||
command == context.stringtable.get (CMD_IMPORT, "import") ||
|
||||
command == context.stringtable.get (CMD_START, "start") ||
|
||||
command == context.stringtable.get (CMD_STOP, "stop") ||
|
||||
command == context.stringtable.get (CMD_UNDO, "undo"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
64
src/Cmd.h
Normal file
64
src/Cmd.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_CMD
|
||||
#define INCLUDED_CMD
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class Cmd
|
||||
{
|
||||
public:
|
||||
Cmd (); // Default constructor
|
||||
Cmd (const std::string&); // Default constructor
|
||||
~Cmd (); // Destructor
|
||||
|
||||
Cmd (const Cmd&);
|
||||
Cmd& operator= (const Cmd&);
|
||||
|
||||
bool valid (const std::string&);
|
||||
bool validCustom (const std::string&);
|
||||
void parse (const std::string&);
|
||||
void allCustomReports (std::vector <std::string>&) const;
|
||||
void allCommands (std::vector <std::string>&) const;
|
||||
|
||||
bool isReadOnlyCommand ();
|
||||
bool isWriteCommand ();
|
||||
|
||||
public:
|
||||
std::string command;
|
||||
|
||||
private:
|
||||
void load ();
|
||||
|
||||
private:
|
||||
std::vector <std::string> commands;
|
||||
std::vector <std::string> customReports;
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
378
src/Config.cpp
378
src/Config.cpp
|
@ -32,8 +32,9 @@
|
|||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include "task.h"
|
||||
#include "Config.h"
|
||||
#include "text.h"
|
||||
#include "util.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// These are default (but overridable) reports. These entries are necessary
|
||||
|
@ -44,32 +45,7 @@
|
|||
// upgrade program to make the change, or c) this.
|
||||
Config::Config ()
|
||||
{
|
||||
(*this)["report.long.description"] = "Lists all task, all data, matching the specified criteria";
|
||||
(*this)["report.long.columns"] = "id,project,priority,entry,start,due,recur,age,tags,description";
|
||||
(*this)["report.long.labels"] = "ID,Project,Pri,Added,Started,Due,Recur,Age,Tags,Description";
|
||||
(*this)["report.long.sort"] = "due+,priority-,project+";
|
||||
|
||||
(*this)["report.list.description"] = "Lists all tasks matching the specified criteria";
|
||||
(*this)["report.list.columns"] = "id,project,priority,due,active,age,description";
|
||||
(*this)["report.list.labels"] = "ID,Project,Pri,Due,Active,Age,Description";
|
||||
(*this)["report.list.sort"] = "due+,priority-,project+";
|
||||
|
||||
(*this)["report.ls.description"] = "Minimal listing of all tasks matching the specified criteria";
|
||||
(*this)["report.ls.columns"] = "id,project,priority,description";
|
||||
(*this)["report.ls.labels"] = "ID,Project,Pri,Description";
|
||||
(*this)["report.ls.sort"] = "priority-,project+";
|
||||
|
||||
(*this)["report.newest.description"] = "Shows the newest tasks";
|
||||
(*this)["report.newest.columns"] = "id,project,priority,due,active,age,description";
|
||||
(*this)["report.newest.labels"] = "ID,Project,Pri,Due,Active,Age,Description";
|
||||
(*this)["report.newest.sort"] = "id-";
|
||||
(*this)["report.newest.limit"] = "10";
|
||||
|
||||
(*this)["report.oldest.description"] = "Shows the oldest tasks";
|
||||
(*this)["report.oldest.columns"] = "id,project,priority,due,active,age,description";
|
||||
(*this)["report.oldest.labels"] = "ID,Project,Pri,Due,Active,Age,Description";
|
||||
(*this)["report.oldest.sort"] = "id+";
|
||||
(*this)["report.oldest.limit"] = "10";
|
||||
setDefaults ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -92,20 +68,20 @@ bool Config::load (const std::string& file)
|
|||
while (getline (in, line))
|
||||
{
|
||||
// Remove comments.
|
||||
size_type pound = line.find ("#");
|
||||
std::string::size_type pound = line.find ("#"); // no i18n
|
||||
if (pound != std::string::npos)
|
||||
line = line.substr (0, pound);
|
||||
|
||||
line = trim (line, " \t");
|
||||
line = trim (line, " \t"); // no i18n
|
||||
|
||||
// Skip empty lines.
|
||||
if (line.length () > 0)
|
||||
{
|
||||
size_type equal = line.find ("=");
|
||||
std::string::size_type equal = line.find ("="); // no i18n
|
||||
if (equal != std::string::npos)
|
||||
{
|
||||
std::string key = trim (line.substr (0, equal), " \t");
|
||||
std::string value = trim (line.substr (equal+1, line.length () - equal), " \t");
|
||||
std::string key = trim (line.substr (0, equal), " \t"); // no i18n
|
||||
std::string value = trim (line.substr (equal+1, line.length () - equal), " \t"); // no i18n
|
||||
(*this)[key] = value;
|
||||
}
|
||||
}
|
||||
|
@ -119,112 +95,234 @@ bool Config::load (const std::string& file)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Config::createDefault (const std::string& home)
|
||||
{
|
||||
// Strip trailing slash off home directory, if necessary.
|
||||
std::string terminatedHome = home;
|
||||
if (home[home.length () - 1] == '/')
|
||||
terminatedHome = home.substr (0, home.length () - 1);
|
||||
|
||||
// Determine default names of init file and task directory.
|
||||
std::string rcFile = terminatedHome + "/.taskrc";
|
||||
std::string dataDir = terminatedHome + "/.task";;
|
||||
|
||||
// If rcFile is not found, offer to create one.
|
||||
if (-1 == access (rcFile.c_str (), F_OK))
|
||||
{
|
||||
if (confirm (
|
||||
"A configuration file could not be found in "
|
||||
+ rcFile
|
||||
+ "\n\n"
|
||||
+ "Would you like a sample .taskrc created, so task can proceed?"))
|
||||
void Config::createDefaultRC (const std::string& rc, const std::string& data)
|
||||
{
|
||||
// Create a sample .taskrc file.
|
||||
FILE* out;
|
||||
if ((out = fopen (rcFile.c_str (), "w")))
|
||||
std::stringstream contents;
|
||||
contents << "# Task program configuration file.\n"
|
||||
<< "# For more documentation, see http://taskwarrior.org\n"
|
||||
<< "\n"
|
||||
<< "# Files\n"
|
||||
<< "data.location=" << data << "\n"
|
||||
<< "locking=on # Use file-level locking\n"
|
||||
<< "\n"
|
||||
<< "# Terminal\n"
|
||||
<< "curses=on # Use ncurses library to determine terminal width\n"
|
||||
<< "#defaultwidth=80 # Without ncurses, assumed width\n"
|
||||
<< "#editor=vi # Preferred text editor\n"
|
||||
<< "\n"
|
||||
<< "# Miscellaneous\n"
|
||||
<< "confirmation=yes # Confirmation on delete, big changes\n"
|
||||
<< "echo.command=yes # Details on command just run\n"
|
||||
<< "next=2 # How many tasks per project in next report\n"
|
||||
<< "bulk=2 # > 2 tasks considered 'a lot', for confirmation\n"
|
||||
<< "nag=You have higher priority tasks. # Nag message to keep you honest\n"
|
||||
<< "\n"
|
||||
<< "# Dates\n"
|
||||
<< "dateformat=m/d/Y # Preferred input and display date format\n"
|
||||
<< "weekstart=Sunday # Sunday or Monday only\n"
|
||||
<< "displayweeknumber=yes # Show week numbers on calendar\n"
|
||||
<< "due=7 # Task is considered due in 7 days\n"
|
||||
<< "#monthsperline=2 # Number of calendar months on a line\n"
|
||||
<< "\n"
|
||||
<< "# Color controls.\n"
|
||||
<< "color=on # Use color\n"
|
||||
<< "color.overdue=bold_red # Color of overdue tasks\n"
|
||||
<< "color.due=bold_yellow # Color of due tasks\n"
|
||||
<< "color.pri.H=bold # Color of priority:H tasks\n"
|
||||
<< "#color.pri.M=on_yellow # Color of priority:M tasks\n"
|
||||
<< "#color.pri.L=on_green # Color of priority:L tasks\n"
|
||||
<< "#color.pri.none=white on_blue # Color of priority: tasks\n"
|
||||
<< "color.active=bold_cyan # Color of active tasks\n"
|
||||
<< "color.tagged=yellow # Color of tagged tasks\n"
|
||||
<< "#color.tag.bug=yellow # Color of +bug tasks\n"
|
||||
<< "#color.project.garden=on_green # Color of project:garden tasks\n"
|
||||
<< "#color.keyword.car=on_blue # Color of description.contains:car tasks\n"
|
||||
<< "#color.recurring=on_red # Color of recur.any: tasks\n"
|
||||
<< "#color.header=bold_green # Color of header messages\n"
|
||||
<< "#color.footnote=bold_green # Color of footnote messages\n"
|
||||
<< "\n"
|
||||
<< "#shadow.file=/tmp/shadow.txt # Location of shadow file\n"
|
||||
<< "#shadow.command=list # Task command for shadow file\n"
|
||||
<< "#shadow.notify=on # Footnote when updated\n"
|
||||
<< "\n"
|
||||
<< "#default.project=foo # Unless otherwise specified\n"
|
||||
<< "#default.priority=M # Unless otherwise specified\n"
|
||||
<< "default.command=list # Unless otherwise specified\n"
|
||||
<< "\n"
|
||||
<< "# Fields: id,uuid,project,priority,entry,start,due,recur,recur_ind,age,\n"
|
||||
<< "# age_compact,active,tags,description,description_only\n"
|
||||
<< "# Description: This report is ...\n"
|
||||
<< "# Sort: due+,priority-,project+\n"
|
||||
<< "# Filter: pro:x pri:H +bug limit:10\n"
|
||||
<< "\n"
|
||||
<< "# task long\n"
|
||||
<< "report.long.description=Lists all task, all data, matching the specified criteria\n"
|
||||
<< "report.long.columns=id,project,priority,entry,start,due,recur,age,tags,description\n"
|
||||
<< "report.long.labels=ID,Project,Pri,Added,Started,Due,Recur,Age,Tags,Description\n"
|
||||
<< "report.long.sort=due+,priority-,project+\n"
|
||||
<< "report.long.filter=status:pending\n"
|
||||
<< "\n"
|
||||
<< "# task list\n"
|
||||
<< "report.list.description=Lists all tasks matching the specified criteria\n"
|
||||
<< "report.list.columns=id,project,priority,due,active,age,description\n"
|
||||
<< "report.list.labels=ID,Project,Pri,Due,Active,Age,Description\n"
|
||||
<< "report.list.sort=due+,priority-,project+\n"
|
||||
<< "report.list.filter=status:pending\n"
|
||||
<< "\n"
|
||||
<< "# task ls\n"
|
||||
<< "report.ls.description=Minimal listing of all tasks matching the specified criteria\n"
|
||||
<< "report.ls.columns=id,project,priority,description\n"
|
||||
<< "report.ls.labels=ID,Project,Pri,Description\n"
|
||||
<< "report.ls.sort=priority-,project+\n"
|
||||
<< "report.ls.filter=status:pending\n"
|
||||
<< "\n"
|
||||
<< "# task newest\n"
|
||||
<< "report.newest.description=Shows the newest tasks\n"
|
||||
<< "report.newest.columns=id,project,priority,due,active,age,description\n"
|
||||
<< "report.newest.labels=ID,Project,Pri,Due,Active,Age,Description\n"
|
||||
<< "report.newest.sort=id-\n"
|
||||
<< "report.newest.filter=status:pending limit:10\n"
|
||||
<< "\n"
|
||||
<< "# task oldest\n"
|
||||
<< "report.oldest.description=Shows the oldest tasks\n"
|
||||
<< "report.oldest.columns=id,project,priority,due,active,age,description\n"
|
||||
<< "report.oldest.labels=ID,Project,Pri,Due,Active,Age,Description\n"
|
||||
<< "report.oldest.sort=id+\n"
|
||||
<< "report.oldest.filter=status:pending limit:10\n"
|
||||
<< "\n"
|
||||
<< "# task overdue\n"
|
||||
<< "report.overdue.description=Lists overdue tasks matching the specified criteria\n"
|
||||
<< "report.overdue.columns=id,project,priority,due,active,age,description\n"
|
||||
<< "report.overdue.labels=ID,Project,Pri,Due,Active,Age,Description\n"
|
||||
<< "report.overdue.sort=due+,priority-,project+\n"
|
||||
<< "report.overdue.filter=status:pending due.before:today\n"
|
||||
<< "\n"
|
||||
<< "# task active\n"
|
||||
<< "report.active.description=Lists active tasks matching the specified criteria\n"
|
||||
<< "report.active.columns=id,project,priority,due,active,age,description\n"
|
||||
<< "report.active.labels=ID,Project,Pri,Due,Active,Age,Description\n"
|
||||
<< "report.active.sort=due+,priority-,project+\n"
|
||||
<< "report.active.filter=status:pending start.any:\n"
|
||||
<< "\n"
|
||||
<< "# task completed\n"
|
||||
<< "report.completed.description=Lists completed tasks matching the specified criteria\n"
|
||||
<< "report.completed.columns=end,project,priority,age,description\n"
|
||||
<< "report.completed.labels=Complete,Project,Pri,Age,Description\n"
|
||||
<< "report.completed.sort=end+,priority-,project+\n"
|
||||
<< "report.completed.filter=status:completed\n"
|
||||
<< "\n"
|
||||
<< "# task recurring\n"
|
||||
<< "report.recurring.description=Lists recurring tasks matching the specified criteria\n"
|
||||
<< "report.recurring.columns=id,project,priority,due,recur,active,age,description\n"
|
||||
<< "report.recurring.labels=ID,Project,Pri,Due,Recur,Active,Age,Description\n"
|
||||
<< "report.recurring.sort=due+,priority-,project+\n"
|
||||
<< "report.recurring.filter=status:pending parent.any:\n"
|
||||
<< "\n"
|
||||
<< "# task waiting\n"
|
||||
<< "report.waiting.description=Lists all waiting tasks matching the specified criteria\n"
|
||||
<< "report.waiting.columns=id,project,priority,wait,age,description\n"
|
||||
<< "report.waiting.labels=ID,Project,Pri,Wait,Age,Description\n"
|
||||
<< "report.waiting.sort=wait+,priority-,project+\n"
|
||||
<< "report.waiting.filter=status:waiting\n"
|
||||
<< "\n"
|
||||
<< "# task all\n"
|
||||
<< "report.all.description=Lists all tasks matching the specified criteria\n"
|
||||
<< "report.all.columns=id,project,priority,due,active,age,description\n"
|
||||
<< "report.all.labels=ID,Project,Pri,Due,Active,Age,Description\n"
|
||||
<< "report.all.sort=due+,priority-,project+\n"
|
||||
<< "\n"
|
||||
<< "# task next\n"
|
||||
<< "report.next.description=Lists the most urgent tasks\n"
|
||||
<< "report.next.columns=id,project,priority,due,active,age,description\n"
|
||||
<< "report.next.labels=ID,Project,Pri,Due,Active,Age,Description\n"
|
||||
<< "report.next.sort=due+,priority-,project+\n"
|
||||
<< "report.next.filter=status:pending\n"
|
||||
<< "\n";
|
||||
|
||||
spit (rc, contents.str ());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Config::createDefaultData (const std::string& data)
|
||||
{
|
||||
fprintf (out, "data.location=%s\n", dataDir.c_str ());
|
||||
fprintf (out, "confirmation=yes\n");
|
||||
fprintf (out, "echo.command=yes\n");
|
||||
fprintf (out, "next=2\n");
|
||||
fprintf (out, "dateformat=m/d/Y\n");
|
||||
fprintf (out, "#monthsperline=2\n");
|
||||
fprintf (out, "#defaultwidth=80\n");
|
||||
fprintf (out, "curses=on\n");
|
||||
fprintf (out, "color=on\n");
|
||||
fprintf (out, "due=7\n");
|
||||
fprintf (out, "nag=You have higher priority tasks.\n");
|
||||
fprintf (out, "locking=on\n");
|
||||
fprintf (out, "#editor=vi\n");
|
||||
|
||||
fprintf (out, "color.overdue=bold_red\n");
|
||||
fprintf (out, "color.due=bold_yellow\n");
|
||||
fprintf (out, "color.pri.H=bold\n");
|
||||
fprintf (out, "#color.pri.M=on_yellow\n");
|
||||
fprintf (out, "#color.pri.L=on_green\n");
|
||||
fprintf (out, "#color.pri.none=white on_blue\n");
|
||||
fprintf (out, "color.active=bold_cyan\n");
|
||||
fprintf (out, "color.tagged=yellow\n");
|
||||
fprintf (out, "#color.tag.bug=yellow\n");
|
||||
fprintf (out, "#color.project.garden=on_green\n");
|
||||
fprintf (out, "#color.keyword.car=on_blue\n");
|
||||
fprintf (out, "#color.recurring=on_red\n");
|
||||
fprintf (out, "#shadow.file=%s/shadow.txt\n", dataDir.c_str ());
|
||||
fprintf (out, "#shadow.command=list\n");
|
||||
fprintf (out, "#shadow.notify=on\n");
|
||||
fprintf (out, "#default.project=foo\n");
|
||||
fprintf (out, "#default.priority=M\n");
|
||||
fprintf (out, "default.command=list\n");
|
||||
|
||||
// Custom reports.
|
||||
fprintf (out, "# Fields: id,uuid,project,priority,entry,start,due,recur,age,active,tags,description\n");
|
||||
fprintf (out, "# description_only\n");
|
||||
fprintf (out, "# Description: This report is ...\n");
|
||||
fprintf (out, "# Sort: due+,priority-,project+\n");
|
||||
fprintf (out, "# Filter: pro:x pri:H +bug\n");
|
||||
fprintf (out, "# Limit: 10\n");
|
||||
|
||||
fprintf (out, "report.long.description=Lists all task, all data, matching the specified criteria\n");
|
||||
fprintf (out, "report.long.labels=ID,Project,Pri,Added,Started,Due,Recur,Age,Tags,Description\n");
|
||||
fprintf (out, "report.long.columns=id,project,priority,entry,start,due,recur,age,tags,description\n");
|
||||
fprintf (out, "report.long.sort=due+,priority-,project+\n");
|
||||
|
||||
fprintf (out, "report.list.description=Lists all tasks matching the specified criteria\n");
|
||||
fprintf (out, "report.list.labels=ID,Project,Pri,Due,Active,Age,Description\n");
|
||||
fprintf (out, "report.list.columns=id,project,priority,due,active,age,description\n");
|
||||
fprintf (out, "report.list.sort=due+,priority-,project+\n");
|
||||
|
||||
fprintf (out, "report.ls.description=Minimal listing of all tasks matching the specified criteria\n");
|
||||
fprintf (out, "report.ls.labels=ID,Project,Pri,Description\n");
|
||||
fprintf (out, "report.ls.columns=id,project,priority,description\n");
|
||||
fprintf (out, "report.ls.sort=priority-,project+\n");
|
||||
|
||||
fprintf (out, "report.newest.description=Shows the newest tasks\n");
|
||||
fprintf (out, "report.newest.labels=ID,Project,Pri,Due,Active,Age,Description\n");
|
||||
fprintf (out, "report.newest.columns=id,project,priority,due,active,age,description\n");
|
||||
fprintf (out, "report.newest.sort=id-\n");
|
||||
fprintf (out, "report.newest.limit=10\n");
|
||||
|
||||
fprintf (out, "report.oldest.description=Shows the oldest tasks\n");
|
||||
fprintf (out, "report.oldest.labels=ID,Project,Pri,Due,Active,Age,Description\n");
|
||||
fprintf (out, "report.oldest.columns=id,project,priority,due,active,age,description\n");
|
||||
fprintf (out, "report.oldest.sort=id+\n");
|
||||
fprintf (out, "report.oldest.limit=10\n");
|
||||
|
||||
fclose (out);
|
||||
|
||||
std::cout << "Done." << std::endl;
|
||||
}
|
||||
}
|
||||
if (access (data.c_str (), F_OK))
|
||||
mkdir (data.c_str (), S_IRWXU);
|
||||
}
|
||||
|
||||
this->load (rcFile);
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Config::setDefaults ()
|
||||
{
|
||||
set ("report.long.description", "Lists all task, all data, matching the specified criteria"); // TODO i18n
|
||||
set ("report.long.columns", "id,project,priority,entry,start,due,recur,age,tags,description"); // TODO i18n
|
||||
set ("report.long.labels", "ID,Project,Pri,Added,Started,Due,Recur,Age,Tags,Description"); // TODO i18n
|
||||
set ("report.long.sort", "due+,priority-,project+"); // TODO i18n
|
||||
set ("report.long.filter", "status:pending"); // TODO i18n
|
||||
|
||||
// Get the data.location value from the (potentially newly created) .taskrc
|
||||
// file.
|
||||
dataDir = this->get ("data.location", dataDir);
|
||||
if (-1 == access (dataDir.c_str (), F_OK))
|
||||
mkdir (dataDir.c_str (), S_IRWXU);
|
||||
set ("report.list.description", "Lists all tasks matching the specified criteria"); // TODO i18n
|
||||
set ("report.list.columns", "id,project,priority,due,active,age,description"); // TODO i18n
|
||||
set ("report.list.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n
|
||||
set ("report.list.sort", "due+,priority-,project+"); // TODO i18n
|
||||
set ("report.list.filter", "status:pending"); // TODO i18n
|
||||
|
||||
set ("report.ls.description", "Minimal listing of all tasks matching the specified criteria"); // TODO i18n
|
||||
set ("report.ls.columns", "id,project,priority,description"); // TODO i18n
|
||||
set ("report.ls.labels", "ID,Project,Pri,Description"); // TODO i18n
|
||||
set ("report.ls.sort", "priority-,project+"); // TODO i18n
|
||||
set ("report.ls.filter", "status:pending"); // TODO i18n
|
||||
|
||||
set ("report.newest.description", "Shows the newest tasks"); // TODO i18n
|
||||
set ("report.newest.columns", "id,project,priority,due,active,age,description"); // TODO i18n
|
||||
set ("report.newest.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n
|
||||
set ("report.newest.sort", "id-"); // TODO i18n
|
||||
set ("report.newest.filter", "status:pending limit:10"); // TODO i18n
|
||||
|
||||
set ("report.oldest.description", "Shows the oldest tasks"); // TODO i18n
|
||||
set ("report.oldest.columns", "id,project,priority,due,active,age,description"); // TODO i18n
|
||||
set ("report.oldest.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n
|
||||
set ("report.oldest.sort", "id+"); // TODO i18n
|
||||
set ("report.oldest.filter", "status:pending limit:10"); // TODO i18n
|
||||
|
||||
set ("report.overdue.description", "Lists overdue tasks matching the specified criteria"); // TODO i18n
|
||||
set ("report.overdue.columns", "id,project,priority,due,active,age,description"); // TODO i18n
|
||||
set ("report.overdue.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n
|
||||
set ("report.overdue.sort", "due+,priority-,project+"); // TODO i18n
|
||||
set ("report.overdue.filter", "status:pending due.before:today"); // TODO i18n
|
||||
|
||||
set ("report.active.description", "Lists active tasks matching the specified criteria"); // TODO i18n
|
||||
set ("report.active.columns", "id,project,priority,due,active,age,description"); // TODO i18n
|
||||
set ("report.active.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n
|
||||
set ("report.active.sort", "due+,priority-,project+"); // TODO i18n
|
||||
set ("report.active.filter", "status:pending start.any:"); // TODO i18n
|
||||
|
||||
set ("report.completed.description", "Lists completed tasks matching the specified criteria"); // TODO i18n
|
||||
set ("report.completed.columns", "end,project,priority,age,description"); // TODO i18n
|
||||
set ("report.completed.labels", "Complete,Project,Pri,Age,Description"); // TODO i18n
|
||||
set ("report.completed.sort", "end+,priority-,project+"); // TODO i18n
|
||||
set ("report.completed.filter", "status:completed"); // TODO i18n
|
||||
|
||||
set ("report.recurring.description", "Lists recurring tasks matching the specified criteria"); // TODO i18n
|
||||
set ("report.recurring.columns", "id,project,priority,due,recur,active,age,description"); // TODO i18n
|
||||
set ("report.recurring.labels", "ID,Project,Pri,Due,Recur,Active,Age,Description"); // TODO i18n
|
||||
set ("report.recurring.sort", "due+,priority-,project+"); // TODO i18n
|
||||
set ("report.recurring.filter", "status:pending parent.any:"); // TODO i18n
|
||||
|
||||
set ("report.waiting.description", "Lists all waiting tasks matching the specified criteria"); // TODO i18n
|
||||
set ("report.waiting.columns", "id,project,priority,wait,age,description"); // TODO i18n
|
||||
set ("report.waiting.labels", "ID,Project,Pri,Wait,Age,Description"); // TODO i18n
|
||||
set ("report.waiting.sort", "wait+,priority-,project+"); // TODO i18n
|
||||
set ("report.waiting.filter", "status:waiting"); // TODO i18n
|
||||
|
||||
set ("report.all.description", "Lists all tasks matching the specified criteria"); // TODO i18n
|
||||
set ("report.all.columns", "id,project,priority,due,active,age,description"); // TODO i18n
|
||||
set ("report.all.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n
|
||||
set ("report.all.sort", "due+,priority-,project+"); // TODO i18n
|
||||
|
||||
set ("report.next.description", "Lists the most urgent tasks"); // TODO i18n
|
||||
set ("report.next.columns", "id,project,priority,due,active,age,description"); // TODO i18n
|
||||
set ("report.next.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n
|
||||
set ("report.next.sort", "due+,priority-,project+"); // TODO i18n
|
||||
set ("report.next.filter", "status:pending"); // TODO i18n
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -265,19 +363,19 @@ const std::string Config::get (
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Config::get (const std::string& key, bool default_value)
|
||||
bool Config::get (const std::string& key, const bool default_value)
|
||||
{
|
||||
if ((*this).find (key) != (*this).end ())
|
||||
{
|
||||
std::string value = lowerCase ((*this)[key]);
|
||||
|
||||
if (value == "t" ||
|
||||
value == "true" ||
|
||||
value == "1" ||
|
||||
value == "yes" ||
|
||||
value == "on" ||
|
||||
value == "enable" ||
|
||||
value == "enabled")
|
||||
if (value == "t" || // TODO i18n
|
||||
value == "true" || // TODO i18n
|
||||
value == "1" || // no i18n
|
||||
value == "yes" || // TODO i18n
|
||||
value == "on" || // TODO i18n
|
||||
value == "enable" || // TODO i18n
|
||||
value == "enabled") // TODO i18n
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -37,14 +37,19 @@ public:
|
|||
Config ();
|
||||
Config (const std::string&);
|
||||
|
||||
Config (const Config&);
|
||||
Config& operator= (const Config&);
|
||||
|
||||
bool load (const std::string&);
|
||||
void createDefault (const std::string&);
|
||||
void createDefaultRC (const std::string&, const std::string&);
|
||||
void createDefaultData (const std::string&);
|
||||
void setDefaults ();
|
||||
|
||||
const std::string get (const char*);
|
||||
const std::string get (const char*, const char*);
|
||||
const std::string get (const std::string&);
|
||||
const std::string get (const std::string&, const std::string&);
|
||||
bool get (const std::string&, bool);
|
||||
bool get (const std::string&, const bool);
|
||||
int get (const std::string&, const int);
|
||||
double get (const std::string&, const double);
|
||||
void set (const std::string&, const int);
|
||||
|
|
757
src/Context.cpp
Normal file
757
src/Context.cpp
Normal file
|
@ -0,0 +1,757 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "Context.h"
|
||||
#include "Timer.h"
|
||||
#include "text.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "i18n.h"
|
||||
#include "../auto.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Context::Context ()
|
||||
: config ()
|
||||
, filter ()
|
||||
, keymap ()
|
||||
, sequence ()
|
||||
, subst ()
|
||||
, task ()
|
||||
, tdb ()
|
||||
, stringtable ()
|
||||
, program ("")
|
||||
, cmd ()
|
||||
, inShadow (false)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Context::~Context ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Context::initialize (int argc, char** argv)
|
||||
{
|
||||
// Capture the args.
|
||||
for (int i = 0; i < argc; ++i)
|
||||
if (i == 0)
|
||||
{
|
||||
program = argv[i];
|
||||
std::string::size_type cal = program.find ("/cal");
|
||||
if (program == "cal" ||
|
||||
(cal != std::string::npos && program.length () == cal + 4))
|
||||
args.push_back ("calendar");
|
||||
}
|
||||
else
|
||||
args.push_back (argv[i]);
|
||||
|
||||
initialize ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Context::initialize ()
|
||||
{
|
||||
Timer t ("Context::initialize");
|
||||
|
||||
// Load the configuration file from the home directory. If the file cannot
|
||||
// be found, offer to create a sample one.
|
||||
loadCorrectConfigFile ();
|
||||
loadAliases ();
|
||||
|
||||
// When redirecting output to a file, do not use color, curses.
|
||||
if (!isatty (fileno (stdout)))
|
||||
{
|
||||
config.set ("curses", "off");
|
||||
|
||||
if (! config.get (std::string ("_forcecolor"), false))
|
||||
config.set ("color", "off");
|
||||
}
|
||||
|
||||
if (config.get ("color", true))
|
||||
initializeColorRules ();
|
||||
|
||||
// Load appropriate stringtable as soon after the config file as possible, to
|
||||
// allow all subsequent messages to be localizable.
|
||||
std::string location = expandPath (config.get ("data.location"));
|
||||
std::string locale = config.get ("locale");
|
||||
|
||||
// If there is a locale variant (en-US.<variant>), then strip it.
|
||||
std::string::size_type period = locale.find ('.');
|
||||
if (period != std::string::npos)
|
||||
locale = locale.substr (0, period);
|
||||
|
||||
if (locale != "")
|
||||
stringtable.load (location + "/strings." + locale);
|
||||
|
||||
// TODO Handle "--version, -v" right here?
|
||||
|
||||
// init TDB.
|
||||
tdb.clear ();
|
||||
std::vector <std::string> all;
|
||||
split (all, location, ',');
|
||||
foreach (path, all)
|
||||
tdb.location (expandPath (*path));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Context::run ()
|
||||
{
|
||||
Timer t ("Context::run");
|
||||
|
||||
std::string output;
|
||||
try
|
||||
{
|
||||
parse (); // Parse command line.
|
||||
output = dispatch (); // Dispatch to command handlers.
|
||||
}
|
||||
|
||||
catch (const std::string& error)
|
||||
{
|
||||
footnote (error);
|
||||
}
|
||||
|
||||
catch (...)
|
||||
{
|
||||
footnote (stringtable.get (100, "Unknown error."));
|
||||
}
|
||||
|
||||
// Dump all debug messages.
|
||||
if (config.get (std::string ("debug"), false))
|
||||
foreach (d, debugMessages)
|
||||
std::cout << colorizeDebug (*d) << std::endl;
|
||||
|
||||
// Dump all headers.
|
||||
foreach (h, headers)
|
||||
std::cout << colorizeHeader (*h) << std::endl;
|
||||
|
||||
// Dump the report output.
|
||||
std::cout << output;
|
||||
|
||||
// Dump all footnotes.
|
||||
foreach (f, footnotes)
|
||||
std::cout << colorizeFootnote (*f) << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Context::dispatch ()
|
||||
{
|
||||
Timer t ("Context::dispatch");
|
||||
|
||||
// TODO Just look at this thing. It cries out for a dispatch table.
|
||||
std::string out;
|
||||
if (cmd.command == "projects") { out = handleProjects (); }
|
||||
else if (cmd.command == "tags") { out = handleTags (); }
|
||||
else if (cmd.command == "colors") { out = handleColor (); }
|
||||
else if (cmd.command == "version") { out = handleVersion (); }
|
||||
else if (cmd.command == "help") { out = longUsage (); }
|
||||
else if (cmd.command == "stats") { out = handleReportStats (); }
|
||||
else if (cmd.command == "info") { out = handleInfo (); }
|
||||
else if (cmd.command == "history") { out = handleReportHistory (); }
|
||||
else if (cmd.command == "ghistory") { out = handleReportGHistory (); }
|
||||
else if (cmd.command == "summary") { out = handleReportSummary (); }
|
||||
else if (cmd.command == "calendar") { out = handleReportCalendar (); }
|
||||
else if (cmd.command == "timesheet") { out = handleReportTimesheet (); }
|
||||
else if (cmd.command == "add") { out = handleAdd (); }
|
||||
else if (cmd.command == "append") { out = handleAppend (); }
|
||||
else if (cmd.command == "annotate") { out = handleAnnotate (); }
|
||||
else if (cmd.command == "done") { out = handleDone (); }
|
||||
else if (cmd.command == "delete") { out = handleDelete (); }
|
||||
else if (cmd.command == "start") { out = handleStart (); }
|
||||
else if (cmd.command == "stop") { out = handleStop (); }
|
||||
else if (cmd.command == "export") { out = handleExport (); }
|
||||
else if (cmd.command == "import") { out = handleImport (); }
|
||||
else if (cmd.command == "duplicate") { out = handleDuplicate (); }
|
||||
else if (cmd.command == "edit") { out = handleEdit (); }
|
||||
#ifdef FEATURE_SHELL
|
||||
else if (cmd.command == "shell") { handleShell (); }
|
||||
#endif
|
||||
else if (cmd.command == "undo") { handleUndo (); }
|
||||
else if (cmd.command == "_projects") { out = handleCompletionProjects (); }
|
||||
else if (cmd.command == "_tags") { out = handleCompletionTags (); }
|
||||
else if (cmd.command == "_commands") { out = handleCompletionCommands (); }
|
||||
else if (cmd.command == "_ids") { out = handleCompletionIDs (); }
|
||||
else if (cmd.command == "_config") { out = handleCompletionConfig (); }
|
||||
else if (cmd.command == "" &&
|
||||
sequence.size ()) { out = handleModify (); }
|
||||
|
||||
// Command that display IDs and therefore need TDB::gc first.
|
||||
else if (cmd.command == "next") { if (!inShadow) tdb.gc (); out = handleReportNext (); }
|
||||
else if (cmd.validCustom (cmd.command)) { if (!inShadow) tdb.gc (); out = handleCustomReport (cmd.command); }
|
||||
|
||||
// If the command is not recognized, display usage.
|
||||
else { out = shortUsage (); }
|
||||
|
||||
// Only update the shadow file if such an update was not suppressed (shadow),
|
||||
if (cmd.isWriteCommand () && !inShadow)
|
||||
shadow ();
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Context::shadow ()
|
||||
{
|
||||
// Determine if shadow file is enabled.
|
||||
std::string shadowFile = expandPath (config.get ("shadow.file"));
|
||||
if (shadowFile != "")
|
||||
{
|
||||
inShadow = true; // Prevents recursion in case shadow command writes.
|
||||
|
||||
// TODO Reinstate these checks.
|
||||
/*
|
||||
// Check for silly shadow file settings.
|
||||
if (shadowFile == dataLocation + "/pending.data")
|
||||
throw std::string ("Configuration variable 'shadow.file' is set to "
|
||||
"overwrite your pending tasks. Please change it.");
|
||||
|
||||
if (shadowFile == dataLocation + "/completed.data")
|
||||
throw std::string ("Configuration variable 'shadow.file' is set to "
|
||||
"overwrite your completed tasks. Please change it.");
|
||||
*/
|
||||
|
||||
std::string oldCurses = config.get ("curses");
|
||||
std::string oldColor = config.get ("color");
|
||||
config.set ("curses", "off");
|
||||
config.set ("color", "off");
|
||||
|
||||
clear ();
|
||||
|
||||
// Run report. Use shadow.command, using default.command as a fallback
|
||||
// with "list" as a default.
|
||||
std::string command = config.get ("shadow.command",
|
||||
config.get ("default.command", "list"));
|
||||
split (args, command, ' ');
|
||||
|
||||
initialize ();
|
||||
parse ();
|
||||
std::string result = dispatch ();
|
||||
std::ofstream out (shadowFile.c_str ());
|
||||
if (out.good ())
|
||||
{
|
||||
out << result;
|
||||
out.close ();
|
||||
}
|
||||
else
|
||||
throw std::string ("Could not write file '") + shadowFile + "'";
|
||||
|
||||
config.set ("curses", oldCurses);
|
||||
config.set ("color", oldColor);
|
||||
|
||||
// Optionally display a notification that the shadow file was updated.
|
||||
if (config.get (std::string ("shadow.notify"), false))
|
||||
footnote (std::string ("[Shadow file '") + shadowFile + "' updated]");
|
||||
|
||||
inShadow = false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Only allows aliases 10 deep.
|
||||
std::string Context::canonicalize (const std::string& input) const
|
||||
{
|
||||
std::string canonical = input;
|
||||
|
||||
// First try to autocomplete the alias.
|
||||
std::vector <std::string> options;
|
||||
std::vector <std::string> matches;
|
||||
foreach (name, aliases)
|
||||
options.push_back (name->first);
|
||||
|
||||
autoComplete (input, options, matches);
|
||||
if (matches.size () == 1)
|
||||
{
|
||||
canonical = matches[0];
|
||||
|
||||
// Follow the chain.
|
||||
int i = 10; // Safety valve.
|
||||
std::map <std::string, std::string>::const_iterator found;
|
||||
while ((found = aliases.find (canonical)) != aliases.end () && i-- > 0)
|
||||
canonical = found->second;
|
||||
|
||||
if (i < 1)
|
||||
return input;
|
||||
}
|
||||
|
||||
return canonical;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Context::loadCorrectConfigFile ()
|
||||
{
|
||||
// Set up default locations.
|
||||
struct passwd* pw = getpwuid (getuid ());
|
||||
if (!pw)
|
||||
throw std::string (
|
||||
stringtable.get (
|
||||
SHELL_READ_PASSWD,
|
||||
"Could not read home directory from the passwd file."));
|
||||
|
||||
std::string home = pw->pw_dir;
|
||||
std::string rc = home + "/.taskrc";
|
||||
std::string data = home + "/.task";
|
||||
|
||||
// Is there an override for rc?
|
||||
foreach (arg, args)
|
||||
{
|
||||
if (*arg == "--")
|
||||
break;
|
||||
else if (arg->substr (0, 3) == "rc:")
|
||||
{
|
||||
rc = arg->substr (3, std::string::npos);
|
||||
args.erase (arg);
|
||||
header ("Using alternate .taskrc file " + rc); // TODO i18n
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Load rc file.
|
||||
config.clear (); // Dump current values.
|
||||
config.setDefaults (); // Add in the custom reports.
|
||||
config.load (rc); // Load new file.
|
||||
|
||||
if (config.get ("data.location") != "")
|
||||
data = config.get ("data.location");
|
||||
|
||||
// Is there an override for data?
|
||||
foreach (arg, args)
|
||||
{
|
||||
if (*arg == "--")
|
||||
break;
|
||||
else if (arg->substr (0, 17) == "rc.data.location:")
|
||||
{
|
||||
data = arg->substr (17, std::string::npos);
|
||||
header ("Using alternate data.location " + data); // TODO i18n
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Do we need to create a default rc?
|
||||
if (access (rc.c_str (), F_OK) &&
|
||||
confirm ("A configuration file could not be found in " // TODO i18n
|
||||
+ home
|
||||
+ "\n\n"
|
||||
+ "Would you like a sample .taskrc created, so task can proceed?"))
|
||||
{
|
||||
config.createDefaultRC (rc, data);
|
||||
}
|
||||
|
||||
// Create data location, if necessary.
|
||||
config.createDefaultData (data);
|
||||
|
||||
// Load rc file.
|
||||
config.clear (); // Dump current values.
|
||||
config.setDefaults (); // Add in the custom reports.
|
||||
config.load (rc); // Load new file.
|
||||
|
||||
// Apply overrides of type: "rc.name:value"
|
||||
std::vector <std::string> filtered;
|
||||
bool foundTerminator = false;
|
||||
foreach (arg, args)
|
||||
{
|
||||
if (*arg == "--")
|
||||
{
|
||||
foundTerminator = true;
|
||||
filtered.push_back (*arg);
|
||||
}
|
||||
else if (!foundTerminator &&
|
||||
arg->substr (0, 3) == "rc.")
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
Nibbler n (*arg);
|
||||
if (n.getUntil ('.', name) &&
|
||||
n.skip ('.') &&
|
||||
n.getUntil (':', name) &&
|
||||
n.skip (':') &&
|
||||
n.getUntilEOS (value))
|
||||
{
|
||||
config.set (name, value);
|
||||
footnote (std::string ("Configuration override ") + // TODO i18n
|
||||
arg->substr (3, std::string::npos));
|
||||
}
|
||||
}
|
||||
else
|
||||
filtered.push_back (*arg);
|
||||
}
|
||||
|
||||
args = filtered;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Context::loadAliases ()
|
||||
{
|
||||
aliases.clear ();
|
||||
|
||||
std::vector <std::string> vars;
|
||||
config.all (vars);
|
||||
foreach (var, vars)
|
||||
{
|
||||
if (var->substr (0, 6) == "alias.")
|
||||
{
|
||||
std::string alias = var->substr (6, std::string::npos);
|
||||
std::string canonical = config.get (*var);
|
||||
|
||||
aliases[alias] = canonical;
|
||||
debug (std::string ("Alias ") + alias + " -> " + canonical);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Context::parse ()
|
||||
{
|
||||
parse (args, cmd, task, sequence, subst, filter);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Context::parse (
|
||||
std::vector <std::string>& parseArgs,
|
||||
Cmd& parseCmd,
|
||||
Task& parseTask,
|
||||
Sequence& parseSequence,
|
||||
Subst& parseSubst,
|
||||
Filter& parseFilter)
|
||||
{
|
||||
Timer t ("Context::parse");
|
||||
|
||||
Att attribute;
|
||||
tagAdditions.clear ();
|
||||
tagRemovals.clear ();
|
||||
std::string descCandidate = "";
|
||||
bool terminated = false;
|
||||
bool foundSequence = false;
|
||||
bool foundSomethingAfterSequence = false;
|
||||
|
||||
foreach (arg, parseArgs)
|
||||
{
|
||||
if (!terminated)
|
||||
{
|
||||
// The '--' argument shuts off all parsing - everything is an argument.
|
||||
if (*arg == "--")
|
||||
{
|
||||
debug ("parse terminator '" + *arg + "'");
|
||||
terminated = true;
|
||||
}
|
||||
|
||||
// Sequence
|
||||
// Note: "add" doesn't require an ID
|
||||
else if (parseCmd.command != "add" &&
|
||||
! foundSomethingAfterSequence &&
|
||||
parseSequence.valid (*arg))
|
||||
{
|
||||
debug ("parse sequence '" + *arg + "'");
|
||||
parseSequence.parse (*arg);
|
||||
foundSequence = true;
|
||||
}
|
||||
|
||||
// Tags to include begin with '+'.
|
||||
else if (arg->length () > 1 &&
|
||||
(*arg)[0] == '+' &&
|
||||
noSpaces (*arg))
|
||||
{
|
||||
debug ("parse tag addition '" + *arg + "'");
|
||||
if (foundSequence)
|
||||
foundSomethingAfterSequence = true;
|
||||
|
||||
if (arg->find (',') != std::string::npos)
|
||||
throw stringtable.get (TAGS_NO_COMMA,
|
||||
"Tags are not permitted to contain commas.");
|
||||
|
||||
tagAdditions.push_back (arg->substr (1, std::string::npos));
|
||||
parseTask.addTag (arg->substr (1, std::string::npos));
|
||||
}
|
||||
|
||||
// Tags to remove begin with '-'.
|
||||
else if (arg->length () > 1 &&
|
||||
(*arg)[0] == '-' &&
|
||||
noSpaces (*arg))
|
||||
{
|
||||
debug ("parse tag removal '" + *arg + "'");
|
||||
if (foundSequence)
|
||||
foundSomethingAfterSequence = true;
|
||||
|
||||
if (arg->find (',') != std::string::npos)
|
||||
throw stringtable.get (TAGS_NO_COMMA,
|
||||
"Tags are not permitted to contain commas.");
|
||||
|
||||
tagRemovals.push_back (arg->substr (1, std::string::npos));
|
||||
}
|
||||
|
||||
// Atributes - name[.mod]:[value]
|
||||
else if (attribute.valid (*arg))
|
||||
{
|
||||
debug ("parse attribute '" + *arg + "'");
|
||||
if (foundSequence)
|
||||
foundSomethingAfterSequence = true;
|
||||
|
||||
attribute.parse (*arg);
|
||||
|
||||
// There has to be a better way. And it starts with a fresh coffee.
|
||||
std::string name = attribute.name ();
|
||||
std::string mod = attribute.mod ();
|
||||
std::string value = attribute.value ();
|
||||
if (attribute.validNameValue (name, mod, value))
|
||||
{
|
||||
attribute.name (name);
|
||||
attribute.mod (mod);
|
||||
attribute.value (value);
|
||||
|
||||
parseTask[attribute.name ()] = attribute;
|
||||
}
|
||||
|
||||
// *arg has the appearance of an attribute (foo:bar), but isn't
|
||||
// recognized, so downgrade it to part of the description.
|
||||
else
|
||||
{
|
||||
if (foundSequence)
|
||||
foundSomethingAfterSequence = true;
|
||||
|
||||
if (descCandidate.length ())
|
||||
descCandidate += " ";
|
||||
descCandidate += *arg;
|
||||
}
|
||||
}
|
||||
|
||||
// Substitution of description and/or annotation text.
|
||||
else if (parseSubst.valid (*arg))
|
||||
{
|
||||
if (foundSequence)
|
||||
foundSomethingAfterSequence = true;
|
||||
|
||||
debug ("parse subst '" + *arg + "'");
|
||||
parseSubst.parse (*arg);
|
||||
}
|
||||
|
||||
// It might be a command if one has not already been found.
|
||||
else if (parseCmd.command == "" &&
|
||||
parseCmd.valid (*arg))
|
||||
{
|
||||
debug ("parse cmd '" + *arg + "'");
|
||||
parseCmd.parse (*arg);
|
||||
|
||||
if (foundSequence)
|
||||
foundSomethingAfterSequence = true;
|
||||
}
|
||||
|
||||
// Anything else is just considered description.
|
||||
else
|
||||
{
|
||||
if (foundSequence)
|
||||
foundSomethingAfterSequence = true;
|
||||
|
||||
if (descCandidate.length ())
|
||||
descCandidate += " ";
|
||||
descCandidate += *arg;
|
||||
}
|
||||
}
|
||||
|
||||
// Command is terminated, therefore everything subsequently is a description.
|
||||
else
|
||||
{
|
||||
debug ("parse post-termination description '" + *arg + "'");
|
||||
if (foundSequence)
|
||||
foundSomethingAfterSequence = true;
|
||||
|
||||
if (descCandidate.length ())
|
||||
descCandidate += " ";
|
||||
descCandidate += *arg;
|
||||
}
|
||||
}
|
||||
|
||||
if (descCandidate != "" && noVerticalSpace (descCandidate))
|
||||
{
|
||||
debug ("parse description '" + descCandidate + "'");
|
||||
parseTask.set ("description", descCandidate);
|
||||
}
|
||||
|
||||
// At this point, either a sequence or a command should have been found.
|
||||
if (parseSequence.size () == 0 && parseCmd.command == "")
|
||||
parseCmd.parse (descCandidate);
|
||||
|
||||
// Read-only command (reports, status, info ...) use filters. Write commands
|
||||
// (add, done ...) do not.
|
||||
if (parseCmd.isReadOnlyCommand ())
|
||||
autoFilter (parseTask, parseFilter);
|
||||
|
||||
// If no command was specified, and there were no command line arguments
|
||||
// then invoke the default command.
|
||||
if (parseCmd.command == "" && parseArgs.size () == 0)
|
||||
{
|
||||
std::string defaultCommand = config.get ("default.command");
|
||||
if (defaultCommand != "")
|
||||
{
|
||||
// Stuff the command line.
|
||||
parseArgs.clear ();
|
||||
split (parseArgs, defaultCommand, ' ');
|
||||
header ("[task " + defaultCommand + "]");
|
||||
|
||||
// Reinitialize the context and recurse.
|
||||
initialize ();
|
||||
parse (args, cmd, task, sequence, subst, filter);
|
||||
}
|
||||
else
|
||||
throw stringtable.get (
|
||||
CMD_MISSING,
|
||||
"You must specify a command, or a task ID to modify");
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Context::clear ()
|
||||
{
|
||||
// Config config;
|
||||
filter.clear ();
|
||||
// Keymap keymap;
|
||||
sequence.clear ();
|
||||
subst.clear ();
|
||||
// task.clear ();
|
||||
task = Task ();
|
||||
tdb.clear ();
|
||||
// stringtable.clear ();
|
||||
program = "";
|
||||
args.clear ();
|
||||
cmd.command = "";
|
||||
tagAdditions.clear ();
|
||||
tagRemovals.clear ();
|
||||
|
||||
clearMessages ();
|
||||
inShadow = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Add all the attributes in the task to the filter. All except uuid.
|
||||
void Context::autoFilter (Task& t, Filter& f)
|
||||
{
|
||||
foreach (att, t)
|
||||
{
|
||||
// Words are found in the description using the .has modifier.
|
||||
if (att->first == "description" && att->second.mod () == "")
|
||||
{
|
||||
std::vector <std::string> words;
|
||||
split (words, att->second.value (), ' ');
|
||||
foreach (word, words)
|
||||
{
|
||||
f.push_back (Att ("description", "has", *word));
|
||||
debug ("auto filter: " + att->first + ".has:" + *word);
|
||||
}
|
||||
}
|
||||
|
||||
// Projects are matched left-most.
|
||||
else if (att->first == "project" && att->second.mod () == "")
|
||||
{
|
||||
if (att->second.value () != "")
|
||||
{
|
||||
f.push_back (Att ("project", "startswith", att->second.value ()));
|
||||
debug ("auto filter: " + att->first + ".startswith:" + att->second.value ());
|
||||
}
|
||||
else
|
||||
{
|
||||
f.push_back (Att ("project", "is", att->second.value ()));
|
||||
debug ("auto filter: " + att->first + ".is:" + att->second.value ());
|
||||
}
|
||||
}
|
||||
|
||||
// The limit attribute does not participate in filtering, and needs to be
|
||||
// specifically handled in handleCustomReport.
|
||||
else if (att->first == "limit")
|
||||
{
|
||||
}
|
||||
|
||||
// Every task has a unique uuid by default, and it shouldn't be included,
|
||||
// because it is guaranteed to not match.
|
||||
else if (att->first == "uuid")
|
||||
{
|
||||
}
|
||||
|
||||
// The mechanism for filtering on tags is +/-<tag>.
|
||||
else if (att->first == "tags")
|
||||
{
|
||||
}
|
||||
|
||||
// Generic attribute matching.
|
||||
else
|
||||
{
|
||||
f.push_back (att->second);
|
||||
debug ("auto filter: " +
|
||||
att->first +
|
||||
(att->second.mod () != "" ?
|
||||
("." + att->second.mod () + ":") :
|
||||
":") +
|
||||
att->second.value ());
|
||||
}
|
||||
}
|
||||
|
||||
// Include tagAdditions.
|
||||
foreach (tag, tagAdditions)
|
||||
{
|
||||
f.push_back (Att ("tags", "has", *tag));
|
||||
debug ("auto filter: +" + *tag);
|
||||
}
|
||||
|
||||
// Include tagRemovals.
|
||||
foreach (tag, tagRemovals)
|
||||
{
|
||||
f.push_back (Att ("tags", "hasnt", *tag));
|
||||
debug ("auto filter: -" + *tag);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Context::header (const std::string& input)
|
||||
{
|
||||
headers.push_back (input);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Context::footnote (const std::string& input)
|
||||
{
|
||||
footnotes.push_back (input);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Context::debug (const std::string& input)
|
||||
{
|
||||
debugMessages.push_back (input);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Context::clearMessages ()
|
||||
{
|
||||
headers.clear ();
|
||||
footnotes.clear ();
|
||||
debugMessages.clear ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
98
src/Context.h
Normal file
98
src/Context.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_CONTEXT
|
||||
#define INCLUDED_CONTEXT
|
||||
|
||||
#include "Filter.h"
|
||||
#include "Keymap.h"
|
||||
#include "Config.h"
|
||||
#include "Sequence.h"
|
||||
#include "Subst.h"
|
||||
#include "Cmd.h"
|
||||
#include "Task.h"
|
||||
#include "TDB.h"
|
||||
#include "StringTable.h"
|
||||
|
||||
class Context
|
||||
{
|
||||
public:
|
||||
Context (); // Default constructor
|
||||
~Context (); // Destructor
|
||||
|
||||
Context (const Context&);
|
||||
Context& operator= (const Context&);
|
||||
|
||||
void initialize (int, char**); // all startup
|
||||
void initialize (); // for reinitializing
|
||||
int run (); // task classic
|
||||
int interactive (); // task interactive (not implemented)
|
||||
std::string dispatch (); // command handler dispatch
|
||||
void shadow (); // shadow file update
|
||||
|
||||
int getWidth (); // determine terminal width
|
||||
|
||||
void header (const std::string&); // Header message sink
|
||||
void footnote (const std::string&); // Footnote message sink
|
||||
void debug (const std::string&); // Debug message sink
|
||||
void clearMessages ();
|
||||
|
||||
void parse ();
|
||||
void parse (std::vector <std::string>&, Cmd&, Task&, Sequence&, Subst&, Filter&);
|
||||
void clear ();
|
||||
|
||||
std::string canonicalize (const std::string&) const;
|
||||
|
||||
private:
|
||||
void loadCorrectConfigFile ();
|
||||
void loadAliases ();
|
||||
void autoFilter (Task&, Filter&);
|
||||
|
||||
public:
|
||||
Config config;
|
||||
Filter filter;
|
||||
Keymap keymap;
|
||||
Sequence sequence;
|
||||
Subst subst;
|
||||
Task task;
|
||||
TDB tdb;
|
||||
StringTable stringtable;
|
||||
std::string program;
|
||||
std::vector <std::string> args;
|
||||
Cmd cmd;
|
||||
std::map <std::string, std::string> aliases;
|
||||
std::vector <std::string> tagAdditions;
|
||||
std::vector <std::string> tagRemovals;
|
||||
|
||||
private:
|
||||
std::vector <std::string> headers;
|
||||
std::vector <std::string> footnotes;
|
||||
std::vector <std::string> debugMessages;
|
||||
bool inShadow;
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
78
src/Date.cpp
78
src/Date.cpp
|
@ -25,11 +25,13 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "task.h"
|
||||
#include "Date.h"
|
||||
#include "text.h"
|
||||
#include "util.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Defaults to "now".
|
||||
|
@ -63,6 +65,10 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
|
|||
int day = 0;
|
||||
int year = 0;
|
||||
|
||||
// Perhaps it is an epoch date, in string form?
|
||||
if (isEpoch (mdy))
|
||||
return;
|
||||
|
||||
// Before parsing according to "format", perhaps this is a relative date?
|
||||
if (isRelativeDate (mdy))
|
||||
return;
|
||||
|
@ -179,6 +185,9 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
|
|||
}
|
||||
}
|
||||
|
||||
if (i < mdy.length ())
|
||||
throw std::string ("\"") + mdy + "\" is not a valid date in " + format + " format.";
|
||||
|
||||
if (!valid (month, day, year))
|
||||
throw std::string ("\"") + mdy + "\" is not a valid date.";
|
||||
|
||||
|
@ -208,6 +217,14 @@ time_t Date::toEpoch ()
|
|||
return mT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Date::toEpochString ()
|
||||
{
|
||||
std::stringstream epoch;
|
||||
epoch << mT;
|
||||
return epoch.str ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Date::toEpoch (time_t& epoch)
|
||||
{
|
||||
|
@ -253,6 +270,22 @@ const std::string Date::toString (const std::string& format /*= "m/d/Y" */) cons
|
|||
return formatted;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Date::valid (const std::string& input, const std::string& format)
|
||||
{
|
||||
try
|
||||
{
|
||||
Date test (input, format);
|
||||
}
|
||||
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Date::valid (const int m, const int d, const int y)
|
||||
{
|
||||
|
@ -277,9 +310,11 @@ bool Date::leapYear (int year)
|
|||
{
|
||||
bool ly = false;
|
||||
|
||||
if (!(year % 4)) ly = true;
|
||||
else if (!(year % 400)) ly = true;
|
||||
else if (!(year % 100)) ly = false;
|
||||
// (year % 4 == 0) && (year % 100 !=0) OR
|
||||
// (year % 400 == 0)
|
||||
// are leapyears
|
||||
|
||||
if (((!(year % 4)) && (year % 100)) || (!(year % 400))) ly = true;
|
||||
|
||||
return ly;
|
||||
}
|
||||
|
@ -354,6 +389,28 @@ std::string Date::dayName (int dow)
|
|||
return days[dow];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Date::weekOfYear (int weekStart) const
|
||||
{
|
||||
struct tm* t = localtime (&mT);
|
||||
char weekStr[3];
|
||||
|
||||
if (weekStart == 0)
|
||||
strftime(weekStr, sizeof(weekStr), "%U", t);
|
||||
else if (weekStart == 1)
|
||||
strftime(weekStr, sizeof(weekStr), "%V", t);
|
||||
else
|
||||
throw std::string ("The 'weekstart' configuration variable may "
|
||||
"only contain 'Sunday' or 'Monday'.");
|
||||
|
||||
int weekNumber = ::atoi (weekStr);
|
||||
|
||||
if (weekStart == 0)
|
||||
weekNumber += 1;
|
||||
|
||||
return weekNumber;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Date::dayOfWeek () const
|
||||
{
|
||||
|
@ -490,6 +547,19 @@ time_t Date::operator- (const Date& rhs)
|
|||
return mT - rhs.mT;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Date::isEpoch (const std::string& input)
|
||||
{
|
||||
if (digitsOnly (input) &&
|
||||
input.length () > 8)
|
||||
{
|
||||
mT = (time_t) ::atoi (input.c_str ());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// If the input string looks like a relative date, determine that date, set mT
|
||||
// and return true.
|
||||
|
|
|
@ -44,8 +44,10 @@ public:
|
|||
|
||||
void toEpoch (time_t&);
|
||||
time_t toEpoch ();
|
||||
std::string toEpochString ();
|
||||
void toMDY (int&, int&, int&);
|
||||
const std::string toString (const std::string& format = "m/d/Y") const;
|
||||
static bool valid (const std::string&, const std::string& format = "m/d/Y");
|
||||
static bool valid (const int, const int, const int);
|
||||
|
||||
static bool leapYear (int);
|
||||
|
@ -53,11 +55,13 @@ public:
|
|||
static std::string monthName (int);
|
||||
static void dayName (int, std::string&);
|
||||
static std::string dayName (int);
|
||||
static int weekOfYear (const std::string&);
|
||||
static int dayOfWeek (const std::string&);
|
||||
|
||||
int month () const;
|
||||
int day () const;
|
||||
int year () const;
|
||||
int weekOfYear (int) const;
|
||||
int dayOfWeek () const;
|
||||
|
||||
bool operator== (const Date&);
|
||||
|
@ -77,6 +81,7 @@ public:
|
|||
time_t operator- (const Date&);
|
||||
|
||||
private:
|
||||
bool isEpoch (const std::string&);
|
||||
bool isRelativeDate (const std::string&);
|
||||
|
||||
protected:
|
||||
|
|
205
src/Duration.cpp
Normal file
205
src/Duration.cpp
Normal file
|
@ -0,0 +1,205 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
#include "text.h"
|
||||
#include "util.h"
|
||||
#include "Duration.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Duration::Duration ()
|
||||
: mDays (0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Duration::Duration (time_t input)
|
||||
{
|
||||
mDays = input;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Duration::Duration (const std::string& input)
|
||||
{
|
||||
parse (input);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Duration::operator int ()
|
||||
{
|
||||
return (int) mDays;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Duration::operator time_t ()
|
||||
{
|
||||
return mDays;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Duration::operator std::string ()
|
||||
{
|
||||
std::stringstream s;
|
||||
s << mDays;
|
||||
return s.str ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Duration::operator< (const Duration& other)
|
||||
{
|
||||
return mDays < other.mDays;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Duration::operator> (const Duration& other)
|
||||
{
|
||||
return mDays > other.mDays;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Duration::~Duration ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Duration::valid (const std::string& input) const
|
||||
{
|
||||
std::string lower_input = lowerCase (input);
|
||||
|
||||
std::vector <std::string> supported;
|
||||
supported.push_back ("daily"); // TODO i18n
|
||||
supported.push_back ("day"); // TODO i18n
|
||||
supported.push_back ("weekly"); // TODO i18n
|
||||
supported.push_back ("weekdays"); // TODO i18n
|
||||
supported.push_back ("sennight"); // TODO i18n
|
||||
supported.push_back ("biweekly"); // TODO i18n
|
||||
supported.push_back ("fortnight"); // TODO i18n
|
||||
supported.push_back ("monthly"); // TODO i18n
|
||||
supported.push_back ("bimonthly"); // TODO i18n
|
||||
supported.push_back ("quarterly"); // TODO i18n
|
||||
supported.push_back ("biannual"); // TODO i18n
|
||||
supported.push_back ("biyearly"); // TODO i18n
|
||||
supported.push_back ("annual"); // TODO i18n
|
||||
supported.push_back ("semiannual"); // TODO i18n
|
||||
supported.push_back ("yearly"); // TODO i18n
|
||||
|
||||
std::vector <std::string> matches;
|
||||
if (autoComplete (lower_input, supported, matches) == 1)
|
||||
return true;
|
||||
|
||||
// Support \d+ d|w|m|q|y
|
||||
// Verify all digits followed by d, w, m, q, or y.
|
||||
unsigned int length = lower_input.length ();
|
||||
for (unsigned int i = 0; i < length; ++i)
|
||||
{
|
||||
if (! isdigit (lower_input[i]) &&
|
||||
i == length - 1)
|
||||
{
|
||||
std::string type = lower_input.substr (length - 1, std::string::npos);
|
||||
if (type == "d" || // TODO i18n
|
||||
type == "w" || // TODO i18n
|
||||
type == "m" || // TODO i18n
|
||||
type == "q" || // TODO i18n
|
||||
type == "y") // TODO i18n
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Duration::parse (const std::string& input)
|
||||
{
|
||||
std::string lower_input = lowerCase (input);
|
||||
|
||||
std::vector <std::string> supported;
|
||||
supported.push_back ("daily"); // TODO i18n
|
||||
supported.push_back ("day"); // TODO i18n
|
||||
supported.push_back ("weekly"); // TODO i18n
|
||||
supported.push_back ("weekdays"); // TODO i18n
|
||||
supported.push_back ("sennight"); // TODO i18n
|
||||
supported.push_back ("biweekly"); // TODO i18n
|
||||
supported.push_back ("fortnight"); // TODO i18n
|
||||
supported.push_back ("monthly"); // TODO i18n
|
||||
supported.push_back ("bimonthly"); // TODO i18n
|
||||
supported.push_back ("quarterly"); // TODO i18n
|
||||
supported.push_back ("biannual"); // TODO i18n
|
||||
supported.push_back ("biyearly"); // TODO i18n
|
||||
supported.push_back ("annual"); // TODO i18n
|
||||
supported.push_back ("semiannual"); // TODO i18n
|
||||
supported.push_back ("yearly"); // TODO i18n
|
||||
|
||||
std::vector <std::string> matches;
|
||||
if (autoComplete (lower_input, supported, matches) == 1)
|
||||
{
|
||||
std::string found = matches[0];
|
||||
|
||||
if (found == "daily" || found == "day") mDays = 1; // TODO i18n
|
||||
else if (found == "weekdays") mDays = 1; // TODO i18n
|
||||
else if (found == "weekly" || found == "sennight") mDays = 7; // TODO i18n
|
||||
else if (found == "biweekly" || found == "fortnight") mDays = 14; // TODO i18n
|
||||
else if (found == "monthly") mDays = 30; // TODO i18n
|
||||
else if (found == "bimonthly") mDays = 61; // TODO i18n
|
||||
else if (found == "quarterly") mDays = 91; // TODO i18n
|
||||
else if (found == "semiannual") mDays = 183; // TODO i18n
|
||||
else if (found == "yearly" || found == "annual") mDays = 365; // TODO i18n
|
||||
else if (found == "biannual" || found == "biyearly") mDays = 730; // TODO i18n
|
||||
}
|
||||
|
||||
// Support \d+ d|w|m|q|y
|
||||
else
|
||||
{
|
||||
// Verify all digits followed by d, w, m, q, or y.
|
||||
unsigned int length = lower_input.length ();
|
||||
for (unsigned int i = 0; i < length; ++i)
|
||||
{
|
||||
if (! isdigit (lower_input[i]) &&
|
||||
i == length - 1)
|
||||
{
|
||||
int number = ::atoi (lower_input.substr (0, i).c_str ());
|
||||
|
||||
switch (lower_input[length - 1])
|
||||
{
|
||||
case 'd': mDays = number * 1; break; // TODO i18n
|
||||
case 'w': mDays = number * 7; break; // TODO i18n
|
||||
case 'm': mDays = number * 30; break; // TODO i18n
|
||||
case 'q': mDays = number * 91; break; // TODO i18n
|
||||
case 'y': mDays = number * 365; break; // TODO i18n
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mDays == 0)
|
||||
throw std::string ("The duration '") + input + "' was not recognized."; // TODO i18n
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
55
src/Duration.h
Normal file
55
src/Duration.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_DURATION
|
||||
#define INCLUDED_DURATION
|
||||
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
|
||||
class Duration
|
||||
{
|
||||
public:
|
||||
Duration (); // Default constructor
|
||||
Duration (time_t); // Default constructor
|
||||
Duration (const std::string&); // Parse
|
||||
bool operator< (const Duration&);
|
||||
bool operator> (const Duration&);
|
||||
~Duration (); // Destructor
|
||||
|
||||
operator int ();
|
||||
operator time_t ();
|
||||
operator std::string ();
|
||||
|
||||
bool valid (const std::string&) const;
|
||||
void parse (const std::string&);
|
||||
|
||||
private:
|
||||
time_t mDays;
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
134
src/Filter.cpp
Normal file
134
src/Filter.cpp
Normal file
|
@ -0,0 +1,134 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <sstream>
|
||||
#include "Filter.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// For every Att in the filter, lookup the equivalent in Record, and perform a
|
||||
// match. Aren't filters easy now that everything is an attribute?
|
||||
bool Filter::pass (const Record& record) const
|
||||
{
|
||||
Record::const_iterator r;
|
||||
|
||||
// First do description/annotation matches.
|
||||
foreach (att, (*this))
|
||||
{
|
||||
// Descriptions have special handling.
|
||||
if (att->name () == "description")
|
||||
{
|
||||
if ((r = record.find (att->name ())) != record.end ())
|
||||
{
|
||||
// A description match failure can be salvaged by an annotation match.
|
||||
if (! att->match (r->second))
|
||||
{
|
||||
bool annoMatch = false;
|
||||
foreach (ra, record)
|
||||
{
|
||||
if (ra->first.length () > 11 &&
|
||||
ra->first.substr (0, 11) == "annotation_")
|
||||
{
|
||||
if (att->match (ra->second))
|
||||
{
|
||||
annoMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!annoMatch)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (! att->match (Att ()))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Annotations are skipped.
|
||||
else if (att->name ().length () > 11 &&
|
||||
att->name ().substr (0, 11) == "annotation_")
|
||||
{
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// An individual attribute match failure is enough to fail the filter.
|
||||
if ((r = record.find (att->name ())) != record.end ())
|
||||
{
|
||||
if (! att->match (r->second))
|
||||
return false;
|
||||
}
|
||||
else if (! att->match (Att ()))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Filter::applySequence (std::vector<Task>& all, Sequence& sequence)
|
||||
{
|
||||
std::vector <Task> filtered;
|
||||
foreach (task, all)
|
||||
foreach (i, sequence)
|
||||
if (task->id == *i)
|
||||
filtered.push_back (*task);
|
||||
|
||||
if (sequence.size () != filtered.size ())
|
||||
{
|
||||
std::vector <int> filteredSequence;
|
||||
foreach (task, filtered)
|
||||
filteredSequence.push_back (task->id);
|
||||
|
||||
std::vector <int> left;
|
||||
std::vector <int> right;
|
||||
listDiff (filteredSequence, (std::vector <int>&)sequence, left, right);
|
||||
if (left.size ())
|
||||
throw std::string ("Sequence filtering error - please report this error");
|
||||
|
||||
if (right.size ())
|
||||
{
|
||||
std::stringstream out;
|
||||
out << "Task";
|
||||
|
||||
if (right.size () > 1) out << "s";
|
||||
|
||||
foreach (r, right)
|
||||
out << " " << *r;
|
||||
|
||||
out << " not found";
|
||||
throw out.str ();
|
||||
}
|
||||
}
|
||||
|
||||
all = filtered;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
43
src/Filter.h
Normal file
43
src/Filter.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_FILTER
|
||||
#define INCLUDED_FILTER
|
||||
|
||||
#include <vector>
|
||||
#include "Att.h"
|
||||
#include "Task.h"
|
||||
#include "Record.h"
|
||||
|
||||
class Filter : public std::vector <Att>
|
||||
{
|
||||
public:
|
||||
bool pass (const Record&) const;
|
||||
void applySequence (std::vector<Task>&, Sequence&);
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
|
@ -306,7 +306,7 @@ Grid::Cell::operator char () const
|
|||
{
|
||||
switch (mType)
|
||||
{
|
||||
case CELL_BOOL: return mBool ? 'Y' : 'N';
|
||||
case CELL_BOOL: return mBool ? 'Y' : 'N'; // TODO i18n
|
||||
case CELL_CHAR: return mChar;
|
||||
case CELL_INT: return (char) mInt;
|
||||
case CELL_FLOAT: return (char) (int) mFloat;
|
||||
|
@ -368,7 +368,7 @@ Grid::Cell::operator std::string () const
|
|||
|
||||
switch (mType)
|
||||
{
|
||||
case CELL_BOOL: return mBool ? "true" : "false";
|
||||
case CELL_BOOL: return mBool ? "true" : "false"; // TODO i18n
|
||||
case CELL_CHAR: sprintf (s, "%c", mChar);
|
||||
return std::string (s);
|
||||
case CELL_INT: sprintf (s, "%d", mInt);
|
||||
|
|
|
@ -45,6 +45,9 @@ public:
|
|||
Cell (const double);
|
||||
Cell (const std::string&);
|
||||
|
||||
Cell (const Cell&);
|
||||
Cell& operator= (const Cell&);
|
||||
|
||||
operator bool () const;
|
||||
operator char () const;
|
||||
operator int () const;
|
||||
|
@ -72,6 +75,9 @@ public:
|
|||
Grid ();
|
||||
~Grid ();
|
||||
|
||||
Grid (const Grid&);
|
||||
Grid& operator= (const Grid&);
|
||||
|
||||
void add (const unsigned int, const unsigned int, const bool);
|
||||
void add (const unsigned int, const unsigned int, const char);
|
||||
void add (const unsigned int, const unsigned int, const int);
|
||||
|
|
66
src/Keymap.cpp
Normal file
66
src/Keymap.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <string>
|
||||
#include "Keymap.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Keymap::Keymap ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Keymap::Keymap (const Keymap& other)
|
||||
{
|
||||
throw std::string ("unimplemented Keymap::Keymap");
|
||||
// mOne = other.mOne;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Keymap& Keymap::operator= (const Keymap& other)
|
||||
{
|
||||
throw std::string ("unimplemented Keymap::operator=");
|
||||
if (this != &other)
|
||||
{
|
||||
// mOne = other.mOne;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Keymap::~Keymap ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Keymap::load (const std::string& file)
|
||||
{
|
||||
throw std::string ("unimplemented Keymap::load");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
51
src/Keymap.h
Normal file
51
src/Keymap.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_KEYMAP
|
||||
#define INCLUDED_KEYMAP
|
||||
|
||||
#include <string>
|
||||
|
||||
class Keymap
|
||||
{
|
||||
public:
|
||||
Keymap (); // Default constructor
|
||||
Keymap (const Keymap&); // Copy constructor
|
||||
Keymap& operator= (const Keymap&); // Assignment operator
|
||||
~Keymap (); // Destructor
|
||||
|
||||
void load (const std::string&); // Load the map file
|
||||
/*
|
||||
real (); // Convert soft to real
|
||||
soft (); // Convert real to soft
|
||||
*/
|
||||
|
||||
private:
|
||||
// TODO Structure for mapping strings to keys.
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
73
src/Location.cpp
Normal file
73
src/Location.cpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Location.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Location::Location ()
|
||||
: path ("")
|
||||
, pending (NULL)
|
||||
, completed (NULL)
|
||||
, undo (NULL)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Location::Location (const std::string& p)
|
||||
: path (p)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Location::Location (const Location& other)
|
||||
{
|
||||
path = other.path;
|
||||
pending = other.pending;
|
||||
completed = other.completed;
|
||||
undo = other.undo;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Location& Location::operator= (const Location& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
path = other.path;
|
||||
pending = other.pending;
|
||||
completed = other.completed;
|
||||
undo = other.undo;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Location::~Location ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
50
src/Location.h
Normal file
50
src/Location.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_LOCATION
|
||||
#define INCLUDED_LOCATION
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
|
||||
class Location
|
||||
{
|
||||
public:
|
||||
Location (); // Default constructor
|
||||
Location (const std::string&); // Default constructor
|
||||
Location (const Location&); // Copy constructor
|
||||
Location& operator= (const Location&); // Assignment operator
|
||||
~Location (); // Destructor
|
||||
|
||||
public:
|
||||
std::string path;
|
||||
FILE* pending;
|
||||
FILE* completed;
|
||||
FILE* undo;
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
|
@ -1,2 +1,11 @@
|
|||
bin_PROGRAMS = task
|
||||
task_SOURCES = Config.cpp Date.cpp T.cpp TDB.cpp Table.cpp Grid.cpp Timer.cpp color.cpp parse.cpp task.cpp command.cpp edit.cpp report.cpp util.cpp text.cpp rules.cpp import.cpp Config.h Date.h T.h TDB.h Table.h Grid.h Timer.h color.h task.h
|
||||
task_SOURCES = Att.cpp Cmd.cpp Config.cpp Context.cpp Date.cpp Duration.cpp \
|
||||
Filter.cpp Grid.cpp Keymap.cpp Location.cpp Nibbler.cpp \
|
||||
Record.cpp Sequence.cpp StringTable.cpp Subst.cpp Task.cpp \
|
||||
TDB.cpp Table.cpp Timer.cpp Permission.cpp color.cpp edit.cpp \
|
||||
command.cpp import.cpp interactive.cpp recur.cpp report.cpp \
|
||||
custom.cpp rules.cpp main.cpp text.cpp util.cpp \
|
||||
Att.h Cmd.h Config.h Context.h Date.h Duration.h Filter.h \
|
||||
Grid.h Keymap.h Location.h Nibbler.h Record.h Sequence.h \
|
||||
StringTable.h Subst.h Task.h TDB.h Table.h Timer.h \
|
||||
Permission.h color.h i18n.h main.h text.h util.h
|
||||
|
|
304
src/Nibbler.cpp
Normal file
304
src/Nibbler.cpp
Normal file
|
@ -0,0 +1,304 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include "Nibbler.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Nibbler::Nibbler ()
|
||||
: mInput ("")
|
||||
, mCursor (0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Nibbler::Nibbler (const char* input)
|
||||
: mInput (input)
|
||||
, mCursor (0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Nibbler::Nibbler (const std::string& input)
|
||||
: mInput (input)
|
||||
, mCursor (0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Nibbler::Nibbler (const Nibbler& other)
|
||||
{
|
||||
mInput = other.mInput;
|
||||
mCursor = other.mCursor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Nibbler& Nibbler::operator= (const Nibbler& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
mInput = other.mInput;
|
||||
mCursor = other.mCursor;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Nibbler::~Nibbler ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Extract up until the next c, or EOS.
|
||||
bool Nibbler::getUntil (char c, std::string& result)
|
||||
{
|
||||
if (mCursor < mInput.length ())
|
||||
{
|
||||
std::string::size_type i = mInput.find (c, mCursor);
|
||||
if (i != std::string::npos)
|
||||
{
|
||||
result = mInput.substr (mCursor, i - mCursor);
|
||||
mCursor = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = mInput.substr (mCursor, std::string::npos);
|
||||
mCursor = mInput.length ();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Nibbler::getUntil (const std::string& terminator, std::string& result)
|
||||
{
|
||||
if (mCursor < mInput.length ())
|
||||
{
|
||||
std::string::size_type i = mInput.find (terminator, mCursor);
|
||||
if (i != std::string::npos)
|
||||
{
|
||||
result = mInput.substr (mCursor, i - mCursor);
|
||||
mCursor = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = mInput.substr (mCursor, std::string::npos);
|
||||
mCursor = mInput.length ();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Nibbler::getUntilOneOf (const std::string& chars, std::string& result)
|
||||
{
|
||||
if (mCursor < mInput.length ())
|
||||
{
|
||||
std::string::size_type i = mInput.find_first_of (chars, mCursor);
|
||||
if (i != std::string::npos)
|
||||
{
|
||||
result = mInput.substr (mCursor, i - mCursor);
|
||||
mCursor = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = mInput.substr (mCursor, std::string::npos);
|
||||
mCursor = mInput.length ();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Nibbler::skipN (const int quantity /* = 1 */)
|
||||
{
|
||||
if (mCursor >= mInput.length ())
|
||||
return false;
|
||||
|
||||
if (mCursor <= mInput.length () - quantity)
|
||||
{
|
||||
mCursor += quantity;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Nibbler::skip (char c)
|
||||
{
|
||||
if (mCursor < mInput.length () &&
|
||||
mInput[mCursor] == c)
|
||||
{
|
||||
++mCursor;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Nibbler::skipAll (char c)
|
||||
{
|
||||
std::string::size_type i = mCursor;
|
||||
while (i < mInput.length () && mInput[i] == c)
|
||||
++i;
|
||||
|
||||
if (i != mCursor)
|
||||
{
|
||||
mCursor = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Nibbler::skipAllOneOf (const std::string& chars)
|
||||
{
|
||||
if (mCursor < mInput.length ())
|
||||
{
|
||||
std::string::size_type i = mInput.find_first_not_of (chars, mCursor);
|
||||
if (i == mCursor)
|
||||
return false;
|
||||
|
||||
if (i == std::string::npos)
|
||||
mCursor = mInput.length (); // Yes, off the end.
|
||||
else
|
||||
mCursor = i;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Nibbler::getQuoted (char c, std::string& result)
|
||||
{
|
||||
std::string::size_type start = mCursor;
|
||||
if (start < mInput.length () && mInput[start] == c)
|
||||
{
|
||||
++start;
|
||||
if (start < mInput.length ())
|
||||
{
|
||||
std::string::size_type end = mInput.find (c, start);
|
||||
if (end != std::string::npos)
|
||||
{
|
||||
result = mInput.substr (start, end - start);
|
||||
mCursor = end + 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Nibbler::getInt (int& result)
|
||||
{
|
||||
std::string::size_type i = mCursor;
|
||||
|
||||
if (i < mInput.length ())
|
||||
{
|
||||
if (mInput[i] == '-')
|
||||
++i;
|
||||
else if (mInput[i] == '+')
|
||||
++i;
|
||||
}
|
||||
|
||||
while (i < mInput.length () && ::isdigit (mInput[i]))
|
||||
++i;
|
||||
|
||||
if (i > mCursor)
|
||||
{
|
||||
result = ::atoi (mInput.substr (mCursor, i - mCursor).c_str ());
|
||||
mCursor = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Nibbler::getUnsignedInt (int& result)
|
||||
{
|
||||
std::string::size_type i = mCursor;
|
||||
while (i < mInput.length () && ::isdigit (mInput[i]))
|
||||
++i;
|
||||
|
||||
if (i > mCursor)
|
||||
{
|
||||
result = ::atoi (mInput.substr (mCursor, i - mCursor).c_str ());
|
||||
mCursor = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Nibbler::getUntilEOL (std::string& result)
|
||||
{
|
||||
return getUntil ('\n', result);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Nibbler::getUntilEOS (std::string& result)
|
||||
{
|
||||
if (mCursor < mInput.length ())
|
||||
{
|
||||
result = mInput.substr (mCursor, std::string::npos);
|
||||
mCursor = mInput.length ();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Nibbler::depleted ()
|
||||
{
|
||||
if (mCursor >= mInput.length ())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
62
src/Nibbler.h
Normal file
62
src/Nibbler.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_NIBBLER
|
||||
#define INCLUDED_NIBBLER
|
||||
|
||||
#include <string>
|
||||
|
||||
class Nibbler
|
||||
{
|
||||
public:
|
||||
Nibbler (); // Default constructor
|
||||
Nibbler (const char*); // Constructor
|
||||
Nibbler (const std::string&); // Constructor
|
||||
Nibbler (const Nibbler&); // Copy constructor
|
||||
Nibbler& operator= (const Nibbler&); // Assignment operator
|
||||
~Nibbler (); // Destructor
|
||||
|
||||
bool getUntil (char, std::string&);
|
||||
bool getUntil (const std::string&, std::string&);
|
||||
bool getUntilOneOf (const std::string&, std::string&);
|
||||
bool skipN (const int quantity = 1);
|
||||
bool skip (char);
|
||||
bool skipAll (char);
|
||||
bool skipAllOneOf (const std::string&);
|
||||
bool getQuoted (char, std::string&);
|
||||
bool getInt (int&);
|
||||
bool getUnsignedInt (int&i);
|
||||
bool getUntilEOL (std::string&);
|
||||
bool getUntilEOS (std::string&);
|
||||
bool depleted ();
|
||||
|
||||
private:
|
||||
std::string mInput;
|
||||
std::string::size_type mCursor;
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
74
src/Permission.cpp
Normal file
74
src/Permission.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <iostream>
|
||||
#include "Permission.h"
|
||||
#include "Context.h"
|
||||
#include "util.h"
|
||||
#include "i18n.h"
|
||||
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Permission::Permission ()
|
||||
: needConfirmation (false)
|
||||
, allConfirmed (false)
|
||||
{
|
||||
// Turning confirmations off is the same as entering "all".
|
||||
if (context.config.get ("confirmation", true) == false)
|
||||
allConfirmed = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Permission::confirmed (const Task& task, const std::string& question)
|
||||
{
|
||||
if (!needConfirmation)
|
||||
return true;
|
||||
|
||||
if (allConfirmed)
|
||||
return true;
|
||||
|
||||
std::cout << std::endl
|
||||
<< "Task "
|
||||
<< task.id
|
||||
<< " \""
|
||||
<< task.get ("description")
|
||||
<< "\""
|
||||
<< std::endl;
|
||||
|
||||
int answer = confirm3 (question);
|
||||
if (answer == 2)
|
||||
allConfirmed = true;
|
||||
|
||||
if (answer > 0)
|
||||
return true;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
50
src/Permission.h
Normal file
50
src/Permission.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_PERMISSION
|
||||
#define INCLUDED_PERMISSION
|
||||
|
||||
#include <string>
|
||||
#include "Task.h"
|
||||
|
||||
class Permission
|
||||
{
|
||||
public:
|
||||
Permission ();
|
||||
Permission (const Permission&);
|
||||
Permission& operator= (const Permission&);
|
||||
|
||||
void bigChange () { needConfirmation = true; }
|
||||
void bigSequence () { needConfirmation = true; }
|
||||
bool confirmed (const Task&, const std::string&);
|
||||
|
||||
private:
|
||||
bool needConfirmation;
|
||||
bool allConfirmed;
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
183
src/Record.cpp
Normal file
183
src/Record.cpp
Normal file
|
@ -0,0 +1,183 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
#include "Nibbler.h"
|
||||
#include "Context.h"
|
||||
#include "i18n.h"
|
||||
#include "Record.h"
|
||||
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Record::Record ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Record::Record (const std::string& input)
|
||||
{
|
||||
parse (input);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Record::~Record ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The format is:
|
||||
//
|
||||
// [ Att::composeF4 ... ] \n
|
||||
//
|
||||
std::string Record::composeF4 () const
|
||||
{
|
||||
std::string ff4 = "[";
|
||||
|
||||
bool first = true;
|
||||
std::map <std::string, Att>::const_iterator it;
|
||||
for (it = this->begin (); it != this->end (); ++it)
|
||||
{
|
||||
if (it->second.value () != "")
|
||||
{
|
||||
ff4 += (first ? "" : " ") + it->second.composeF4 ();
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
ff4 += "]\n";
|
||||
return ff4;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// start --> [ --> Att --> ] --> end
|
||||
// ^ |
|
||||
// +-------+
|
||||
//
|
||||
void Record::parse (const std::string& input)
|
||||
{
|
||||
clear ();
|
||||
|
||||
Nibbler n (input);
|
||||
std::string line;
|
||||
if (n.skip ('[') &&
|
||||
n.getUntil (']', line) &&
|
||||
n.skip (']') &&
|
||||
n.depleted ())
|
||||
{
|
||||
if (line.length () == 0)
|
||||
throw context.stringtable.get (RECORD_EMPTY,
|
||||
"Empty record in input");
|
||||
|
||||
Nibbler nl (line);
|
||||
Att a;
|
||||
while (!nl.depleted ())
|
||||
{
|
||||
a.parse (nl);
|
||||
(*this)[a.name ()] = a;
|
||||
nl.skip (' ');
|
||||
}
|
||||
|
||||
std::string remainder;
|
||||
nl.getUntilEOS (remainder);
|
||||
if (remainder.length ())
|
||||
throw context.stringtable.get (RECORD_EXTRA,
|
||||
"Unrecognized characters at end of line");
|
||||
}
|
||||
else
|
||||
throw context.stringtable.get (RECORD_NOT_FF4,
|
||||
"Record not recognized as format 4");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Record::has (const std::string& name) const
|
||||
{
|
||||
Record::const_iterator i = this->find (name);
|
||||
if (i != this->end ())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::vector <Att> Record::all ()
|
||||
{
|
||||
std::vector <Att> all;
|
||||
foreach (a, (*this))
|
||||
all.push_back (a->second);
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const std::string Record::get (const std::string& name) const
|
||||
{
|
||||
Record::const_iterator i = this->find (name);
|
||||
if (i != this->end ())
|
||||
return i->second.value ();
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Record::get_int (const std::string& name) const
|
||||
{
|
||||
Record::const_iterator i = this->find (name);
|
||||
if (i != this->end ())
|
||||
return ::atoi (i->second.value ().c_str ());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Record::set (const std::string& name, const std::string& value)
|
||||
{
|
||||
(*this)[name] = Att (name, value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Record::set (const std::string& name, int value)
|
||||
{
|
||||
std::stringstream svalue;
|
||||
svalue << value;
|
||||
|
||||
(*this)[name] = Att (name, svalue.str ());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Record::remove (const std::string& name)
|
||||
{
|
||||
Record::iterator it;
|
||||
if ((it = this->find (name)) != this->end ())
|
||||
this->erase (it);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
56
src/Record.h
Normal file
56
src/Record.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_RECORD
|
||||
#define INCLUDED_RECORD
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "Att.h"
|
||||
|
||||
class Record : public std::map <std::string, Att>
|
||||
{
|
||||
public:
|
||||
Record (); // Default constructor
|
||||
Record (const std::string&); // Copy constructor
|
||||
virtual ~Record (); // Destructor
|
||||
|
||||
std::string composeF4 () const;
|
||||
std::string composeCSV () const;
|
||||
void parse (const std::string&);
|
||||
|
||||
bool has (const std::string&) const;
|
||||
std::vector <Att> all ();
|
||||
const std::string get (const std::string&) const;
|
||||
int get_int (const std::string&) const;
|
||||
void set (const std::string&, const std::string&);
|
||||
void set (const std::string&, int);
|
||||
void remove (const std::string&);
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
162
src/Sequence.cpp
Normal file
162
src/Sequence.cpp
Normal file
|
@ -0,0 +1,162 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <ctype.h>
|
||||
#include "util.h"
|
||||
#include "text.h"
|
||||
#include "i18n.h"
|
||||
#include "Context.h"
|
||||
#include "Sequence.h"
|
||||
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Sequence::Sequence ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Sequence::Sequence (const std::string& input)
|
||||
{
|
||||
parse (input);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Sequence::~Sequence ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Sequence::valid (const std::string& input) const
|
||||
{
|
||||
std::vector <std::string> ranges;
|
||||
split (ranges, input, ',');
|
||||
|
||||
std::vector <std::string>::iterator it;
|
||||
for (it = ranges.begin (); it != ranges.end (); ++it)
|
||||
{
|
||||
std::vector <std::string> range;
|
||||
split (range, *it, '-');
|
||||
|
||||
if (range.size () < 1 ||
|
||||
range.size () > 2)
|
||||
return false;
|
||||
|
||||
if (range.size () <= 2 && !validId (range[0]))
|
||||
return false;
|
||||
|
||||
if (range.size () == 2 && !validId (range[1]))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Sequence::parse (const std::string& input)
|
||||
{
|
||||
std::vector <std::string> ranges;
|
||||
split (ranges, input, ',');
|
||||
|
||||
std::vector <std::string>::iterator it;
|
||||
for (it = ranges.begin (); it != ranges.end (); ++it)
|
||||
{
|
||||
std::vector <std::string> range;
|
||||
split (range, *it, '-');
|
||||
|
||||
switch (range.size ())
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
if (! validId (range[0]))
|
||||
throw context.stringtable.get (SEQUENCE_BAD_SEQ, "Invalid ID in sequence");
|
||||
|
||||
int id = ::atoi (range[0].c_str ());
|
||||
this->push_back (id);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
if (! validId (range[0]) ||
|
||||
! validId (range[1]))
|
||||
throw context.stringtable.get (SEQUENCE_BAD_SEQ, "Invalid ID in range");
|
||||
|
||||
int low = ::atoi (range[0].c_str ());
|
||||
int high = ::atoi (range[1].c_str ());
|
||||
if (low > high)
|
||||
throw context.stringtable.get (SEQUENCE_INVERTED, "Inverted sequence range high-low");
|
||||
|
||||
if (high - low >= SEQUENCE_MAX)
|
||||
throw context.stringtable.get (SEQUENCE_RANGE_MAX, "ID Range too large");
|
||||
|
||||
for (int i = low; i <= high; ++i)
|
||||
this->push_back (i);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw context.stringtable.get (SEQUENCE_NOT_A_SEQUENCE, "Not a sequence.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Sequence::combine (const Sequence& other)
|
||||
{
|
||||
// Create a map using the sequence elements as keys. This will create a
|
||||
// unique list, with no duplicates.
|
||||
std::map <int, int> both;
|
||||
foreach (i, *this) both[*i] = 0;
|
||||
foreach (i, other) both[*i] = 0;
|
||||
|
||||
// Now make a sequence out of the keys of the map.
|
||||
this->clear ();
|
||||
foreach (i, both)
|
||||
this->push_back (i->first);
|
||||
|
||||
std::sort (this->begin (), this->end ());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Sequence::validId (const std::string& input) const
|
||||
{
|
||||
if (input.length () == 0)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < input.length (); ++i)
|
||||
if (!::isdigit (input[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
51
src/Sequence.h
Normal file
51
src/Sequence.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef INCLUDED_SEQUENCE
|
||||
#define INCLUDED_SEQUENCE
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#define SEQUENCE_MAX 1000
|
||||
|
||||
class Sequence : public std::vector <int>
|
||||
{
|
||||
public:
|
||||
Sequence (); // Default constructor
|
||||
Sequence (const std::string&); // Parse
|
||||
~Sequence (); // Destructor
|
||||
|
||||
bool valid (const std::string&) const;
|
||||
void parse (const std::string&);
|
||||
void combine (const Sequence&);
|
||||
|
||||
private:
|
||||
bool validId (const std::string&) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
98
src/StringTable.cpp
Normal file
98
src/StringTable.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// task - a command line task list manager.
|
||||
//
|
||||
// Copyright 2006 - 2009, Paul Beckingham.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 2 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program; if not, write to the
|
||||
//
|
||||
// Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor,
|
||||
// Boston, MA
|
||||
// 02110-1301
|
||||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <text.h>
|
||||
#include <util.h>
|
||||
#include <stdlib.h>
|
||||
#include "StringTable.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
StringTable::StringTable ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
StringTable::~StringTable ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// UTF-8 encoding
|
||||
//
|
||||
// 123 This is the string
|
||||
// 124 This is another string
|
||||
// ...
|
||||
void StringTable::load (const std::string& file)
|
||||
{
|
||||
this->clear (); // Allows dynamic reload.
|
||||
|
||||
std::ifstream in;
|
||||
in.open (file.c_str (), std::ifstream::in);
|
||||
if (in.good ())
|
||||
{
|
||||
std::string line;
|
||||
while (getline (in, line))
|
||||
{
|
||||
// Remove comments.
|
||||
std::string::size_type pound = line.find ("#"); // no i18n
|
||||
if (pound != std::string::npos)
|
||||
line = line.substr (0, pound);
|
||||
|
||||
line = trim (line, " \t"); // no i18n
|
||||
|
||||
// Skip empty lines.
|
||||
if (line.length () > 0)
|
||||
{
|
||||
std::string::size_type equal = line.find (" "); // no i18n
|
||||
if (equal != std::string::npos)
|
||||
{
|
||||
int key = ::atoi (trim (line.substr (0, equal), " \t").c_str ()); // no i18n
|
||||
std::string value = trim (line.substr (equal+1, line.length () - equal), " \t"); // no i18n
|
||||
(*this)[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
in.close ();
|
||||
}
|
||||
else
|
||||
throw std::string ("Could not read string file '") + file + "'"; // TODO i18n
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string StringTable::get (int id, const std::string& alternate)
|
||||
{
|
||||
// Return the right string.
|
||||
if (this->find (id) != this->end ())
|
||||
return (*this)[id];
|
||||
|
||||
return alternate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue