mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
Merge branch '1.9.3' of tasktools.org:task into 1.9.3
Conflicts: src/Config.cpp
This commit is contained in:
commit
2eaba55481
27 changed files with 663 additions and 338 deletions
|
@ -28,6 +28,8 @@
|
|||
changes to the completion percentage when it changes.
|
||||
+ Added feature #478, which uses the colorization rules in the 'info'
|
||||
report.
|
||||
+ Added feature #481, allowing for user control of the color rule order
|
||||
of precedence via the 'rule.precedence.color' configuration variable.
|
||||
+ New 'depends' column for custom reports.
|
||||
+ New 'blocked' report for showing blocked tasks.
|
||||
+ Improved man pages (thanks to Andy Lester).
|
||||
|
@ -37,6 +39,8 @@
|
|||
+ The 'tags' command highlights special tags.
|
||||
+ The 'stats' and 'info' reports not obey color.alternate.
|
||||
+ New fish shell tab completion script (thanks to Mick Koch).
|
||||
+ Color rules now obey the rc.search.case.sensitive configuration option.
|
||||
+ The color.keyword.XXX color rule now applies to annotations too.
|
||||
+ Fixed bug #427, preventing the task edit command to parse annotation
|
||||
dates with spaces.
|
||||
+ Fixed bug #433, making task command output more consistent.
|
||||
|
@ -57,6 +61,8 @@
|
|||
and overdue.
|
||||
+ Fixed bug #459, which showed a confusing message when 'limit:page' was
|
||||
used, with few tasks.
|
||||
+ Fixed bug #461, in which the filter 'due:today' failed, but 'due.is:today'
|
||||
worked.
|
||||
+ Fixed bug #466, which gave the wrong error message when a custom report
|
||||
was missing a direction indicator for the sort order.
|
||||
+ Fixed bug #470, which caused task to not support the color 'none'.
|
||||
|
@ -67,6 +73,7 @@
|
|||
+ Fixed problem with the 'undo' command not observing the rc.color or the
|
||||
rc._forcecolor settings.
|
||||
+ Fixed problem with extra blank line in the ghistory reports.
|
||||
+ Fixed a precision problem with average age on the summary report.
|
||||
+ Clarified the documentation regarding the project name (taskwarrior) and
|
||||
the program name (task).
|
||||
|
||||
|
|
12
NEWS
12
NEWS
|
@ -6,6 +6,9 @@ New Features in taskwarrior 1.9.3
|
|||
- Now supports durations in dates, such as:
|
||||
$ task ... due:4d
|
||||
$ task ... due:3wks
|
||||
- 'sow', 'som' and 'soy' are now accepted in dates. 'soww' and 'eoww' are
|
||||
now synonyms for 'sow' and 'eow' (ww = working week) 'socw' and 'eocw'
|
||||
refer to the calendar week (starting Sunday/Monday and
|
||||
- Now supports the beginning of the week, month and year in dates.
|
||||
- Now supports 'now' as a date/time.
|
||||
- Now defines an overdue task as being one second after the due date,
|
||||
|
@ -15,6 +18,7 @@ New Features in taskwarrior 1.9.3
|
|||
- When completing or modifying a task, the project status is displayed.
|
||||
- The 'info' report is now colorized.
|
||||
- Certain characters (#, $, @) are now supported for use in tags.
|
||||
- User-controlled color rule precedence.
|
||||
|
||||
Please refer to the ChangeLog file for full details. There are too many to
|
||||
list here.
|
||||
|
@ -31,10 +35,10 @@ New commands in taskwarrior 1.9.3
|
|||
New configuration options in taskwarrior 1.9.3
|
||||
|
||||
- journal.time, journal.time.start.annotation, journal.time.stop.annotation
|
||||
- 'sow', 'som' and 'soy' are now accepted in dates
|
||||
'soww' and 'eoww' are now synonyms for 'sow' and 'eow' (ww = working week)
|
||||
'socw' and 'eocw' refer to the calendar week (starting Sunday/Monday and
|
||||
ending Saturday/Sunday)
|
||||
ending Saturday/Sunday).
|
||||
- Color rule precedence can now be explicitly set with the configuration
|
||||
variable rule.precedence.color. Try "task show rule.pre" to show the
|
||||
default settings.
|
||||
|
||||
Newly deprecated features in taskwarrior 1.9.3
|
||||
|
||||
|
|
|
@ -236,6 +236,20 @@ It is possible to create a very colorful mix of rules. With 256-color support,
|
|||
those colors can be made subtle, and complementary, but without care, this can
|
||||
be a visual mess. Beware!
|
||||
|
||||
The precedence for the color rules is determined by the configuration variable
|
||||
'rule.precedence.color', which by default contains:
|
||||
|
||||
due.today,active,blocked,overdue,due,keyword,project,tag,recurring,pri,tagged
|
||||
|
||||
These are just the color rules with the 'color.' prefix removed. The rule
|
||||
'color.due.today' is the highest precedence, and 'color.tagged' is the lowest.
|
||||
|
||||
The keyword rule shown here as 'keyword' corresponds to a wildcard pattern,
|
||||
meaning 'color.keyword.*', or in other words all the keyword rules. Similarly
|
||||
for the 'color.tag.*' and 'color.project.*' rules.
|
||||
|
||||
There is also 'color.project.none', 'color.tag.none' and 'color.pri.none'.
|
||||
|
||||
.SH THEMES
|
||||
Taskwarrior supports themes. What this really means is that with the ability to
|
||||
include other files into the .taskrc file, different sets of color rules can
|
||||
|
@ -266,6 +280,10 @@ dark-green-256.theme
|
|||
dark-blue-256.theme
|
||||
.RE
|
||||
|
||||
You can also see how the theme will color the various tasks with the command:
|
||||
|
||||
$ task color legend
|
||||
|
||||
Better yet, create your own, and share it. We will gladly host the theme file
|
||||
on <http://taskwarrior.org>.
|
||||
|
||||
|
|
|
@ -537,39 +537,50 @@ terminal, can be obtained by running the command:
|
|||
.RE
|
||||
|
||||
.RS
|
||||
The coloration rules and their defaults are:
|
||||
Note that no default values are listed here - the defaults now correspond to the
|
||||
dark-256.theme (Linux) and dark-16.theme (other) theme values.
|
||||
The coloration rules are as follows:
|
||||
.RE
|
||||
|
||||
.RS
|
||||
.B color.overdue=bold red
|
||||
The color for overdue tasks.
|
||||
.B color.due.today
|
||||
Task is due today
|
||||
.br
|
||||
.B color.due.today=bold magenta
|
||||
The color of tasks due today.
|
||||
.B color.active
|
||||
Task is started, therefore active.
|
||||
.br
|
||||
.B color.due=bold yellow
|
||||
The color of due tasks.
|
||||
.B color.blocked
|
||||
Task is blocked by a dependency.
|
||||
.br
|
||||
.B color.pri.H=bold
|
||||
The color of priority:H tasks.
|
||||
.B color.overdue
|
||||
Task is overdue (due some time prior to now).
|
||||
.br
|
||||
.B color.pri.M=on yellow
|
||||
The color of priority:M tasks. No default value.
|
||||
.B color.due
|
||||
Task is coming due.
|
||||
.br
|
||||
.B color.pri.L=on green
|
||||
The color of priority:L tasks. No default value.
|
||||
.B color.project.none
|
||||
Task does not have an assigned project.
|
||||
.br
|
||||
.B color.pri.none=white on blue
|
||||
The color of priority: tasks. No default value.
|
||||
.B color.tag.none
|
||||
Task has no tags.
|
||||
.br
|
||||
.B color.active=bold cyan
|
||||
The color of active tasks.
|
||||
.B color.tagged
|
||||
Task has at least one tag.
|
||||
.br
|
||||
.B color.tagged=yellow
|
||||
The color of tagged tasks.
|
||||
.B color.recurring
|
||||
Task is recurring.
|
||||
.br
|
||||
.B color.recurring=on red
|
||||
The color for recurring tasks.
|
||||
.B color.pri.H
|
||||
Task has priority H.
|
||||
.br
|
||||
.B color.pri.M
|
||||
Task has priority M.
|
||||
.br
|
||||
.B color.pri.L
|
||||
Task has priority L.
|
||||
.br
|
||||
.B color.pri.none
|
||||
Task has no priority.
|
||||
.RE
|
||||
.RE
|
||||
|
||||
|
@ -690,6 +701,15 @@ Colors used by the undo command, to indicate the values both before and after
|
|||
a change that is to be reverted.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B rule.precedence.color=overdue,tag,project,keyword,active,...
|
||||
.RS
|
||||
This setting specifies the precedence of the color rules, from highest to
|
||||
lowest. Note that the prefix 'color.' is omitted (for brevity), and that any
|
||||
wildcard values (color.tag.XXX) is shortened to 'tag', which places all specific
|
||||
tag rules at the same precedence, again for brevity.
|
||||
.RE
|
||||
|
||||
.SS SHADOW FILE
|
||||
|
||||
.TP
|
||||
|
|
|
@ -60,6 +60,8 @@ color.pri.H=bold white
|
|||
color.pri.M=white
|
||||
color.pri.L=
|
||||
color.tagged=green
|
||||
color.blocked=black on white # placeholder color
|
||||
color.blocked=black on white
|
||||
color.project.none=
|
||||
color.tag.none=
|
||||
color.alternate=
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ color.pri.H=color255
|
|||
color.pri.M=color250
|
||||
color.pri.L=color245
|
||||
color.tagged=rgb031
|
||||
color.blocked=black on white # placeholder color
|
||||
color.blocked=on gray4
|
||||
color.project.none=
|
||||
color.tag.none=
|
||||
color.alternate=on color233
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ color.pri.H=rgb035
|
|||
color.pri.M=rgb025
|
||||
color.pri.L=rgb015
|
||||
color.tagged=color246
|
||||
color.blocked=black on white # placeholder color
|
||||
color.blocked=on gray4
|
||||
color.project.none=
|
||||
color.tag.none=
|
||||
color.alternate=on color233
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ color.pri.H=rgb050
|
|||
color.pri.M=rgb030
|
||||
color.pri.L=rgb010
|
||||
color.tagged=color246
|
||||
color.blocked=black on white # placeholder color
|
||||
color.blocked=on gray4
|
||||
color.project.none=
|
||||
color.tag.none=
|
||||
color.alternate=on color233
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ color.pri.H=rgb500
|
|||
color.pri.M=rgb400
|
||||
color.pri.L=rgb300
|
||||
color.tagged=color246
|
||||
color.blocked=black on white # placeholder color
|
||||
color.blocked=on gray4
|
||||
color.project.none=
|
||||
color.tag.none=
|
||||
color.alternate=on color233
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ color.pri.H=bold black
|
|||
color.pri.M=black
|
||||
color.pri.L=
|
||||
color.tagged=green
|
||||
color.blocked=black on white # placeholder color
|
||||
color.blocked=black on white
|
||||
color.project.none=
|
||||
color.tag.none=
|
||||
color.alternate=
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@ color.pri.H=color232
|
|||
color.pri.M=color237
|
||||
color.pri.L=color242
|
||||
color.tagged=rgb020
|
||||
color.blocked=black on white # placeholder color
|
||||
color.blocked=on gray4
|
||||
color.project.none=
|
||||
color.tag.none=
|
||||
color.alternate=on color254
|
||||
|
||||
|
|
13
src/Att.cpp
13
src/Att.cpp
|
@ -438,11 +438,11 @@ bool Att::validMod (const std::string& mod)
|
|||
std::string Att::type (const std::string& name) const
|
||||
{
|
||||
if (name == "due" ||
|
||||
name == "wait" ||
|
||||
name == "until" ||
|
||||
name == "start" ||
|
||||
name == "entry" ||
|
||||
name == "end" ||
|
||||
name == "wait")
|
||||
name == "end")
|
||||
return "date";
|
||||
|
||||
else if (name == "recur")
|
||||
|
@ -542,16 +542,17 @@ bool Att::match (const Att& other) const
|
|||
if (mMod == "")
|
||||
{
|
||||
// Exact matches on dates should only compare m/d/y, not h:m:s. This allows
|
||||
// Comapisons like "task list due:today" (bug #405).
|
||||
// comparisons like "task list due:today" (bug #405).
|
||||
std::string which = type (mName);
|
||||
if (which == "date")
|
||||
{
|
||||
if (other.mValue == "")
|
||||
return false;
|
||||
|
||||
Date left (mValue);
|
||||
Date right (other.mValue);
|
||||
|
||||
if (left.year () != right.year () ||
|
||||
left.month () != right.month () ||
|
||||
left.day () != right.day ())
|
||||
if (! left.sameDay (right))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -124,6 +124,7 @@ std::string Config::defaults =
|
|||
"color.header=color3 # Color of header messages\n"
|
||||
"color.footnote=color3 # Color of footnote messages\n"
|
||||
"color.debug=color3 # Color of diagnostic output\n"
|
||||
"color.alternate=on color233 # Alternate color for line coloring\n"
|
||||
"\n"
|
||||
"color.summary.bar=on rgb141 # Color of summary report progress bar\n"
|
||||
"color.summary.background=on color0 # Color of summary report background\n"
|
||||
|
@ -143,29 +144,28 @@ std::string Config::defaults =
|
|||
"color.calendar.holiday=color0 on color11 # Color of public holidays in calendar\n"
|
||||
"color.calendar.weeknumber=rgb013 # Color of the weeknumbers in calendar\n"
|
||||
"\n"
|
||||
"# The following rules are presented in their order of precedence.\n"
|
||||
"# The higher the color rule is up this list, the higher precedence\n"
|
||||
"# it has in determining the color for the task. Precedence is shown\n"
|
||||
"# in brackets [1]\n"
|
||||
"color.recurring=rgb013 # [1] Color of recur.any: tasks\n"
|
||||
"color.overdue=color9 # [2] Color of overdue tasks\n"
|
||||
"color.due.today=rgb400 # [3] Color of tasks due today\n"
|
||||
"color.due=color1 # [4] Color of due tasks\n"
|
||||
"#color.keyword.car=on blue # [5] Color of description.contains:car tasks\n"
|
||||
"#color.project.garden=on green # [6] Color of project:garden tasks\n"
|
||||
"#color.tag.bug=yellow # [7] Color of +bug tasks\n"
|
||||
"color.active=rgb555 on rgb410 # [8] Color of active tasks\n"
|
||||
"color.pri.none= # [9] Color of priority: tasks\n"
|
||||
"color.pri.H=rgb255 # [9] Color of priority:H tasks\n"
|
||||
"color.pri.M=rgb250 # [9] Color of priority:M tasks\n"
|
||||
"color.pri.L=rgb245 # [9] Color of priority:L tasks\n"
|
||||
"color.tagged=rgb031 # [10] Color of tagged tasks\n"
|
||||
"color.blocked=black on white # [11] Color of blocked tasks\n"
|
||||
"color.alternate=on color233 # [12] Alternate color for line coloring\n"
|
||||
"# Here are the color rules.\n"
|
||||
"color.recurring=rgb013 # Color of recur.any: tasks\n"
|
||||
"color.overdue=color9 # Color of overdue tasks\n"
|
||||
"color.due.today=rgb400 # Color of tasks due today\n"
|
||||
"color.due=color1 # Color of due tasks\n"
|
||||
"#color.keyword.car=on blue # Color of description.contains:car tasks\n"
|
||||
"#color.project.garden=on green # Color of project:garden tasks\n"
|
||||
"#color.project.none= # Color of tasks with no project\n"
|
||||
"#color.tag.bug=yellow # Color of +bug tasks\n"
|
||||
"#color.tag.none= # Color of tag-less tasks\n"
|
||||
"color.active=rgb555 on rgb410 # Color of active tasks\n"
|
||||
"color.pri.none= # Color of priority: tasks\n"
|
||||
"color.pri.H=rgb255 # Color of priority:H tasks\n"
|
||||
"color.pri.M=rgb250 # Color of priority:M tasks\n"
|
||||
"color.pri.L=rgb245 # Color of priority:L tasks\n"
|
||||
"color.tagged=rgb031 # Color of tagged tasks\n"
|
||||
"color.blocked=black on white # Color of blocked tasks\n"
|
||||
#else
|
||||
"color.header=yellow # Color of header messages\n"
|
||||
"color.footnote=yellow # Color of footnote messages\n"
|
||||
"color.debug=yellow # Color of diagnostic output\n"
|
||||
"color.alternate= # Alternate color for line coloring\n"
|
||||
"\n"
|
||||
"color.summary.bar=on green # Color of summary report progress bar\n"
|
||||
"color.summary.background=on black # Color of summary report background\n"
|
||||
|
@ -185,26 +185,29 @@ std::string Config::defaults =
|
|||
"color.calendar.holiday=black on bright yellow # Color of public holidays in calendar\n"
|
||||
"color.calendar.weeknumber=bold blue # Color of the weeknumbers in calendar\n"
|
||||
"\n"
|
||||
"# The following rules are presented in their order of precedence.\n"
|
||||
"# The higher the color rule is up this list, the higher precedence\n"
|
||||
"# it has in determining the color for the task. Precedence is shown\n"
|
||||
"# in brackets [1]\n"
|
||||
"color.recurring=magenta # [1] Color of recur.any: tasks\n"
|
||||
"color.overdue=bold red # [2] Color of overdue tasks\n"
|
||||
"color.due.today=red # [3] Color of tasks due today\n"
|
||||
"color.due=red # [4] Color of due tasks\n"
|
||||
"#color.keyword.car=on blue # [5] Color of description.contains:car tasks\n"
|
||||
"#color.project.garden=on green # [6] Color of project:garden tasks\n"
|
||||
"#color.tag.bug=yellow # [7] Color of +bug tasks\n"
|
||||
"color.active=black on bright green # [8] Color of active tasks\n"
|
||||
"color.pri.none= # [9] Color of priority: tasks\n"
|
||||
"color.pri.H=bold white # [9] Color of priority:H tasks\n"
|
||||
"color.pri.M=white # [9] Color of priority:M tasks\n"
|
||||
"color.pri.L= # [9] Color of priority:L tasks\n"
|
||||
"color.tagged=green # [10] Color of tagged tasks\n"
|
||||
"color.blocked=black on white # [11] Color of blocked tasks\n"
|
||||
"color.alternate= # [12] Alternate color for line coloring\n"
|
||||
"# Here are the color rules.\n"
|
||||
"color.recurring=magenta # Color of recur.any: tasks\n"
|
||||
"color.overdue=bold red # Color of overdue tasks\n"
|
||||
"color.due.today=red # Color of tasks due today\n"
|
||||
"color.due=red # Color of due tasks\n"
|
||||
"#color.keyword.car=on blue # Color of description.contains:car tasks\n"
|
||||
"#color.project.garden=on green # Color of project:garden tasks\n"
|
||||
"#color.project.none= # Color of tasks with no project\n"
|
||||
"#color.tag.bug=yellow # Color of +bug tasks\n"
|
||||
"#color.tag.none= # Color of tag-less tasks\n"
|
||||
"color.active=black on bright green # Color of active tasks\n"
|
||||
"color.pri.none= # Color of priority: tasks\n"
|
||||
"color.pri.H=bold white # Color of priority:H tasks\n"
|
||||
"color.pri.M=white # Color of priority:M tasks\n"
|
||||
"color.pri.L= # Color of priority:L tasks\n"
|
||||
"color.tagged=green # Color of tagged tasks\n"
|
||||
"color.blocked=black on white # Color of blocked tasks\n"
|
||||
#endif
|
||||
"\n"
|
||||
"# Here is the rule precedence order, highest to lowest.\n"
|
||||
"# Note that these are just the color rule names, without the leading 'color.'\n"
|
||||
"# and any trailing '.value'.\n"
|
||||
"rule.precedence.color=due.today,active,blocked,overdue,due,keyword,project,tag,recurring,pri,tagged\n"
|
||||
"\n"
|
||||
"# Shadow file support\n"
|
||||
"#shadow.file=/tmp/shadow.txt # Location of shadow file\n"
|
||||
|
@ -396,6 +399,7 @@ std::string Config::defaults =
|
|||
//
|
||||
// In all real use cases, Config::load is called.
|
||||
Config::Config ()
|
||||
: original_file ()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -125,8 +125,6 @@ void Context::initialize ()
|
|||
if (locale != "")
|
||||
stringtable.load (location.data + "/strings." + locale);
|
||||
|
||||
// TODO Handle "--version, -v" right here?
|
||||
|
||||
// init TDB.
|
||||
tdb.clear ();
|
||||
std::vector <std::string> all;
|
||||
|
|
|
@ -812,6 +812,7 @@ int handleShow (std::string &outs)
|
|||
"import.synonym.id import.synonym.uuid complete.all.projects complete.all.tags "
|
||||
"search.case.sensitive hooks active.indicator tag.indicator recurrence.indicator "
|
||||
"recurrence.limit list.all.projects list.all.tags undo.style verbose "
|
||||
"rule.precedence.color "
|
||||
#ifdef FEATURE_SHELL
|
||||
"shell.prompt "
|
||||
#endif
|
||||
|
@ -2032,7 +2033,7 @@ int handleColor (std::string &outs)
|
|||
// actual colors.
|
||||
if (*item != "_forcecolor" &&
|
||||
*item != "color" &&
|
||||
item->find ("color") != std::string::npos)
|
||||
item->find ("color") == 0)
|
||||
{
|
||||
int row = table.addRow ();
|
||||
table.addCell (row, 0, *item);
|
||||
|
|
|
@ -154,11 +154,15 @@ bool dependencyChainBroken (Task& task)
|
|||
std::string dependencyNag (Task& task)
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
if (task.has ("depends"))
|
||||
{
|
||||
out << "# dependencyNag "
|
||||
<< task.id
|
||||
<< " "
|
||||
<< task.get ("uuid")
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
return out.str ();
|
||||
}
|
||||
|
|
|
@ -114,6 +114,8 @@ void handleRecurrence ()
|
|||
sprintf (indexMask, "%u", (unsigned int) i);
|
||||
rec.set ("imask", indexMask); // Store index into mask.
|
||||
|
||||
rec.remove ("mask"); // Remove the mask of the parent.
|
||||
|
||||
// Add the new task to the vector, for immediate use.
|
||||
modified.push_back (rec);
|
||||
|
||||
|
|
|
@ -470,9 +470,6 @@ int handleInfo (std::string &outs)
|
|||
}
|
||||
}
|
||||
|
||||
if (task->getStatus () == Task::recurring ||
|
||||
task->has ("parent"))
|
||||
{
|
||||
// recur
|
||||
if (task->has ("recur"))
|
||||
{
|
||||
|
@ -499,20 +496,19 @@ int handleInfo (std::string &outs)
|
|||
}
|
||||
|
||||
// mask
|
||||
if (task->has ("mask"))
|
||||
if (task->getStatus () == Task::recurring)
|
||||
{
|
||||
row = table.addRow ();
|
||||
table.addCell (row, 0, "Mask");
|
||||
table.addCell (row, 1, task->get ("mask"));
|
||||
}
|
||||
|
||||
// parent
|
||||
if (task->has ("parent"))
|
||||
{
|
||||
// parent
|
||||
row = table.addRow ();
|
||||
table.addCell (row, 0, "Parent task");
|
||||
table.addCell (row, 1, task->get ("parent"));
|
||||
}
|
||||
|
||||
// imask
|
||||
row = table.addRow ();
|
||||
|
@ -759,7 +755,7 @@ int handleReportSummary (std::string &outs)
|
|||
table.addCell (row, 0, (i->first == "" ? "(none)" : i->first));
|
||||
table.addCell (row, 1, countPending[i->first]);
|
||||
if (counter[i->first])
|
||||
table.addCell (row, 2, Duration ((int) sumEntry[i->first] / counter[i->first]).format ());
|
||||
table.addCell (row, 2, Duration ((int) (sumEntry[i->first] / (double)counter[i->first])).format ());
|
||||
|
||||
int c = countCompleted[i->first];
|
||||
int p = countPending[i->first];
|
||||
|
|
322
src/rules.cpp
322
src/rules.cpp
|
@ -36,137 +36,251 @@
|
|||
extern Context context;
|
||||
|
||||
static std::map <std::string, Color> gsColor;
|
||||
static std::vector <std::string> gsPrecedence;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void initializeColorRules ()
|
||||
{
|
||||
std::vector <std::string> ruleNames;
|
||||
context.config.all (ruleNames);
|
||||
foreach (it, ruleNames)
|
||||
gsColor.clear ();
|
||||
gsPrecedence.clear ();
|
||||
|
||||
// Load all the configuration values, filter to only the ones that begin with
|
||||
// "color.", then store name/value in gsColor, and name in rules.
|
||||
std::vector <std::string> rules;
|
||||
std::vector <std::string> variables;
|
||||
context.config.all (variables);
|
||||
foreach (it, variables)
|
||||
{
|
||||
if (it->substr (0, 6) == "color.")
|
||||
{
|
||||
Color c (context.config.get (*it));
|
||||
gsColor[*it] = c;
|
||||
|
||||
rules.push_back (*it);
|
||||
}
|
||||
}
|
||||
|
||||
// Load the rule.precedence.color list, split it, then autocomplete against
|
||||
// the 'rules' vector loaded above.
|
||||
std::vector <std::string> results;
|
||||
std::vector <std::string> precedence;
|
||||
split (precedence, context.config.get ("rule.precedence.color"), ',');
|
||||
|
||||
foreach (it, precedence)
|
||||
{
|
||||
// Add the leading "color." string.
|
||||
std::string rule = "color." + *it;
|
||||
autoComplete (rule, rules, results);
|
||||
|
||||
foreach (r, results)
|
||||
gsPrecedence.push_back (*r);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizeBlocked (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
if (gsColor[rule].nontrivial ())
|
||||
if (task.get ("depends") != "")
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizeTagged (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
if (gsColor[rule].nontrivial ())
|
||||
if (task.getTagCount ())
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizePriorityL (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
if (gsColor[rule].nontrivial ())
|
||||
if (task.get ("priority") == "L")
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizePriorityM (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
if (gsColor[rule].nontrivial ())
|
||||
if (task.get ("priority") == "M")
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizePriorityH (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
if (gsColor[rule].nontrivial ())
|
||||
if (task.get ("priority") == "H")
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizePriorityNone (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
if (gsColor[rule].nontrivial ())
|
||||
if (task.get ("priority") == "")
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizeActive (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
Task::status status = task.getStatus ();
|
||||
|
||||
if (gsColor[rule].nontrivial () &&
|
||||
status != Task::completed &&
|
||||
status != Task::deleted &&
|
||||
task.has ("start"))
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizeTag (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
if (task.hasTag (rule.substr (10)))
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizeProject (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
// Observe the case sensitivity setting.
|
||||
bool sensitive = context.config.getBoolean ("search.case.sensitive");
|
||||
|
||||
if (compare (task.get ("project"), rule.substr (14), sensitive))
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizeProjectNone (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
if (task.get ("project") == "")
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizeTagNone (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
if (task.getTagCount () == 0)
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizeKeyword (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
// Observe the case sensitivity setting.
|
||||
bool sensitive = context.config.getBoolean ("search.case.sensitive");
|
||||
|
||||
// The easiest thing to check is the description, because it is just one
|
||||
// attribute.
|
||||
if (find (task.get ("description"), rule.substr (14), sensitive) != std::string::npos)
|
||||
c.blend (gsColor[rule]);
|
||||
|
||||
// Failing the description check, look at all annotations, returning on the
|
||||
// first match.
|
||||
else
|
||||
{
|
||||
Task::iterator it;
|
||||
for (it = task.begin (); it != task.end (); ++it)
|
||||
{
|
||||
if (it->first.substr (0, 11) == "annotation_" &&
|
||||
find (it->second.value (), rule.substr (14), sensitive) != std::string::npos)
|
||||
{
|
||||
c.blend (gsColor[rule]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void autoColorize (Task& task, Color& c)
|
||||
static void colorizeDue (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
// The special tag 'nocolor' overrides all auto colorization.
|
||||
if (task.hasTag ("nocolor"))
|
||||
return;
|
||||
|
||||
// Note: fg, bg already contain colors specifically assigned via command.
|
||||
// Note: These rules form a hierarchy - the last rule is King.
|
||||
|
||||
Task::status status = task.getStatus ();
|
||||
|
||||
// Colorization of the blocked.
|
||||
if (gsColor["color.blocked"].nontrivial ())
|
||||
if (task.get ("depends") != "")
|
||||
c.blend (gsColor["color.blocked"]);
|
||||
|
||||
// Colorization of the tagged.
|
||||
if (gsColor["color.tagged"].nontrivial ())
|
||||
if (task.getTagCount ())
|
||||
c.blend (gsColor["color.tagged"]);
|
||||
|
||||
// Colorization of the low priority.
|
||||
if (gsColor["color.pri.L"].nontrivial ())
|
||||
if (task.get ("priority") == "L")
|
||||
c.blend (gsColor["color.pri.L"]);
|
||||
|
||||
// Colorization of the medium priority.
|
||||
if (gsColor["color.pri.M"].nontrivial ())
|
||||
if (task.get ("priority") == "M")
|
||||
c.blend (gsColor["color.pri.M"]);
|
||||
|
||||
// Colorization of the high priority.
|
||||
if (gsColor["color.pri.H"].nontrivial ())
|
||||
if (task.get ("priority") == "H")
|
||||
c.blend (gsColor["color.pri.H"]);
|
||||
|
||||
// Colorization of the priority-less.
|
||||
if (gsColor["color.pri.none"].nontrivial ())
|
||||
if (task.get ("priority") == "")
|
||||
c.blend (gsColor["color.pri.none"]);
|
||||
|
||||
// Colorization of the active, if not completed/deleted.
|
||||
if (gsColor["color.active"].nontrivial () &&
|
||||
status != Task::completed &&
|
||||
status != Task::deleted)
|
||||
if (task.has ("start"))
|
||||
c.blend (gsColor["color.active"]);
|
||||
|
||||
// Colorization by tag value.
|
||||
std::map <std::string, Color>::iterator it;
|
||||
for (it = gsColor.begin (); it != gsColor.end (); ++it)
|
||||
{
|
||||
if (it->first.substr (0, 10) == "color.tag.")
|
||||
{
|
||||
std::string value = it->first.substr (10);
|
||||
if (task.hasTag (value))
|
||||
c.blend (it->second);
|
||||
}
|
||||
}
|
||||
|
||||
// Colorization by project name.
|
||||
for (it = gsColor.begin (); it != gsColor.end (); ++it)
|
||||
{
|
||||
if (it->first.substr (0, 14) == "color.project.")
|
||||
{
|
||||
std::string value = lowerCase (it->first.substr (14));
|
||||
std::string project = lowerCase (task.get ("project"));
|
||||
if (project.find (value) == 0)
|
||||
c.blend (it->second);
|
||||
}
|
||||
}
|
||||
|
||||
// Colorization by keyword.
|
||||
for (it = gsColor.begin (); it != gsColor.end (); ++it)
|
||||
{
|
||||
if (it->first.substr (0, 14) == "color.keyword.")
|
||||
{
|
||||
std::string value = lowerCase (it->first.substr (14));
|
||||
std::string desc = lowerCase (task.get ("description"));
|
||||
if (desc.find (value) != std::string::npos)
|
||||
c.blend (it->second);
|
||||
}
|
||||
}
|
||||
|
||||
// Colorization of the due and overdue.
|
||||
if (task.has ("due") &&
|
||||
status != Task::completed &&
|
||||
status != Task::deleted)
|
||||
{
|
||||
std::string due = task.get ("due");
|
||||
switch (getDueState (due))
|
||||
if (getDueState (task.get ("due")) == 1)
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizeDueToday (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
case 1: // imminent
|
||||
c.blend (gsColor["color.due"]);
|
||||
break;
|
||||
Task::status status = task.getStatus ();
|
||||
|
||||
case 2: // today
|
||||
c.blend (gsColor["color.due.today"]);
|
||||
break;
|
||||
|
||||
case 3: // overdue
|
||||
c.blend (gsColor["color.overdue"]);
|
||||
break;
|
||||
|
||||
case 0: // not due at all
|
||||
default:
|
||||
break;
|
||||
if (task.has ("due") &&
|
||||
status != Task::completed &&
|
||||
status != Task::deleted)
|
||||
{
|
||||
if (getDueState (task.get ("due")) == 2)
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
}
|
||||
|
||||
// Colorization of the recurring.
|
||||
if (gsColor["color.recurring"].nontrivial ())
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizeOverdue (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
Task::status status = task.getStatus ();
|
||||
|
||||
if (task.has ("due") &&
|
||||
status != Task::completed &&
|
||||
status != Task::deleted)
|
||||
{
|
||||
if (getDueState (task.get ("due")) == 3)
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void colorizeRecurring (Task& task, const std::string& rule, Color& c)
|
||||
{
|
||||
if (gsColor[rule].nontrivial ())
|
||||
if (task.has ("recur"))
|
||||
c.blend (gsColor["color.recurring"]);
|
||||
c.blend (gsColor[rule]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void autoColorize (Task& task, Color& c)
|
||||
{
|
||||
// The special tag 'nocolor' overrides all auto and specific colorization.
|
||||
if (task.hasTag ("nocolor"))
|
||||
{
|
||||
c = Color ();
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: c already contains colors specifically assigned via command.
|
||||
// Note: These rules form a hierarchy - the last rule is King, hence the
|
||||
// reverse iterator.
|
||||
std::vector <std::string>::reverse_iterator r;
|
||||
for (r = gsPrecedence.rbegin (); r != gsPrecedence.rend (); ++r)
|
||||
{
|
||||
if (*r == "color.blocked") colorizeBlocked (task, *r, c);
|
||||
else if (*r == "color.tagged") colorizeTagged (task, *r, c);
|
||||
else if (*r == "color.pri.L") colorizePriorityL (task, *r, c);
|
||||
else if (*r == "color.pri.M") colorizePriorityM (task, *r, c);
|
||||
else if (*r == "color.pri.H") colorizePriorityH (task, *r, c);
|
||||
else if (*r == "color.pri.none") colorizePriorityNone (task, *r, c);
|
||||
else if (*r == "color.active") colorizeActive (task, *r, c);
|
||||
else if (*r == "color.project.none") colorizeProjectNone (task, *r, c);
|
||||
else if (*r == "color.tag.none") colorizeTagNone (task, *r, c);
|
||||
else if (*r == "color.due") colorizeDue (task, *r, c);
|
||||
else if (*r == "color.due.today") colorizeDueToday (task, *r, c);
|
||||
else if (*r == "color.overdue") colorizeOverdue (task, *r, c);
|
||||
else if (*r == "color.recurring") colorizeRecurring (task, *r, c);
|
||||
|
||||
// Wildcards
|
||||
else if (r->substr (0, 9) == "color.tag") colorizeTag (task, *r, c);
|
||||
else if (r->substr (0, 13) == "color.project") colorizeProject (task, *r, c);
|
||||
else if (r->substr (0, 13) == "color.keyword") colorizeKeyword (task, *r, c);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 13;
|
||||
use Test::More tests => 40;
|
||||
|
||||
# Create the rc file.
|
||||
if (open my $fh, '>', 'bug.rc')
|
||||
|
@ -59,6 +59,67 @@ $output = qx{../task rc:bug.rc long -\@strange};
|
|||
like ($output, qr/one/, '+ordinary implicitly included');
|
||||
unlike ($output, qr/two/, '@strange explicitly excluded');
|
||||
|
||||
# Bug #XXX - '-t1 -t2' doesn't seem to work, when @ characters are involved.
|
||||
unlink 'pending.data';
|
||||
qx{../task rc:bug.rc add one +t1};
|
||||
qx{../task rc:bug.rc add two +t2};
|
||||
qx{../task rc:bug.rc add three +t3};
|
||||
|
||||
my $output = qx{../task rc:bug.rc list -t1};
|
||||
unlike ($output, qr/one/, 'Single: no t1');
|
||||
like ($output, qr/two/, 'Single: yes t2');
|
||||
like ($output, qr/three/, 'Single: yes t3');
|
||||
|
||||
$output = qx{../task rc:bug.rc list -t1 -t2};
|
||||
unlike ($output, qr/one/, 'Double: no t1');
|
||||
unlike ($output, qr/two/, 'Double: no t2');
|
||||
like ($output, qr/three/, 'Double: yes t3');
|
||||
|
||||
$output = qx{../task rc:bug.rc list -t1 -t2 -t3};
|
||||
unlike ($output, qr/one/, 'Triple: no t1');
|
||||
unlike ($output, qr/two/, 'Triple: no t2');
|
||||
unlike ($output, qr/three/, 'Triple: no t3');
|
||||
|
||||
# Once again, with @ characters.
|
||||
qx{../task rc:bug.rc 1 +\@1};
|
||||
qx{../task rc:bug.rc 2 +\@2};
|
||||
qx{../task rc:bug.rc 3 +\@3};
|
||||
|
||||
$output = qx{../task rc:bug.rc list -\@1};
|
||||
unlike ($output, qr/one/, 'Single: no @1');
|
||||
like ($output, qr/two/, 'Single: yes @2');
|
||||
like ($output, qr/three/, 'Single: yes @3');
|
||||
|
||||
$output = qx{../task rc:bug.rc list -\@1 -\@2};
|
||||
unlike ($output, qr/one/, 'Double: no @1');
|
||||
unlike ($output, qr/two/, 'Double: no @2');
|
||||
like ($output, qr/three/, 'Double: yes @3');
|
||||
|
||||
$output = qx{../task rc:bug.rc list -\@1 -\@2 -\@3};
|
||||
unlike ($output, qr/one/, 'Triple: no @1');
|
||||
unlike ($output, qr/two/, 'Triple: no @2');
|
||||
unlike ($output, qr/three/, 'Triple: no @3');
|
||||
|
||||
# Once again, with @ characters and punctuation.
|
||||
qx{../task rc:bug.rc 1 +\@foo.1};
|
||||
qx{../task rc:bug.rc 2 +\@foo.2};
|
||||
qx{../task rc:bug.rc 3 +\@foo.3};
|
||||
|
||||
$output = qx{../task rc:bug.rc list -\@foo.1};
|
||||
unlike ($output, qr/one/, 'Single: no @foo.1');
|
||||
like ($output, qr/two/, 'Single: yes @foo.2');
|
||||
like ($output, qr/three/, 'Single: yes @foo.3');
|
||||
|
||||
$output = qx{../task rc:bug.rc list -\@foo.1 -\@foo.2};
|
||||
unlike ($output, qr/one/, 'Double: no @foo.1');
|
||||
unlike ($output, qr/two/, 'Double: no @foo.2');
|
||||
like ($output, qr/three/, 'Double: yes @foo.3');
|
||||
|
||||
$output = qx{../task rc:bug.rc list -\@foo.1 -\@foo.2 -\@foo.3};
|
||||
unlike ($output, qr/one/, 'Triple: no @foo.1');
|
||||
unlike ($output, qr/two/, 'Triple: no @foo.2');
|
||||
unlike ($output, qr/three/, 'Triple: no @foo.3');
|
||||
|
||||
# Cleanup.
|
||||
unlink 'pending.data';
|
||||
ok (!-r 'pending.data', 'Removed pending.data');
|
||||
|
|
66
src/tests/bug.485.x
Executable file
66
src/tests/bug.485.x
Executable file
|
@ -0,0 +1,66 @@
|
|||
#! /usr/bin/perl
|
||||
################################################################################
|
||||
## taskwarrior - a command line task list manager.
|
||||
##
|
||||
## Copyright 2006 - 2010, 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
|
||||
##
|
||||
################################################################################
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 9;
|
||||
|
||||
# Create the rc file.
|
||||
if (open my $fh, '>', 'bug.rc')
|
||||
{
|
||||
print $fh "data.location=.\n";
|
||||
|
||||
close $fh;
|
||||
ok (-r 'bug.rc', 'Created bug.rc');
|
||||
}
|
||||
|
||||
# Bug #485 - 'task list recur:month' doesn't list monthly tasks
|
||||
qx{../task rc:bug.rc add one due:tomorrow recur:monthly};
|
||||
qx{../task rc:bug.rc add two due:tomorrow recur:month};
|
||||
my $output = qx{../task rc:bug.rc list recur:monthly};
|
||||
like ($output, qr/one/, 'monthly -> monthly');
|
||||
like ($output, qr/two/, 'month -> monthly');
|
||||
|
||||
$output = qx{../task rc:bug.rc list recur:month};
|
||||
like ($output, qr/one/, 'monthly -> month');
|
||||
like ($output, qr/two/, 'month -> month');
|
||||
|
||||
# Cleanup.
|
||||
unlink 'pending.data';
|
||||
ok (!-r 'pending.data', 'Removed pending.data');
|
||||
|
||||
unlink 'completed.data';
|
||||
ok (!-r 'completed.data', 'Removed completed.data');
|
||||
|
||||
unlink 'undo.data';
|
||||
ok (!-r 'undo.data', 'Removed undo.data');
|
||||
|
||||
unlink 'bug.rc';
|
||||
ok (!-r 'bug.rc', 'Removed bug.rc');
|
||||
|
||||
exit 0;
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
## taskwarrior - a command line task list manager.
|
||||
##
|
||||
## Copyright 2006 - 2010, Paul Beckingham.
|
||||
## Copyright 2006 - 2010, Paul Beckingham, Federico Hernandez.
|
||||
## All rights reserved.
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify it under
|
||||
|
@ -28,15 +28,18 @@
|
|||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 8;
|
||||
use Test::More tests => 9;
|
||||
|
||||
# Create the rc file.
|
||||
if (open my $fh, '>', 'color.rc')
|
||||
{
|
||||
print $fh "data.location=.\n",
|
||||
"search.case.sensitive=yes\n",
|
||||
"color=on\n",
|
||||
"color.alternate=\n",
|
||||
"color.keyword.red=red\n",
|
||||
"color.keyword.green=green\n",
|
||||
"color.keyword.yellow=yellow\n",
|
||||
"_forcecolor=1\n";
|
||||
close $fh;
|
||||
ok (-r 'color.rc', 'Created color.rc');
|
||||
|
@ -46,11 +49,14 @@ if (open my $fh, '>', 'color.rc')
|
|||
qx{../task rc:color.rc add nothing};
|
||||
qx{../task rc:color.rc add red};
|
||||
qx{../task rc:color.rc add green};
|
||||
qx{../task rc:color.rc add -- annotation};
|
||||
qx{../task rc:color.rc 4 annotate yellow};
|
||||
my $output = qx{../task rc:color.rc list};
|
||||
|
||||
like ($output, qr/ (?!<\033\[\d\dm) .* nothing .* (?!>\033\[0m) /x, 'none');
|
||||
like ($output, qr/ \033\[31m .* red .* \033\[0m /x, 'color.keyword.red');
|
||||
like ($output, qr/ \033\[32m .* green .* \033\[0m /x, 'color.keyword.green');
|
||||
like ($output, qr/ \033\[33m .* annotation .* \033\[0m /x, 'color.keyword.yellow (annotation)');
|
||||
|
||||
# Cleanup.
|
||||
unlink 'pending.data';
|
||||
|
|
|
@ -35,6 +35,7 @@ if (open my $fh, '>', 'color.rc')
|
|||
{
|
||||
print $fh "data.location=.\n",
|
||||
"color.project.x=red\n",
|
||||
"color.project.none=green\n",
|
||||
"color.alternate=\n",
|
||||
"_forcecolor=1\n";
|
||||
close $fh;
|
||||
|
@ -46,7 +47,7 @@ qx{../task rc:color.rc add nothing};
|
|||
qx{../task rc:color.rc add project:x red};
|
||||
my $output = qx{../task rc:color.rc list};
|
||||
|
||||
like ($output, qr/ (?!<\033\[\d\dm) .* nothing .* (?!>\033\[0m) /x, 'none');
|
||||
like ($output, qr/ \033\[32m .* nothing .* \033\[0m /x, 'color.project.none');
|
||||
like ($output, qr/ \033\[31m .* red .* \033\[0m /x, 'color.project.red');
|
||||
|
||||
# Cleanup.
|
||||
|
|
|
@ -36,6 +36,7 @@ if (open my $fh, '>', 'color.rc')
|
|||
print $fh "data.location=.\n",
|
||||
"color.tagged=\n",
|
||||
"color.alternate=\n",
|
||||
"color.tag.none=yellow\n",
|
||||
"color.tag.red=red\n",
|
||||
"color.tag.green=green\n",
|
||||
"_forcecolor=1\n";
|
||||
|
@ -49,7 +50,7 @@ qx{../task rc:color.rc add +red red};
|
|||
qx{../task rc:color.rc add +green green};
|
||||
my $output = qx{../task rc:color.rc list};
|
||||
|
||||
like ($output, qr/ (?!<\033\[\d\dm) .* nothing .* (?!>\033\[0m) /x, 'none');
|
||||
like ($output, qr/ \033\[33m .* nothing .* \033\[0m /x, 'color.tag.none');
|
||||
like ($output, qr/ \033\[31m .* red .* \033\[0m /x, 'color.tag.red');
|
||||
like ($output, qr/ \033\[32m .* green .* \033\[0m /x, 'color.tag.green');
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 7;
|
||||
use Test::More tests => 9;
|
||||
|
||||
# Create the rc file.
|
||||
if (open my $fh, '>', 'due.rc')
|
||||
|
@ -57,6 +57,13 @@ my $output = qx{../task rc:due.rc list};
|
|||
like ($output, qr/\[31m.+$just.+\[0m/, 'one marked due');
|
||||
like ($output, qr/\s+$almost\s+/, 'two not marked due');
|
||||
|
||||
qx{../task rc:due.rc add three due:today};
|
||||
$output = qx{../task rc:due.rc list due:today};
|
||||
like ($output, qr/three/, 'due:today works as a filter');
|
||||
|
||||
$output = qx{../task rc:due.rc list due.is:today};
|
||||
like ($output, qr/three/, 'due.is:today works as a filter');
|
||||
|
||||
# Cleanup.
|
||||
unlink 'pending.data';
|
||||
ok (!-r 'pending.data', 'Removed pending.data');
|
||||
|
|
|
@ -71,8 +71,8 @@ qx{../task rc:wait.rc add wait:tomorrow tomorrow};
|
|||
$output = qx{../task rc:wait.rc ls};
|
||||
unlike ($output, qr/tomorrow/ms, 'waiting task invisible');
|
||||
|
||||
$output = qx{../task rc:wait.rc ls wait:tomorrow};
|
||||
like ($output, qr/tomorrow/ms, 'waiting task visible when specifically asked for it');
|
||||
$output = qx{../task rc:wait.rc all status:waiting wait:tomorrow};
|
||||
like ($output, qr/tomorrow/ms, 'waiting task visible when specifically queried');
|
||||
|
||||
# Cleanup.
|
||||
unlink 'pending.data';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue