mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
232 lines
9.9 KiB
C++
232 lines
9.9 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright 2006 - 2021, Tomas Babej, Paul Beckingham, Federico Hernandez.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
// SOFTWARE.
|
|
//
|
|
// https://www.opensource.org/licenses/mit-license.php
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <cmake.h>
|
|
// cmake.h include header must come first
|
|
|
|
#include <CmdHelp.h>
|
|
#include <Context.h>
|
|
#include <Table.h>
|
|
#include <format.h>
|
|
#include <shared.h>
|
|
#include <util.h>
|
|
|
|
#include <algorithm>
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
CmdHelp::CmdHelp() {
|
|
_keyword = "help";
|
|
_usage = "task help ['usage']";
|
|
_description = "Displays this usage help text";
|
|
_read_only = true;
|
|
_displays_id = false;
|
|
_needs_gc = false;
|
|
_uses_context = false;
|
|
_accepts_filter = false;
|
|
_accepts_modifications = false;
|
|
_accepts_miscellaneous = true;
|
|
_category = Command::Category::misc;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
int CmdHelp::execute(std::string& output) {
|
|
auto words = Context::getContext().cli2.getWords();
|
|
if (words.size() == 1 && closeEnough("usage", words[0]))
|
|
output = '\n' + composeUsage() + '\n';
|
|
else
|
|
output =
|
|
'\n' + composeUsage() + '\n' +
|
|
"Documentation for Taskwarrior can be found using 'man task', 'man taskrc', 'man "
|
|
"task-color', 'man task-sync' or at https://taskwarrior.org\n"
|
|
"\n"
|
|
"The general form of commands is:\n"
|
|
" task [<filter>] <command> [<mods>]\n"
|
|
"\n"
|
|
"The <filter> consists of zero or more restrictions on which tasks to select, "
|
|
"such as:\n"
|
|
" task <command> <mods>\n"
|
|
" task 28 <command> <mods>\n"
|
|
" task +weekend <command> <mods>\n"
|
|
" task project:Home due.before:today <command> <mods>\n"
|
|
" task ebeeab00-ccf8-464b-8b58-f7f2d606edfb <command> <mods>\n"
|
|
"\n"
|
|
"By default, filter elements are combined with an implicit 'and' operator, but "
|
|
"'or' and 'xor' may also be used, provided parentheses are included:\n"
|
|
" task '(/[Cc]at|[Dd]og/ or /[0-9]+/)' <command> <mods>\n"
|
|
"\n"
|
|
"A filter may target specific tasks using ID or UUID numbers. To specify "
|
|
"multiple tasks use one of these forms:\n"
|
|
" task 1,2,3 delete\n"
|
|
" task 1-3 info\n"
|
|
" task 1,2-5,19 modify pri:H\n"
|
|
" task 4-7 ebeeab00-ccf8-464b-8b58-f7f2d606edfb info\n"
|
|
"\n"
|
|
"The <mods> consist of zero or more changes to apply to the selected tasks, "
|
|
"such as:\n"
|
|
" task <filter> <command> project:Home\n"
|
|
" task <filter> <command> +weekend +garden due:tomorrow\n"
|
|
" task <filter> <command> Description/annotation text\n"
|
|
" task <filter> <command> /from/to/ <- replace first match\n"
|
|
" task <filter> <command> /from/to/g <- replace all matches\n"
|
|
"\n"
|
|
"Tags are arbitrary words, any quantity:\n"
|
|
" +tag The + means add the tag\n"
|
|
" -tag The - means remove the tag\n"
|
|
"\n"
|
|
"Built-in attributes are:\n"
|
|
" description: Task description text\n"
|
|
" status: Status of task - pending, completed, deleted, waiting\n"
|
|
" project: Project name\n"
|
|
" priority: Priority\n"
|
|
" due: Due date\n"
|
|
" recur: Recurrence frequency\n"
|
|
" until: Expiration date of a task\n"
|
|
" limit: Desired number of rows in report, or 'page'\n"
|
|
" wait: Date until task becomes pending\n"
|
|
" entry: Date task was created\n"
|
|
" end: Date task was completed/deleted\n"
|
|
" start: Date task was started\n"
|
|
" scheduled: Date task is scheduled to start\n"
|
|
" modified: Date task was last modified\n"
|
|
" depends: Other tasks that this task depends upon\n"
|
|
"\n"
|
|
"Attribute modifiers make filters more precise. Supported modifiers are:\n"
|
|
"\n"
|
|
" Modifiers Example Equivalent Meaning\n"
|
|
" ---------------- ----------------- ------------------- -------------------------\n"
|
|
" due:today due = today Fuzzy match\n"
|
|
" not due.not:today due != today Fuzzy non-match\n"
|
|
" before, below due.before:today due < today Exact date comparison\n"
|
|
" after, above due.after:today due >= tomorrow Exact date comparison\n"
|
|
" none project.none: project == '' Empty\n"
|
|
" any project.any: project !== '' Not empty\n"
|
|
" is, equals project.is:x project == x Exact match\n"
|
|
" isnt project.isnt:x project !== x Exact non-match\n"
|
|
" has, contains desc.has:Hello desc ~ Hello Pattern match\n"
|
|
" hasnt, desc.hasnt:Hello desc !~ Hello Pattern non-match\n"
|
|
" startswith, left desc.left:Hel desc ~ '^Hel' Beginning match\n"
|
|
" endswith, right desc.right:llo desc ~ 'llo$' End match\n"
|
|
" word desc.word:Hello desc ~ '\\bHello\\b' Boundaried word match\n"
|
|
" noword desc.noword:Hello desc !~ '\\bHello\\b' Boundaried word non-match\n"
|
|
"\n"
|
|
"Alternately algebraic expressions support:\n"
|
|
" and or xor Logical operators\n"
|
|
" < <= = != >= > Relational operators\n"
|
|
" ( ) Precedence\n"
|
|
"\n"
|
|
" task due.before:eom priority.not:L list\n"
|
|
" task '(due < eom and priority != L)' list\n"
|
|
"\n"
|
|
"The default .taskrc file can be overridden with:\n"
|
|
" task ... rc:<alternate file> ...\n"
|
|
" task ... rc:~/.alt_taskrc ...\n"
|
|
"\n"
|
|
"The values in .taskrc (or alternate) can be overridden with:\n"
|
|
" task ... rc.<name>=<value> ...\n"
|
|
" task rc.color=off list\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, even "
|
|
"if they would otherwise be attributes or tags:\n"
|
|
" task add -- project:Home needs scheduling\n"
|
|
"\n"
|
|
"Many characters have special meaning to the shell, including:\n"
|
|
" $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~\n"
|
|
"\n";
|
|
|
|
/*
|
|
TODO To be included later, before the 'precedence' line.
|
|
|
|
" + - Addition, Subtraktion\n" \
|
|
" ! Negation\n" \
|
|
" ~ !~ Treffer, kein Treffer\n" \
|
|
*/
|
|
|
|
return 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
std::string CmdHelp::composeUsage() const {
|
|
Table view;
|
|
view.width(Context::getContext().getWidth());
|
|
view.add("");
|
|
view.add("");
|
|
view.add("");
|
|
|
|
// Static first row.
|
|
auto row = view.addRow();
|
|
view.set(row, 0, "Usage:");
|
|
view.set(row, 1, "task");
|
|
view.set(row, 2, "Runs rc.default.command, if specified.");
|
|
|
|
// Obsolete method of getting a list of all commands.
|
|
std::vector<std::string> all;
|
|
for (auto& cmd : Context::getContext().commands) all.push_back(cmd.first);
|
|
|
|
// Sort alphabetically by usage.
|
|
std::sort(all.begin(), all.end());
|
|
|
|
// Add the regular commands.
|
|
for (auto& name : all) {
|
|
if (name[0] != '_') {
|
|
row = view.addRow();
|
|
view.set(row, 1, Context::getContext().commands[name]->usage());
|
|
view.set(row, 2, Context::getContext().commands[name]->description());
|
|
}
|
|
}
|
|
|
|
// Add the helper commands.
|
|
for (auto& name : all) {
|
|
if (name[0] == '_') {
|
|
row = view.addRow();
|
|
view.set(row, 1, Context::getContext().commands[name]->usage());
|
|
view.set(row, 2, Context::getContext().commands[name]->description());
|
|
}
|
|
}
|
|
|
|
// Add the aliases commands.
|
|
row = view.addRow();
|
|
view.set(row, 1, " ");
|
|
|
|
for (auto& alias : Context::getContext().config) {
|
|
if (alias.first.substr(0, 6) == "alias.") {
|
|
row = view.addRow();
|
|
view.set(row, 1, alias.first.substr(6));
|
|
view.set(row, 2, format("Aliased to '{1}'", alias.second));
|
|
}
|
|
}
|
|
|
|
return view.render();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|