diff --git a/ChangeLog b/ChangeLog index a0fec7283..14bff99ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,12 @@ to Juergen Daubert). + Fixed bug #327 that allowed the removal of a due date from a recurring task. + + Fixed bug #317 which colored tasks in the 'completed' report according to + due dates, which are no longer relevant to a completed task (thanks to + Cory Donnelly). + + Fixed bug that was causing the 'completed' report to sort incorrectly. + + Fixed bug #322 which failed to propagate rc overrides to shell commands. + + Fixed redundant messages when exiting shell mode. ------ old releases ------------------------------ diff --git a/src/Context.cpp b/src/Context.cpp index 1b7ba1072..ed76022ff 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -50,7 +50,8 @@ Context::Context () , tdb () , stringtable () , program ("") -, overrides ("") +, file_override ("") +, var_overrides ("") , cmd () , inShadow (false) { @@ -66,6 +67,7 @@ void Context::initialize (int argc, char** argv) { // Capture the args. for (int i = 0; i < argc; ++i) + { if (i == 0) { program = argv[i]; @@ -76,6 +78,7 @@ void Context::initialize (int argc, char** argv) } else args.push_back (argv[i]); + } initialize (); } @@ -350,13 +353,14 @@ void Context::loadCorrectConfigFile () std::string rc = home + "/.taskrc"; std::string data = home + "/.task"; - // Is there an override for rc? + // Is there an file_override for rc:? foreach (arg, args) { if (*arg == "--") break; else if (arg->substr (0, 3) == "rc:") { + file_override = *arg; rc = arg->substr (3, std::string::npos); home = rc; @@ -380,7 +384,7 @@ void Context::loadCorrectConfigFile () if (config.get ("data.location") != "") data = config.get ("data.location"); - // Is there an override for data? + // Are there any var_overrides for data.location? foreach (arg, args) { if (*arg == "--") @@ -440,7 +444,7 @@ void Context::loadCorrectConfigFile () n.getUntilEOS (value)) { config.set (name, value); - overrides += " " + *arg; + var_overrides += " " + *arg; footnote (std::string ("Configuration override ") + // TODO i18n arg->substr (3, std::string::npos)); } @@ -658,15 +662,21 @@ void Context::parse ( if (parseCmd.command == "" && parseArgs.size () == 0) { // Apply overrides, if any. - std::string defaultCommand = config.get ("default.command") + overrides; + std::string defaultCommand = config.get ("default.command"); if (defaultCommand != "") { + // Add on the overrides. + defaultCommand += " " + file_override + " " + var_overrides; + // Stuff the command line. args.clear (); split (args, defaultCommand, ' '); header ("[task " + defaultCommand + "]"); // Reinitialize the context and recurse. + file_override = ""; + var_overrides = ""; + footnotes.clear (); initialize (); parse (args, cmd, task, sequence, subst, filter); } @@ -691,6 +701,8 @@ void Context::clear () // stringtable.clear (); program = ""; args.clear (); + file_override = ""; + var_overrides = ""; cmd.command = ""; tagAdditions.clear (); tagRemovals.clear (); diff --git a/src/Context.h b/src/Context.h index e903bb8a7..bf56675bc 100644 --- a/src/Context.h +++ b/src/Context.h @@ -83,7 +83,8 @@ public: StringTable stringtable; std::string program; std::vector args; - std::string overrides; + std::string file_override; + std::string var_overrides; Cmd cmd; std::map aliases; std::vector tagAdditions; diff --git a/src/command.cpp b/src/command.cpp index c359171c7..964d7d669 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -1169,13 +1169,9 @@ void handleShell () << std::endl << std::endl; - // Preserve any special override arguments, and reapply them for each - // shell command. - std::vector special; - foreach (arg, context.args) - if (arg->substr (0, 3) == "rc." || - arg->substr (0, 3) == "rc:") - special.push_back (*arg); + // Make a copy because context.clear will delete them. + std::string permanentOverrides = " " + context.file_override + + " " + context.var_overrides; std::string quit = "quit"; // TODO i18n std::string command; @@ -1187,8 +1183,10 @@ void handleShell () command = ""; std::getline (std::cin, command); - command = trim (command); + std::string decoratedCommand = trim (command + permanentOverrides); + // When looking for the 'quit' command, use 'command', not + // 'decoratedCommand'. if (command.length () > 0 && command.length () <= quit.length () && lowerCase (command) == quit.substr (0, command.length ())) @@ -1202,8 +1200,7 @@ void handleShell () context.clear (); std::vector args; - split (args, command, ' '); - foreach (arg, special) context.args.push_back (*arg); + split (args, decoratedCommand, ' '); foreach (arg, args) context.args.push_back (*arg); context.initialize (); @@ -1222,6 +1219,9 @@ void handleShell () } } while (keepGoing && !std::cin.eof ()); + + // No need to repeat any overrides after the shell quits. + context.clearMessages (); } #endif diff --git a/src/custom.cpp b/src/custom.cpp index 7c9e73d61..4d15779eb 100644 --- a/src/custom.cpp +++ b/src/custom.cpp @@ -461,6 +461,7 @@ int runCustomReport ( std::string column = sortColumn->substr (0, sortColumn->length () - 1); char direction = (*sortColumn)[sortColumn->length () - 1]; + // TODO This code should really be using Att::type. if (column == "id") table.sortOn (columnIndex[column], (direction == '+' ? diff --git a/src/rules.cpp b/src/rules.cpp index 604c5eb3c..484f868a8 100644 --- a/src/rules.cpp +++ b/src/rules.cpp @@ -91,6 +91,8 @@ void autoColorize ( // 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 tagged. if (gsFg["color.tagged"] != Text::nocolor || gsBg["color.tagged"] != Text::nocolor) @@ -146,9 +148,11 @@ void autoColorize ( } } - // Colorization of the active. - if (gsFg["color.active"] != Text::nocolor || - gsBg["color.active"] != Text::nocolor) + // Colorization of the active, if not completed/deleted. + if ((gsFg["color.active"] != Text::nocolor || + gsBg["color.active"] != Text::nocolor) && + status != Task::completed && + status != Task::deleted) { if (task.has ("start")) { @@ -202,7 +206,9 @@ void autoColorize ( } // Colorization of the due and overdue. - if (task.has ("due")) + if (task.has ("due") && + status != Task::completed && + status != Task::deleted) { std::string due = task.get ("due"); switch (getDueState (due)) diff --git a/src/tests/bug.bulk.t b/src/tests/bug.bulk.t index 2016abc13..5c8d9602c 100755 --- a/src/tests/bug.bulk.t +++ b/src/tests/bug.bulk.t @@ -28,7 +28,7 @@ use strict; use warnings; -use Test::More tests => 14; +use Test::More tests => 15; # Create the rc file. if (open my $fh, '>', 'bulk.rc') @@ -49,13 +49,13 @@ qx{../task rc:bulk.rc add t4 due:thursday}; qx{../task rc:bulk.rc add t5 due:friday}; qx{../task rc:bulk.rc add t6 due:saturday}; -my $output = qx{yes|../task rc:bulk.rc pro:p1 pri:M 4 5 6}; +my $output = qx{echo "quit"|../task rc:bulk.rc pro:p1 pri:M 4 5 6}; +like ($output, qr/Modified 0 tasks/, '"quit" prevents any further modifications'); + +my $output = qx{echo "all"|../task rc:bulk.rc pro:p1 pri:M 4 5 6}; unlike ($output, qr/Task 4 "t4"\n - No changes were made/, 'Task 4 modified'); unlike ($output, qr/Task 5 "t5"\n - No changes were made/, 'Task 5 modified'); unlike ($output, qr/Task 6 "t6"\n - No changes were made/, 'Task 6 modified'); -#diag ("---"); -#diag ($output); -#diag ("---"); $output = qx{../task rc:bulk.rc info 4}; like ($output, qr/Project\s+p1/, 'project applied to 4'); diff --git a/src/text.cpp b/src/text.cpp index d980b7c34..793ebc0f1 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -57,14 +57,16 @@ void wrapText ( void split ( std::vector& results, const std::string& input, - const char delimiter) + const char delimiter, + bool nontrivial /* = true */) { results.clear (); std::string::size_type start = 0; std::string::size_type i; while ((i = input.find (delimiter, start)) != std::string::npos) { - results.push_back (input.substr (start, i - start)); + if (!nontrivial || i != start) + results.push_back (input.substr (start, i - start)); start = i + 1; } @@ -76,7 +78,8 @@ void split ( void split ( std::vector& results, const std::string& input, - const std::string& delimiter) + const std::string& delimiter, + bool nontrivial /* = true */) { results.clear (); std::string::size_type length = delimiter.length (); @@ -85,7 +88,8 @@ void split ( std::string::size_type i; while ((i = input.find (delimiter, start)) != std::string::npos) { - results.push_back (input.substr (start, i - start)); + if (!nontrivial || i != start) + results.push_back (input.substr (start, i - start)); start = i + length; } diff --git a/src/text.h b/src/text.h index 95eb718a7..bb82cb6fa 100644 --- a/src/text.h +++ b/src/text.h @@ -38,8 +38,8 @@ std::string trimRight (const std::string& in, const std::string& t = " "); std::string trim (const std::string& in, const std::string& t = " "); std::string unquoteText (const std::string&); void extractLine (std::string&, std::string&, int); -void split (std::vector&, const std::string&, const char); -void split (std::vector&, const std::string&, const std::string&); +void split (std::vector&, const std::string&, const char, bool nontrivial = true); +void split (std::vector&, const std::string&, const std::string&, bool nontrivial = true); void join (std::string&, const std::string&, const std::vector&); std::string commify (const std::string&); std::string lowerCase (const std::string&);