diff --git a/ChangeLog b/ChangeLog index e28469f60..32d8a1a3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,7 +32,7 @@ 'blanklines'. + The 'verbose' configuration variable now accepts a specific list of items to be verbose about. See taskrc(5). - + New 'exec' command that runs external programs. + + New 'execute' command that runs external programs. # Tracked Features, sorted by ID. + Added feature #330, which supports the 'inverse' color attribute. diff --git a/NEWS b/NEWS index fa1117f06..767d94350 100644 --- a/NEWS +++ b/NEWS @@ -16,7 +16,7 @@ New Features in taskwarrior 2.0.0 - Performance enhancements. - New 'next' report, that gauges urgency and reports the most urgent tasks. - Fine control of verbosity through the 'verbose=' configuration variable. - - New 'exec' command that runs external scripts/programs. + - New 'execute' command that runs external scripts/programs. Please refer to the ChangeLog file for full details. There are too many to list here. diff --git a/doc/man/task.1.in b/doc/man/task.1.in index 302790c52..f7615493a 100644 --- a/doc/man/task.1.in +++ b/doc/man/task.1.in @@ -209,6 +209,12 @@ to achieve this: This example first gets the IDs for the project:Home filter, then sets the priority to H for each of those tasks. +.TP +.B execute +Executes the specified command. Not useful by itself, but when used in +conjunction with aliases and extensions can provide seamless extension +integration. + .TP .B version Shows the taskwarrior version number @@ -217,7 +223,7 @@ Shows the taskwarrior version number .B help Shows the long usage text. -.TP +.TP .B show [all | substring]" Shows all the current settings in the taskwarrior configuration file. If a substring is specified just the settings containing that substring will be diff --git a/scripts/extensions/command.lua b/scripts/extensions/command.lua index 7616c3438..8839a8113 100644 --- a/scripts/extensions/command.lua +++ b/scripts/extensions/command.lua @@ -15,6 +15,12 @@ function install () '© 2011, Göteborg Bit Factory' -- Copyright end +-- Arguments: None +-- Returns: Usage syntax, such as "task random" +function usage () + return 'task random' +end + -- Arguments: None -- Returns: Valid Taskwarrior BNF, minimally defining a production rule that -- has the same name as the command itself diff --git a/src/Context.cpp b/src/Context.cpp index 157cf3cd6..2749c90bb 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -119,7 +119,8 @@ void Context::initialize2 (int argc, char** argv) // TODO Load relevant rc file. // Instantiate built-in command objects. - commands["exec"] = Command::factory ("exec"); + commands["execute"] = Command::factory ("execute"); + commands["help"] = Command::factory ("help"); commands["install"] = Command::factory ("install"); commands["logo"] = Command::factory ("_logo"); @@ -280,7 +281,6 @@ int Context::dispatch (std::string &out) else if (cmd.command == "version") { rc = handleVersion (out); } else if (cmd.command == "config") { rc = handleConfig (out); } else if (cmd.command == "show") { rc = handleShow (out); } - else if (cmd.command == "help") { rc = longUsage (out); } else if (cmd.command == "stats") { rc = handleReportStats (out); } else if (cmd.command == "info") { rc = handleInfo (out); } else if (cmd.command == "history.monthly") { rc = handleReportHistoryMonthly (out); } diff --git a/src/commands/CMakeLists.txt b/src/commands/CMakeLists.txt index 03c6a3188..a4dcdb724 100644 --- a/src/commands/CMakeLists.txt +++ b/src/commands/CMakeLists.txt @@ -6,6 +6,7 @@ include_directories (${CMAKE_SOURCE_DIR}/src set (commands_SRCS Command.cpp Command.h CmdExec.cpp CmdExec.h + CmdHelp.cpp CmdHelp.h CmdInstall.cpp CmdInstall.h CmdLogo.cpp CmdLogo.h) diff --git a/src/commands/CmdExec.cpp b/src/commands/CmdExec.cpp index 055e5e1db..3cc03856a 100644 --- a/src/commands/CmdExec.cpp +++ b/src/commands/CmdExec.cpp @@ -35,6 +35,8 @@ extern Context context; CmdExec::CmdExec () : _external_command ("") { + _usage = "task execute "; + _description = "Executes external commands and scripts"; _read_only = false; _displays_id = true; } @@ -42,8 +44,12 @@ CmdExec::CmdExec () //////////////////////////////////////////////////////////////////////////////// bool CmdExec::implements (const std::string& command_line) { + _external_command = ""; if (context.args.size () > 1 && - (context.args[0] == "exec" || + (context.args[0] == "execute" || + context.args[0] == "execut" || + context.args[0] == "execu" || + context.args[0] == "exec" || context.args[0] == "exe" || context.args[0] == "ex")) { diff --git a/src/commands/CmdHelp.cpp b/src/commands/CmdHelp.cpp new file mode 100644 index 000000000..248735f2e --- /dev/null +++ b/src/commands/CmdHelp.cpp @@ -0,0 +1,374 @@ +//////////////////////////////////////////////////////////////////////////////// +// taskwarrior - a command line task list manager. +// +// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez. +// 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 +#include +#include +#include + +extern Context context; + +//////////////////////////////////////////////////////////////////////////////// +CmdHelp::CmdHelp () +{ + _usage = "task help"; + _description = "Displays this usage help text"; + _read_only = true; + _displays_id = false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool CmdHelp::implements (const std::string& command_line) +{ + if (context.args.size () && + (context.args[0] == "help" || + context.args[0] == "hel" || + context.args[0] == "he")) + { + return true; + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +int CmdHelp::execute (const std::string& command_line, std::string& output) +{ + ViewText view; + view.width (context.getWidth ()); + view.add (Column::factory ("string.left", "")); + view.add (Column::factory ("string.left", "")); + view.add (Column::factory ("string.left", "")); + + // Static first row. + int row = view.addRow (); + view.set (row, 0, "Usage:"); + view.set (row, 1, "task"); + + // Obsolete method of getting a list of all commands. + std::vector all; + std::map ::iterator i; + for (i = context.commands.begin (); i != context.commands.end (); ++i) + all.push_back (i->first); + + // Sort alphabetically. + std::sort (all.begin (), all.end ()); + + foreach (name, all) + { + row = view.addRow (); + view.set (row, 1, context.commands[*name]->usage ()); + view.set (row, 2, context.commands[*name]->description ()); + } + +/* + row = view.addRow (); + view.set (row, 1, "task add [tags] [attrs] desc..."); + view.set (row, 2, "Adds a new task."); + + row = view.addRow (); + view.set (row, 1, "task log [tags] [attrs] desc..."); + view.set (row, 2, "Adds a new task that is already completed."); + + row = view.addRow (); + view.set (row, 1, "task append ID [tags] [attrs] desc..."); + view.set (row, 2, "Appends more description to an existing task."); + + row = view.addRow (); + view.set (row, 1, "task prepend ID [tags] [attrs] desc..."); + view.set (row, 2, "Prepends more description to an existing task."); + + row = view.addRow (); + view.set (row, 1, "task annotate ID desc..."); + view.set (row, 2, "Adds an annotation to an existing task."); + + row = view.addRow (); + view.set (row, 1, "task denotate ID desc..."); + view.set (row, 2, "Deletes an annotation of an existing task."); + + row = view.addRow (); + view.set (row, 1, "task ID [tags] [attrs] [desc...]"); + view.set (row, 2, "Modifies the existing task with provided arguments."); + + row = view.addRow (); + view.set (row, 1, "task ID /from/to/g"); + view.set (row, 2, "Performs substitution on the task description and " + "annotations. The 'g' is optional, and causes " + "substitutions for all matching text, not just the " + "first occurrence."); + + row = view.addRow (); + view.set (row, 1, "task ID"); + view.set (row, 2, "Specifying an ID without a command invokes the 'info' command."); + + row = view.addRow (); + view.set (row, 1, "task edit ID"); + view.set (row, 2, "Launches an editor to let you modify all aspects of a task directly, therefore it is to be used carefully."); + + row = view.addRow (); + view.set (row, 1, "task undo"); + view.set (row, 2, "Reverts the most recent action."); + + row = view.addRow (); + view.set (row, 1, "task shell"); + view.set (row, 2, "Launches an interactive shell."); + + row = view.addRow (); + view.set (row, 1, "task duplicate ID [tags] [attrs] [desc...]"); + view.set (row, 2, "Duplicates the specified task, and allows modifications."); + + row = view.addRow (); + view.set (row, 1, "task delete ID"); + view.set (row, 2, "Deletes the specified task."); + + row = view.addRow (); + view.set (row, 1, "task info ID"); + view.set (row, 2, "Shows all data, metadata for specified task."); + + row = view.addRow (); + view.set (row, 1, "task start ID"); + view.set (row, 2, "Marks specified task as started."); + + row = view.addRow (); + view.set (row, 1, "task stop ID"); + view.set (row, 2, "Removes the 'start' time from a task."); + + row = view.addRow (); + view.set (row, 1, "task done ID [tags] [attrs] [desc...]"); + view.set (row, 2, "Marks the specified task as completed."); + + row = view.addRow (); + view.set (row, 1, "task projects"); + view.set (row, 2, "Shows a list of all project names used, and how many tasks are in each."); + + row = view.addRow (); + view.set (row, 1, "task tags"); + view.set (row, 2, "Shows a list of all tags used."); + + row = view.addRow (); + view.set (row, 1, "task summary"); + view.set (row, 2, "Shows a report of task status by project."); + + row = view.addRow (); + view.set (row, 1, "task timesheet [weeks]"); + view.set (row, 2, "Shows a weekly report of tasks completed and started."); + + row = view.addRow (); + view.set (row, 1, "task history"); + view.set (row, 2, "Shows a report of task history, by month. Alias to history.monthly."); + + row = view.addRow (); + view.set (row, 1, "task history.annual"); + view.set (row, 2, "Shows a report of task history, by year."); + + row = view.addRow (); + view.set (row, 1, "task ghistory"); + view.set (row, 2, "Shows a graphical report of task history, by month. Alias to ghistory.monthly."); + + row = view.addRow (); + view.set (row, 1, "task ghistory.annual"); + view.set (row, 2, "Shows a graphical report of task history, by year."); + + row = view.addRow (); + view.set (row, 1, "task burndown.daily"); + view.set (row, 2, "Shows a graphical burndown chart, by day."); + + row = view.addRow (); + view.set (row, 1, "task burndown.weekly"); + view.set (row, 2, "Shows a graphical burndown chart, by week."); + + row = view.addRow (); + view.set (row, 1, "task burndown.monthly"); + view.set (row, 2, "Shows a graphical burndown chart, by month."); + + row = view.addRow (); + view.set (row, 1, "task calendar [due|month year|year]"); + view.set (row, 2, "Shows a calendar, with due tasks marked."); + + row = view.addRow (); + view.set (row, 1, "task stats"); + view.set (row, 2, "Shows task database statistics."); + + row = view.addRow (); + view.set (row, 1, "task import"); + view.set (row, 2, "Imports tasks from a variety of formats."); + + row = view.addRow (); + view.set (row, 1, "task export"); + view.set (row, 2, "Lists all tasks in CSV format. Alias to export.csv"); + + row = view.addRow (); + view.set (row, 1, "task export.csv"); + view.set (row, 2, "Lists all tasks in CSV format."); + + row = view.addRow (); + view.set (row, 1, "task export.ical"); + view.set (row, 2, "Lists all tasks in iCalendar format."); + + row = view.addRow (); + view.set (row, 1, "task export.yaml"); + view.set (row, 2, "Lists all tasks in YAML format."); + + row = view.addRow (); + view.set (row, 1, "task merge URL"); + view.set (row, 2, "Merges the specified undo.data file with the local data files."); + + row = view.addRow (); + view.set (row, 1, "task push URL"); + view.set (row, 2, "Pushes the local *.data files to the URL."); + + row = view.addRow (); + view.set (row, 1, "task pull URL"); + view.set (row, 2, "Overwrites the local *.data files with those found at the URL."); + + row = view.addRow (); + view.set (row, 1, "task color [sample | legend]"); + view.set (row, 2, "Displays all possible colors, a named sample, or a " + "legend containing all currently defined colors."); + + row = view.addRow (); + view.set (row, 1, "task count [filter]"); + view.set (row, 2, "Shows only the number of matching tasks."); + + row = view.addRow (); + view.set (row, 1, "task ids [filter]"); + view.set (row, 2, "Shows only the IDs of matching tasks, in the form of a range."); + + row = view.addRow (); + view.set (row, 1, "task version"); + view.set (row, 2, "Shows the task version number."); + + row = view.addRow (); + view.set (row, 1, "task show [all | substring]"); + view.set (row, 2, "Shows the entire task configuration variables or the ones containing substring."); + + row = view.addRow (); + view.set (row, 1, "task config [name [value | '']]"); + view.set (row, 2, "Add, modify and remove settings in the task configuration."); + + row = view.addRow (); + view.set (row, 1, "task diagnostics"); + view.set (row, 2, "Information needed when reporting a problem."); + + row = view.addRow (); + view.set (row, 1, "task help"); + view.set (row, 2, "Shows the long usage text."); +*/ + +/* + // TODO Add custom reports here... + std::vector all; + context.cmd.allCustomReports (all); + foreach (report, all) + { + std::string command = std::string ("task ") + *report + std::string (" [tags] [attrs] desc..."); + std::string description = context.config.get (std::string ("report.") + *report + ".description"); + if (description == "") + description = "(missing description)"; + + row = view.addRow (); + view.set (row, 1, command); + view.set (row, 2, description); + } +*/ + + output = "\n" + + view.render () + + "\n" + + "Documentation for taskwarrior can be found using 'man task', " + "'man taskrc', 'man task-tutorial', 'man task-color', 'man task-faq' " + "or at http://taskwarrior.org" + + "\n" + + "\n" + + "ID is the numeric identifier displayed by the 'task list' command. " + "You can specify multiple IDs for task commands, and multiple tasks " + "will be affected. To specify multiple IDs make sure you use one " + "of these forms:\n" + " task delete 1,2,3\n" + " task info 1-3\n" + " task pri:H 1,2-5,19\n" + "\n" + "Tags are arbitrary words, any quantity:\n" + " +tag The + means add the tag\n" + " -tag The - means remove the tag\n" + "\n" + "Attributes are:\n" + " project: Project name\n" + " priority: Priority\n" + " due: Due date\n" + " recur: Recurrence frequency\n" + " until: Recurrence end date\n" + " fg: Foreground color\n" + " bg: Background color\n" + " limit: Desired number of rows in report, or 'page'\n" + " wait: Date until task becomes pending\n" + "\n" + "Attribute modifiers improve filters. Supported modifiers are:\n" + " before (synonyms under, below)\n" + " after (synonyms over, above)\n" + " none\n" + " any\n" + " is (synonym equals)\n" + " isnt (synonym not)\n" + " has (synonym contains)\n" + " hasnt\n" + " startswith (synonym left)\n" + " endswith (synonym right)\n" + " word\n" + " noword\n" + "\n" + " For example:\n" + " task list due.before:eom priority.not:L\n" + "\n" + " Modifiers can be inverted with the ~ character:\n" + " project.~is is equivalent to project.isnt\n" + "\n" + "The default .taskrc file can be overridden with:\n" + " task rc: ...\n" + "\n" + "The values in .taskrc (or alternate) can be overridden with:\n" + " task ... rc.:\n" + "\n" + "Any command or attribute name may be abbreviated if still unique:\n" + " task list project:Home\n" + " task li pro:Home\n" + "\n" + "Some task descriptions need to be escaped because of the shell:\n" + " task add \"quoted ' quote\"\n" + " task add escaped \\' quote\n" + "\n" + "The argument -- tells taskwarrior to treat all other args as description.\n" + " task add -- project:Home needs scheduling\n" + "\n" + "Many characters have special meaning to the shell, including:\n" + " $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~\n" + "\n"; + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/commands/CmdHelp.h b/src/commands/CmdHelp.h new file mode 100644 index 000000000..bfbe06610 --- /dev/null +++ b/src/commands/CmdHelp.h @@ -0,0 +1,43 @@ +//////////////////////////////////////////////////////////////////////////////// +// taskwarrior - a command line task list manager. +// +// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez. +// 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_CMDHELP +#define INCLUDED_CMDHELP + +#include +#include + +class CmdHelp : public Command +{ +public: + CmdHelp (); + + bool implements (const std::string&); + int execute (const std::string&, std::string&); +}; + +#endif +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/commands/CmdInstall.cpp b/src/commands/CmdInstall.cpp index 6cf1cfc90..6be1db420 100644 --- a/src/commands/CmdInstall.cpp +++ b/src/commands/CmdInstall.cpp @@ -34,6 +34,8 @@ extern Context context; //////////////////////////////////////////////////////////////////////////////// CmdInstall::CmdInstall () { + _usage = "task install [ ...]"; + _description = "Installs extensions and external scripts"; _read_only = true; _displays_id = false; } diff --git a/src/commands/CmdLogo.cpp b/src/commands/CmdLogo.cpp index 33591d58b..2191f47a6 100644 --- a/src/commands/CmdLogo.cpp +++ b/src/commands/CmdLogo.cpp @@ -25,7 +25,6 @@ // //////////////////////////////////////////////////////////////////////////////// -#include // TODO Remove. #include #include #include @@ -35,6 +34,8 @@ extern Context context; //////////////////////////////////////////////////////////////////////////////// CmdLogo::CmdLogo () { + _usage = "task logo"; + _description = "Displays the Taskwarrior logo"; _read_only = true; _displays_id = false; } diff --git a/src/commands/Command.cpp b/src/commands/Command.cpp index 333c671db..1e775a9bb 100644 --- a/src/commands/Command.cpp +++ b/src/commands/Command.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,8 @@ extern Context context; Command* Command::factory (const std::string& name) { Command* command; - if (name == "exec") command = new CmdExec (); + if (name == "execute") command = new CmdExec (); + else if (name == "help") command = new CmdHelp (); else if (name == "install") command = new CmdInstall (); else if (name == "_logo") command = new CmdLogo (); else @@ -51,7 +53,9 @@ Command* Command::factory (const std::string& name) //////////////////////////////////////////////////////////////////////////////// Command::Command () -: _read_only (true) +: _usage ("") +, _description ("") +, _read_only (true) , _displays_id (true) { } @@ -59,6 +63,8 @@ Command::Command () //////////////////////////////////////////////////////////////////////////////// Command::Command (const Command& other) { + _usage = other._usage; + _description = other._description; _read_only = other._read_only; _displays_id = other._displays_id; } @@ -68,6 +74,8 @@ Command& Command::operator= (const Command& other) { if (this != &other) { + _usage = other._usage; + _description = other._description; _read_only = other._read_only; _displays_id = other._displays_id; } @@ -78,7 +86,9 @@ Command& Command::operator= (const Command& other) //////////////////////////////////////////////////////////////////////////////// bool Command::operator== (const Command& other) const { - return _read_only == other._read_only && + return _usage == other._usage && + _description == other._description && + _read_only == other._read_only && _displays_id == other._displays_id; } @@ -87,6 +97,18 @@ Command::~Command () { } +//////////////////////////////////////////////////////////////////////////////// +std::string Command::usage () const +{ + return _usage; +} + +//////////////////////////////////////////////////////////////////////////////// +std::string Command::description () const +{ + return _description; +} + //////////////////////////////////////////////////////////////////////////////// bool Command::read_only () const { diff --git a/src/commands/Command.h b/src/commands/Command.h index f07ceb2a2..ee08d9ef3 100644 --- a/src/commands/Command.h +++ b/src/commands/Command.h @@ -40,14 +40,18 @@ public: static Command* factory (const std::string&); + std::string usage () const; + std::string description () const; bool read_only () const; bool displays_id () const; virtual bool implements (const std::string&) = 0; virtual int execute (const std::string&, std::string&) = 0; protected: - bool _read_only; - bool _displays_id; + std::string _usage; + std::string _description; + bool _read_only; + bool _displays_id; }; #endif diff --git a/src/main.h b/src/main.h index 32542a8dc..a77d5b04e 100644 --- a/src/main.h +++ b/src/main.h @@ -99,7 +99,6 @@ int handleEdit (std::string&); // report.cpp int shortUsage (std::string&); -int longUsage (std::string&); int handleInfo (std::string&); int handleReportSummary (std::string&); int handleReportCalendar (std::string&); diff --git a/src/report.cpp b/src/report.cpp index f05c335ce..075dd902f 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -285,84 +285,6 @@ int shortUsage (std::string& outs) return 0; } -//////////////////////////////////////////////////////////////////////////////// -int longUsage (std::string& outs) -{ - int rc = 0; - std::string shortUsageString; - std::stringstream out; - - (void)shortUsage(shortUsageString); - - out << shortUsageString - << "ID is the numeric identifier displayed by the 'task list' command. " - << "You can specify multiple IDs for task commands, and multiple tasks " - << "will be affected. To specify multiple IDs make sure you use one " - << "of these forms:" << "\n" - << " task delete 1,2,3" << "\n" - << " task info 1-3" << "\n" - << " task pri:H 1,2-5,19" << "\n" - << "\n" - << "Tags are arbitrary words, any quantity:" << "\n" - << " +tag The + means add the tag" << "\n" - << " -tag The - means remove the tag" << "\n" - << "\n" - << "Attributes are:" << "\n" - << " project: Project name" << "\n" - << " priority: Priority" << "\n" - << " due: Due date" << "\n" - << " recur: Recurrence frequency" << "\n" - << " until: Recurrence end date" << "\n" - << " fg: Foreground color" << "\n" - << " bg: Background color" << "\n" - << " limit: Desired number of rows in report, or 'page'" << "\n" - << " wait: Date until task becomes pending" << "\n" - << "\n" - << "Attribute modifiers improve filters. Supported modifiers are:" << "\n" - << " before (synonyms under, below)" << "\n" - << " after (synonyms over, above)" << "\n" - << " none" << "\n" - << " any" << "\n" - << " is (synonym equals)" << "\n" - << " isnt (synonym not)" << "\n" - << " has (synonym contains)" << "\n" - << " hasnt" << "\n" - << " startswith (synonym left)" << "\n" - << " endswith (synonym right)" << "\n" - << " word" << "\n" - << " noword" << "\n" - << "\n" - << " For example:" << "\n" - << " task list due.before:eom priority.not:L" << "\n" - << "\n" - << " Modifiers can be inverted with the ~ character:" << "\n" - << " project.~is is equivalent to project.isnt" << "\n" - << "\n" - << "The default .taskrc file can be overridden with:" << "\n" - << " task rc: ..." << "\n" - << "\n" - << "The values in .taskrc (or alternate) can be overridden with:" << "\n" - << " task ... rc.:" << "\n" - << "\n" - << "Any command or attribute name may be abbreviated if still unique:" << "\n" - << " task list project:Home" << "\n" - << " task li pro:Home" << "\n" - << "\n" - << "Some task descriptions need to be escaped because of the shell:" << "\n" - << " task add \"quoted ' quote\"" << "\n" - << " task add escaped \\' quote" << "\n" - << "\n" - << "The argument -- tells taskwarrior to treat all other args as description." << "\n" - << " task add -- project:Home needs scheduling" << "\n" - << "\n" - << "Many characters have special meaning to the shell, including:" << "\n" - << " $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~" << "\n" - << "\n"; - - outs = out.str(); - return rc; -} - //////////////////////////////////////////////////////////////////////////////// // Display all information for the given task. int handleInfo (std::string& outs)