mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-08-19 00:43:07 +02:00
zcmdcat: zsh completion: group commands by category
This commit is contained in:
parent
5ca1dd540e
commit
c78fc47402
4 changed files with 59 additions and 10 deletions
|
@ -58,7 +58,7 @@ _task_conjunctions=(
|
|||
'>'
|
||||
)
|
||||
_task_cmds=($(task _commands; task _aliases))
|
||||
_task_zshcmds=( ${(f)"$(task _zshcommands)"} )
|
||||
_task_zshcmds=( ${(f)"$(task _zshcommands)"} sentinel:sentinel:sentinel )
|
||||
|
||||
_task_aliases=($(task _aliases))
|
||||
|
||||
|
@ -224,6 +224,34 @@ _task_id() {
|
|||
_describe -t values 'task IDs' _task_zshids
|
||||
}
|
||||
|
||||
# subcommand-only function
|
||||
(( $+functions[_task_subcommands] )) ||
|
||||
_task_subcommands() {
|
||||
local -a subcommands
|
||||
local _zshcmd
|
||||
local cmd category desc
|
||||
local lastcategory=''
|
||||
# The list is sorted by category, in the right order.
|
||||
for _zshcmd in "$_task_zshcmds[@]"; do
|
||||
# Parse out the three fields
|
||||
cmd=${_zshcmd%%:*}
|
||||
category=${${_zshcmd#*:}%%:*}
|
||||
desc=${_zshcmd#*:*:}
|
||||
|
||||
# Present each category as soon as the first entry in the *next* category
|
||||
# is seen.
|
||||
if [[ $category != $lastcategory && -n $lastcategory ]]; then
|
||||
_describe -t ${lastcategory}-commands "task ${lastcategory} command" subcommands
|
||||
subcommands=()
|
||||
fi
|
||||
|
||||
# Log the subcommand; we will process it in some future iteration.
|
||||
subcommands+=( "$cmd:$desc" )
|
||||
|
||||
lastcategory=$category
|
||||
done
|
||||
}
|
||||
|
||||
## first level completion => task sub-command completion
|
||||
(( $+functions[_task_default] )) ||
|
||||
_task_default() {
|
||||
|
@ -245,8 +273,8 @@ _task_default() {
|
|||
# update IDs
|
||||
_task_zshids=( ${(f)"$(task _zshids)"} )
|
||||
|
||||
_describe -t commands 'task command' _task_zshcmds
|
||||
_describe -t values 'task IDs' _task_zshids
|
||||
_task_subcommands
|
||||
_describe -t tasks 'task IDs' _task_zshids
|
||||
_describe -t aliases 'task aliases' _task_aliases
|
||||
_call_function ret _task_filter
|
||||
|
||||
|
|
|
@ -80,18 +80,22 @@ CmdZshCommands::CmdZshCommands ()
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CmdZshCommands::execute (std::string& output)
|
||||
{
|
||||
// Get a list of all commands.
|
||||
std::vector <std::string> commands;
|
||||
|
||||
// Get a list of all command descriptions, sorted by category and then
|
||||
// alphabetically by command name.
|
||||
typedef std::tuple <Command::Category, std::string, std::string> Element;
|
||||
std::vector <Element> commands;
|
||||
for (auto& command : context.commands)
|
||||
commands.push_back (command.first);
|
||||
|
||||
// Sort alphabetically.
|
||||
commands.push_back (std::make_tuple (command.second->_category,
|
||||
command.first,
|
||||
command.second->description()));
|
||||
std::sort (commands.begin (), commands.end ());
|
||||
|
||||
// Emit the commands in order.
|
||||
std::stringstream out;
|
||||
for (auto& c : commands)
|
||||
out << c << ":" << context.commands[c]->description () << "\n";
|
||||
out << std::get<1> (c) << ":"
|
||||
<< Command::categoryNames.at (std::get<0> (c)) << ":"
|
||||
<< std::get<2> (c) << "\n";
|
||||
|
||||
output = out.str ();
|
||||
return 0;
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
enum class Category
|
||||
{
|
||||
unassigned,
|
||||
// In presentation ("usefulness") order: frequently-used categories first.
|
||||
interrogator,
|
||||
report,
|
||||
operation,
|
||||
|
|
|
@ -63,6 +63,22 @@ class TestAliasesCompletion(TestCase):
|
|||
self.assertIn("information", out)
|
||||
self.assertNotIn("samplealias", out)
|
||||
|
||||
class TestZshCompletion(TestCase):
|
||||
"""Test _zshcommands and related completion subcommands"""
|
||||
|
||||
def setUp(self):
|
||||
self.t = Task()
|
||||
self.t.config("report.foobar.columns", "id")
|
||||
|
||||
def test_categories(self):
|
||||
"""test _zshcommands categories"""
|
||||
code, out, err = self.t("_zshcommands")
|
||||
|
||||
self.assertIn("\nfoobar:report:", out)
|
||||
self.assertIn("\ninformation:interrogator:", out)
|
||||
self.assertIn("\nexport:migration:", out)
|
||||
self.assertNotIn(":unassigned:", out)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from simpletap import TAPTestRunner
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue