diff --git a/AUTHORS b/AUTHORS
index ffcf9c092..d045cad9b 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -3,6 +3,8 @@ Principal Author:
Contributing Authors:
Damian Glenny
+ Andy Lester
+ H. İbrahim Güngör
With thanks to:
Eugene Kramer
@@ -12,7 +14,7 @@ With thanks to:
Thomas Engel
Nishiishii
galvanizd
- H. İbrahim Güngör
Stas Antons
- Andy Lester
+ Vincent Fleuranceau
+ T. Charles Yun
diff --git a/ChangeLog b/ChangeLog
index 606cbf7ac..f924b0d61 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,12 +7,34 @@ represents a feature release, and the Z represents a patch.
------ current release ---------------------------
-1.4.1 (7/?/2008)
+1.4.2 (9/13/2008)
+ + "task undo" can now retract a "task done" command, provided no reports
+ have been run (and therefore TDB::gc run)
+ + Task now correctly sorts on entire strings, instead of just the first
+ character (thanks to Andy Lester)
+ + Task now uses dashes (-----) to column underlines when color is disabled
+ (thanks to Vincent Fleuranceau)
+ + Task now allows mixed case attribute names (pri:, PRI:, Pri: ...) and
+ commands (add, ADD, Add ...) (thanks to Vincent Fleuranceau)
+ + 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)
+ + Task supports improved word-wrapping to the terminal width
+ + Task now supports "default.command" configuration variable (for example
+ it could contain "list due:tomorrow") that is the command that is run
+ whenever task is invoked with no arguments.
+ + Bug: Now properly supports relative dates in filters (task list due:eom,
+ task list due:tomorrow, task list due:23rd ...)
+ + Bug: Source now properly includes in order to build clean
+ using gcc 4.3.
+
+------ old releases ------------------------------
+
+1.4.1 (7/18/2008)
+ Bug: Descriptions can not be altered with "task 123 New description"
+ Tweak: For "task calendar" month names are now centered over the month
+ Removed TUTORIAL file contents in favor of online version
-
------- old releases ------------------------------
+ + Provided Mac .pkg binary
1.4.0 (7/10/2008)
+ New recurring tasks feature
diff --git a/NEWS b/NEWS
index de3298f15..18b4251e8 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ Task has been built and tested on the following configurations:
- Fedora Core 8
- Fedora Core 9
- Ubuntu 8 Hardy Heron
+ - Ubuntu 9 Feisty Fawn
- Solaris 10
- Cygwin 1.5.25-14
diff --git a/configure.ac b/configure.ac
index d9f7bbeb4..9d7bc2d33 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
-AC_INIT(task, 1.4.1, bugs@beckingham.net)
+AC_INIT(task, 1.4.2, bugs@beckingham.net)
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([src/task.cpp])
AC_CONFIG_HEADER([auto.h])
diff --git a/html/advanced.html b/html/advanced.html
index feed82b65..3208f2671 100644
--- a/html/advanced.html
+++ b/html/advanced.html
@@ -43,6 +43,25 @@
lists all these commands.
+
+ However, if the following configuration variable is specified:
+
+
+ default.command=list pri:H
+
+
+ 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:
+
+
+ % task
+[task list project:foo]
+
+ID Project Pri Description
+ 1 foo H Design the thing
+ 2 foo Build the thing
+
% task projects
This report generates a list of all the different projects that you
diff --git a/html/config.html b/html/config.html
index b241b8d92..251766af1 100644
--- a/html/config.html
+++ b/html/config.html
@@ -210,6 +210,8 @@
color
May be "on" or "off". Determines whether task uses color.
+ When "off", task will use dashes (-----) to underline column
+ headings.
@@ -246,6 +248,44 @@
Colors any task where the description contains X.
+
+ default.project
+
+ Provides a default project name for the "task add ..." command.
+
+
+ default.priority
+
+ Provides a default priority for the "task add ..." command.
+
+
+ default.command
+
+
+ Provides a default command that is run every time task is
+ invoked with no arguments. For example, if set to:
+
+
+ default.command=list project:foo
+
+
+ Then task will run the "list project:foo" command if no
+ command is specified. This means that by merely typing:
+
+
+ % task
+[task list project:foo]
+
+ID Project Pri Description
+ 1 foo H Design the thing
+ 2 foo Build the thing
+
+
+ Note that the value of this variable is simply the command
+ line that you would ordinarily type, but without the
+ preceding "task" program name.
+
+
diff --git a/html/task.html b/html/task.html
index 0dd342053..cec9f6ae7 100644
--- a/html/task.html
+++ b/html/task.html
@@ -75,27 +75,45 @@
- New in version 1.4.1 (7/18/2008)
+ New in version 1.4.2 (9/13/2008)
- - Fixed bug: Descriptions could not be altered with "task 123 New description"
-
- Tweak: For "task calendar" month names are now centered over the month
-
- Removed TUTORIAL file contents in favor of online version
-
- New Mac Intel-only Leopard (10.5) binary package
+
- "task undo" can now retract a "task done" command, provided no
+ reports have been run.
+
- Task now correctly sorts on entire strings, instead of just the
+ first character (thanks to Andy Lester).
+
- Task now uses dashes (-----) to underline column headings when
+ color is disabled (thanks to Vincent Fleuranceau).
+
- Task now allows mixed case attribute names (pri:, PRI:, Pri: ...)
+ and commands (add, ADD, Add ...) (thanks to Vincent Fleuranceau).
+
- 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).
+
- Task supports improved word-wrapping to the terminal width.
+
- 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.
+
- Fixed bug so that relative dates in filters (task list due:eom,
+ task list due:tomorrow, task list due:23rd ...) are now properly
+ supported.
+
- Fixed bug so that source now properly includes <string.h> in
+ order to build clean using gcc 4.3.
diff --git a/html/versions.html b/html/versions.html
index 30df5851f..e6e3ffe4f 100644
--- a/html/versions.html
+++ b/html/versions.html
@@ -35,6 +35,20 @@
+
+
New in version 1.4.1 (7/18/2008)
+
task-1.4.1.tar.gz
+
+ Mac OS X 10.5 (Leopard) Intel-only:
+
task-1.4.1.pkg
+
+
+
+ - Fixed bug: Descriptions could not be altered with "task 123 New description"
+
- Tweak: For "task calendar" month names are now centered over the month
+
- Removed TUTORIAL file contents in favor of online version
+
- New Mac Intel-only Leopard (10.5) binary package
+
New in version 1.4.0 (7/10/2008)
Source:
task-1.4.0.tar.gz
diff --git a/ideas.txt b/ideas.txt
index 261044c07..09cea7499 100644
--- a/ideas.txt
+++ b/ideas.txt
@@ -20,51 +20,3 @@ Test Suite
- debug=on to cause all cout to be csv
- regression tests for every bug, command, feature
-Recurrence
- + new T::status recurring (stored as R)
- + new user-specifiable attributes - recur:
[until:]
- + duration:
- daily, day, 1d
- Nd
- weekly, 1w
- Nw
- biweekly
- monthly, 1m
- bimonthly
- Nm
- quarterly, 1q
- Nq
- biannual, biyearly
- annual, yearly, 1y
- Na, Ny
- + recur: without due: => Error
- + until: without recur: => Error
- + New file format: supports status R, recur:, until:, base:, range:
- - on TDB.gc, adjust base: and compress range: for T::status == recurring
- - all recurring tasks are removed from lists by T::*pendingT, and a synthetic
- addendum is generated
- - when a recurring task is completed, range: is updated, and a synthetic
- task is added to completed.data that retains the attributes of the root
-
- - Scenario:
- # Today = 6/22/2008
- % task add Friday due:6/15/2008 recur:weekly until 8/1/2008
- # task must generate a base and range
- # base:6/15/2008
- # range:-------
- # ^6/15
- # ^6/22
- # ^6/29
- # ^7/6
- # ^7/13
- # ^7/20
- # ^7/27
- % task ls
- 1 Friday 6/15/2008 .lte. today (overdue)
- 2 Friday 6/22/2008 .lte. today (due)
- 3 Friday 6/29/2008 one recurrence
- 4 Friday 7/6/2008 (not shown)
- 5 Friday 7/13/2008 (not shown)
- 6 Friday 7/20/2008 (not shown)
- 7 Friday 7/27/2008 (not shown)
-
diff --git a/src/Date.cpp b/src/Date.cpp
index f7378bbb3..67ac7e7c7 100644
--- a/src/Date.cpp
+++ b/src/Date.cpp
@@ -543,22 +543,35 @@ bool Date::isRelativeDate (const std::string& input)
else
today += (dow - today.dayOfWeek ()) * 86400;
- mT = today.mT;
+ int m, d, y;
+ today.toMDY (m, d, y);
+ Date then (m, d, y);
+
+ mT = then.mT;
return true;
}
else if (found == "today")
{
- mT = today.mT;
+ Date then (today.month (),
+ today.day (),
+ today.year ());
+ mT = then.mT;
return true;
}
else if (found == "tomorrow")
{
- mT = today.mT + 86400;
+ Date then (today.month (),
+ today.day (),
+ today.year ());
+ mT = then.mT + 86400;
return true;
}
else if (found == "yesterday")
{
- mT = today.mT - 86400;
+ Date then (today.month (),
+ today.day (),
+ today.year ());
+ mT = then.mT - 86400;
return true;
}
else if (found == "eom")
diff --git a/src/Table.cpp b/src/Table.cpp
index 89f65bdf9..6de729b4b 100644
--- a/src/Table.cpp
+++ b/src/Table.cpp
@@ -54,6 +54,7 @@
Table::Table ()
: mRows (0)
, mIntraPadding (1)
+ , mDashedUnderline (false)
, mTablePadding (0)
, mTableWidth (0)
, mSuppressWS (false)
@@ -103,6 +104,12 @@ void Table::setTableWidth (int width)
mTableWidth = width;
}
+////////////////////////////////////////////////////////////////////////////////
+void Table::setTableDashedUnderline ()
+{
+ mDashedUnderline = true;
+}
+
////////////////////////////////////////////////////////////////////////////////
int Table::addColumn (const std::string& col)
{
@@ -582,7 +589,57 @@ const std::string Table::formatHeader (
fg, bg,
Text::colorize (
decoration, Text::nocolor,
- pad + preJust+ data + postJust + pad) + intraPad);
+ pad + preJust + data + postJust + pad) + intraPad);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// data One Data to be rendered
+// width 8 Max data width for column/specified width
+// padding 1 Extra padding around data
+// intraPadding 0 Extra padding between columns only
+// justification right Alignment withing padding
+//
+// Returns:
+// "------- "
+// ------- data
+// ^ ^ padding
+// ^ intraPadding
+// ^^^^^^^^ width
+// ^ ^ fg/bg
+//
+const std::string Table::formatHeaderDashedUnderline (
+ int col,
+ int width,
+ int padding)
+{
+ assert (width > 0);
+
+ Text::color fg = getHeaderFg (col);
+ Text::color bg = getHeaderBg (col);
+ Text::color decoration = getHeaderUnderline (col);
+
+ std::string data = "";
+ for (int i = 0; i < width; ++i)
+ data += '-';
+
+ std::string pad = "";
+ std::string intraPad = "";
+ std::string attrOn = "";
+ std::string attrOff = "";
+
+ for (int i = 0; i < padding; ++i)
+ pad += " ";
+
+ // Place the value within the available space - justify.
+ if (col < (signed) mColumns.size () - 1)
+ for (int i = 0; i < getIntraPadding (); ++i)
+ intraPad += " ";
+
+ return Text::colorize (
+ fg, bg,
+ Text::colorize (
+ decoration, Text::nocolor,
+ pad + data + pad) + intraPad);
}
////////////////////////////////////////////////////////////////////////////////
@@ -758,12 +815,12 @@ void Table::sort (std::vector & order)
break;
case ascendingCharacter:
- if ((char)*left > (char)*right)
+ if ((std::string)*left > (std::string)*right)
SWAP
break;
case descendingCharacter:
- if ((char)*left < (char)*right)
+ if ((std::string)*left < (std::string)*right)
SWAP
break;
@@ -861,13 +918,24 @@ const std::string Table::render ()
// Print column headers in column order.
std::string output;
+ std::string underline;
for (size_t col = 0; col < mColumns.size (); ++col)
+ {
output += formatHeader (
col,
mCalculatedWidth[col],
mColumnPadding[col]);
+ if (mDashedUnderline)
+ underline += formatHeaderDashedUnderline (
+ col,
+ mCalculatedWidth[col],
+ mColumnPadding[col]);
+ }
+
output += "\n";
+ if (underline.length ())
+ output += underline + "\n";
// Determine row order, according to sort options.
std::vector order;
diff --git a/src/Table.h b/src/Table.h
index 7428453ec..6a793af0c 100644
--- a/src/Table.h
+++ b/src/Table.h
@@ -51,6 +51,7 @@ public:
void setTablePadding (int);
void setTableIntraPadding (int);
void setTableWidth (int);
+ void setTableDashedUnderline ();
int addColumn (const std::string&);
void setColumnColor (int, Text::color, Text::color);
@@ -98,6 +99,7 @@ private:
just getJustification (const int, const int);
just getHeaderJustification (const int);
const std::string formatHeader (const int, const int, const int);
+ const std::string formatHeaderDashedUnderline (const int, const int, const int);
void formatCell (const int, const int, const int, const int, std::vector &, std::string&);
void optimize (std::string&);
void sort (std::vector &);
@@ -110,6 +112,7 @@ private:
std::map mFg;
std::map mBg;
std::map mUnderline;
+ bool mDashedUnderline;
// Padding...
int mTablePadding;
diff --git a/src/command.cpp b/src/command.cpp
index 5344a4037..51d5f7f37 100644
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -66,6 +66,20 @@ void handleAdd (const TDB& tdb, T& task, Config& conf)
task.setAttribute ("mask", "");
}
+/**/
+ // Override with default.project, if not specified.
+ if (task.getAttribute ("project") == "")
+ task.setAttribute ("project", conf.get ("default.project", ""));
+
+ // Override with default.priority, if not specified.
+ if (task.getAttribute ("priority") == "")
+ {
+ std::string defaultPriority = conf.get ("default.priority", "");
+ if (validPriority (defaultPriority))
+ task.setAttribute ("priority", defaultPriority);
+ }
+/**/
+
if (task.getDescription () == "")
throw std::string ("Cannot add a blank task.");
@@ -203,6 +217,49 @@ void handleUndelete (TDB& tdb, T& task, Config& conf)
<< "command is run immediately after the errant delete command." << std::endl;
}
+////////////////////////////////////////////////////////////////////////////////
+// If a task is done, but is still in the pending file, then it may be undone
+// simply by changing it's status.
+void handleUndo (TDB& tdb, T& task, Config& conf)
+{
+ std::vector all;
+ tdb.allPendingT (all);
+
+ int id = task.getId ();
+ std::vector ::iterator it;
+ for (it = all.begin (); it != all.end (); ++it)
+ {
+ if (it->getId () == id)
+ {
+ if (it->getStatus () == T::completed)
+ {
+ if (it->getAttribute ("recur") != "")
+ {
+ std::cout << "Task does not support 'undo' for recurring tasks." << std::endl;
+ return;
+ }
+
+ T restored (*it);
+ restored.setStatus (T::pending);
+ restored.removeAttribute ("end");
+ tdb.modifyT (restored);
+
+ std::cout << "Task " << id << " successfully undone." << std::endl;
+ return;
+ }
+ else
+ {
+ std::cout << "Task " << id << " is not done - therefore cannot be undone." << std::endl;
+ return;
+ }
+ }
+ }
+
+ std::cout << "Task " << id
+ << " not found - tasks can only be reliably undone if the undo" << std::endl
+ << "command is run immediately after the errant done command." << std::endl;
+}
+
////////////////////////////////////////////////////////////////////////////////
void handleVersion (Config& conf)
{
@@ -217,6 +274,26 @@ void handleVersion (Config& conf)
}
#endif
+ // Create a table for the disclaimer.
+ Table disclaimer;
+ disclaimer.setTableWidth (width);
+ disclaimer.addColumn (" ");
+ disclaimer.setColumnWidth (0, Table::flexible);
+ disclaimer.setColumnJustification (0, Table::left);
+ disclaimer.addCell (disclaimer.addRow (), 0,
+ "Task comes with ABSOLUTELY NO WARRANTY; for details read the COPYING file "
+ "included. This is free software, and you are welcome to redistribute it "
+ "under certain conditions; again, see the COPYING file for details.");
+
+ // Create a table for the URL.
+ Table link;
+ link.setTableWidth (width);
+ link.addColumn (" ");
+ link.setColumnWidth (0, Table::flexible);
+ link.setColumnJustification (0, Table::left);
+ link.addCell (link.addRow (), 0,
+ "See http://www.beckingham.net/task.html for the latest releases and a full tutorial.");
+
// Create a table for output.
Table table;
table.setTableWidth (width);
@@ -255,18 +332,10 @@ void handleVersion (Config& conf)
<< " "
<< VERSION
<< std::endl
- << std::endl
- << "Task comes with ABSOLUTELY NO WARRANTY; for details read the COPYING file"
- << std::endl
- << "included. This is free software, and you are welcome to redistribute it"
- << std::endl
- << "under certain conditions; again, see the COPYING file for details."
- << std::endl
+ << disclaimer.render ()
<< std::endl
<< table.render ()
- << std::endl
- << "See http://www.beckingham.net/task.html for the latest releases and a full tutorial."
- << std::endl
+ << link.render ()
<< std::endl;
// Verify installation. This is mentioned in the documentation as the way to
diff --git a/src/parse.cpp b/src/parse.cpp
index 770c2b2f0..98c376fe2 100644
--- a/src/parse.cpp
+++ b/src/parse.cpp
@@ -141,6 +141,7 @@ static const char* commands[] =
"summary",
"tags",
"undelete",
+ "undo",
"usage",
"version",
"",
@@ -207,7 +208,7 @@ bool validDate (std::string& date, Config& conf)
}
////////////////////////////////////////////////////////////////////////////////
-static bool validPriority (const std::string& input)
+bool validPriority (const std::string& input)
{
if (input != "H" &&
input != "M" &&
@@ -370,8 +371,8 @@ void parse (
std::string to;
// An id is the first argument found that contains all digits.
- if (command != "add" && // "add" doesn't require an ID
- task.getId () == 0 &&
+ if (lowerCase (command) != "add" && // "add" doesn't require an ID
+ task.getId () == 0 &&
validId (arg))
task.setId (::atoi (arg.c_str ()));
@@ -388,7 +389,7 @@ void parse (
// value.
else if ((colon = arg.find (":")) != std::string::npos)
{
- std::string name = arg.substr (0, colon);
+ std::string name = lowerCase (arg.substr (0, colon));
std::string value = arg.substr (colon + 1, std::string::npos);
if (validAttribute (name, value, conf))
@@ -412,8 +413,9 @@ void parse (
// Command.
else if (command == "")
{
- if (isCommand (arg) && validCommand (arg))
- command = arg;
+ std::string l = lowerCase (arg);
+ if (isCommand (l) && validCommand (l))
+ command = l;
else
descCandidate += arg;
// throw std::string ("'") + arg + "' is not a valid command.";
diff --git a/src/report.cpp b/src/report.cpp
index e0ec8db90..c82abeaac 100644
--- a/src/report.cpp
+++ b/src/report.cpp
@@ -79,6 +79,7 @@ void filter (std::vector& all, T& task)
// Apply attribute filter.
matches = 0;
foreach (a, attrList)
+ {
if (a->first == "project")
{
if (a->second.length () <= refTask.getAttribute (a->first).length ())
@@ -87,6 +88,7 @@ void filter (std::vector& all, T& task)
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
+ }
if (matches == attrList.size ())
{
@@ -143,7 +145,7 @@ void handleList (TDB& tdb, T& task, Config& conf)
if (showAge) table.addColumn ("Age");
table.addColumn ("Description");
- if (conf.get ("color", true))
+ if (conf.get (std::string ("color"), true))
{
table.setColumnUnderline (0);
table.setColumnUnderline (1);
@@ -153,6 +155,8 @@ void handleList (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (5);
if (showAge) table.setColumnUnderline (6);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnWidth (0, Table::minimum);
table.setColumnWidth (1, Table::minimum);
@@ -291,6 +295,8 @@ void handleSmallList (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (2);
table.setColumnUnderline (3);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnWidth (0, Table::minimum);
table.setColumnWidth (1, Table::minimum);
@@ -414,6 +420,8 @@ void handleCompleted (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (1);
table.setColumnUnderline (2);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnWidth (0, Table::minimum);
table.setColumnWidth (1, Table::minimum);
@@ -493,6 +501,8 @@ void handleInfo (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (0);
table.setColumnUnderline (1);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnWidth (0, Table::minimum);
table.setColumnWidth (1, Table::minimum);
@@ -710,6 +720,8 @@ void handleLongList (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (7);
if (showAge) table.setColumnUnderline (8);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnWidth (0, Table::minimum);
table.setColumnWidth (1, Table::minimum);
@@ -913,6 +925,8 @@ void handleReportSummary (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (2);
table.setColumnUnderline (3);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnJustification (1, Table::right);
table.setColumnJustification (2, Table::right);
@@ -1056,6 +1070,8 @@ void handleReportNext (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (5);
if (showAge) table.setColumnUnderline (6);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnWidth (0, Table::minimum);
table.setColumnWidth (1, Table::minimum);
@@ -1275,6 +1291,8 @@ void handleReportHistory (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (4);
table.setColumnUnderline (5);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnJustification (2, Table::right);
table.setColumnJustification (3, Table::right);
@@ -1462,6 +1480,8 @@ void handleReportGHistory (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (0);
table.setColumnUnderline (1);
}
+ else
+ table.setTableDashedUnderline ();
// Determine the longest line.
int maxLine = 0;
@@ -1623,6 +1643,8 @@ void handleReportUsage (const TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (0);
table.setColumnUnderline (1);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnJustification (1, Table::right);
table.sortOn (1, Table::descendingNumeric);
@@ -1681,6 +1703,8 @@ std::string renderMonths (
table.setColumnUnderline (i + 6);
table.setColumnUnderline (i + 7);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnJustification (i + 0, Table::right);
table.setColumnJustification (i + 1, Table::right);
@@ -1896,6 +1920,8 @@ void handleReportActive (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (3);
table.setColumnUnderline (4);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnWidth (0, Table::minimum);
table.setColumnWidth (1, Table::minimum);
@@ -2011,6 +2037,8 @@ void handleReportOverdue (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (3);
table.setColumnUnderline (4);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnWidth (0, Table::minimum);
table.setColumnWidth (1, Table::minimum);
@@ -2126,6 +2154,8 @@ void handleReportOldest (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (5);
if (showAge) table.setColumnUnderline (6);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnWidth (0, Table::minimum);
table.setColumnWidth (1, Table::minimum);
@@ -2269,6 +2299,8 @@ void handleReportNewest (TDB& tdb, T& task, Config& conf)
table.setColumnUnderline (5);
if (showAge) table.setColumnUnderline (6);
}
+ else
+ table.setTableDashedUnderline ();
table.setColumnWidth (0, Table::minimum);
table.setColumnWidth (1, Table::minimum);
diff --git a/src/task.cpp b/src/task.cpp
index 0d3f6c7f5..29951dee3 100644
--- a/src/task.cpp
+++ b/src/task.cpp
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -125,6 +126,10 @@ static void shortUsage (Config& conf)
table.addCell (row, 1, "task done ID");
table.addCell (row, 2, "Marks the specified task as completed");
+ row = table.addRow ();
+ table.addCell (row, 1, "task undo ID");
+ table.addCell (row, 2, "Marks the specified done task as pending, provided a report has not yet been run");
+
row = table.addRow ();
table.addCell (row, 1, "task projects");
table.addCell (row, 2, "Shows a list of all project names used, and how many tasks are in each");
@@ -295,10 +300,23 @@ int main (int argc, char** argv)
if (conf.get ("command.logging") == "on")
tdb.logCommand (argc, argv);
- // Parse the command line.
+ // If argc == 1 and the default.command configuration variable is set,
+ // then use that, otherwise stick with argc/argv.
std::vector args;
- for (int i = 1; i < argc; ++i)
- args.push_back (argv[i]);
+ std::string defaultCommand = conf.get ("default.command");
+ if (argc == 1 && defaultCommand != "")
+ {
+ // Stuff the command line.
+ split (args, defaultCommand, ' ');
+ std::cout << "[task " << defaultCommand << "]" << std::endl;
+ }
+ else
+ {
+ // Parse the command line.
+ for (int i = 1; i < argc; ++i)
+ args.push_back (argv[i]);
+ }
+
std::string command;
T task;
parse (args, command, task, conf);
@@ -316,6 +334,7 @@ int main (int argc, char** argv)
else if (command == "delete") handleDelete (tdb, task, conf);
else if (command == "start") handleStart (tdb, task, conf);
else if (command == "done") handleDone (tdb, task, conf);
+ else if (command == "undo") handleUndo (tdb, task, conf);
else if (command == "export") handleExport (tdb, task, conf);
else if (command == "version") handleVersion ( conf);
else if (command == "summary") handleReportSummary (tdb, task, conf);
diff --git a/src/task.h b/src/task.h
index 4a8dc78fd..7b732f423 100644
--- a/src/task.h
+++ b/src/task.h
@@ -55,6 +55,7 @@ for (typeof (c) *foreach_p = & (c); \
// parse.cpp
void parse (std::vector &, std::string&, T&, Config&);
+bool validPriority (const std::string&);
bool validDate (std::string&, Config&);
// task.cpp
@@ -76,6 +77,7 @@ void handleExport (TDB&, T&, Config&);
void handleDelete (TDB&, T&, Config&);
void handleStart (TDB&, T&, Config&);
void handleDone (TDB&, T&, Config&);
+void handleUndo (TDB&, T&, Config&);
void handleModify (TDB&, T&, Config&);
void handleColor (Config&);
diff --git a/src/tests/in b/src/tests/in
new file mode 100755
index 000000000..761c1f877
--- /dev/null
+++ b/src/tests/in
@@ -0,0 +1,15 @@
+./task add monday due:monday
+./task add tuesday due:tuesday
+./task add wednesday due:wednesday
+./task add thursday due:thursday
+./task add friday due:friday
+./task add saturday due:saturday
+./task add sunday due:sunday
+./task add yesterday due:yesterday
+./task add today due:today
+./task add tomorrow due:tomorrow
+./task add eow due:eow
+./task add eom due:eom
+./task add eoy due:eoy
+./task add 21st due:21st
+
diff --git a/src/tests/out b/src/tests/out
new file mode 100755
index 000000000..c0b81f3b4
--- /dev/null
+++ b/src/tests/out
@@ -0,0 +1,15 @@
+./task li due:monday
+./task li due:tuesday
+./task li due:wednesday
+./task li due:thursday
+./task li due:friday
+./task li due:saturday
+./task li due:sunday
+./task li due:yesterday
+./task li due:today
+./task li due:tomorrow
+./task li due:eow
+./task li due:eom
+./task li due:eoy
+./task li due:21st
+