Add support for command completion on commands, use it for :new
That means commands can be completed using other commands and their completers. Yes that does makes sense. Closes #296
This commit is contained in:
parent
b579f90bae
commit
5b554ff474
|
@ -23,6 +23,7 @@ decl str termcmd %sh{
|
||||||
|
|
||||||
def -docstring 'create a new kak client for current session' \
|
def -docstring 'create a new kak client for current session' \
|
||||||
-shell-params \
|
-shell-params \
|
||||||
|
-command-completion \
|
||||||
new %{ %sh{
|
new %{ %sh{
|
||||||
if [ -z "${kak_opt_termcmd}" ]; then
|
if [ -z "${kak_opt_termcmd}" ]; then
|
||||||
echo "echo -color Error 'termcmd option is not set'"
|
echo "echo -color Error 'termcmd option is not set'"
|
||||||
|
|
|
@ -506,7 +506,7 @@ Completions CommandManager::complete(const Context& context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// command name completion
|
// command name completion
|
||||||
if (tokens.empty() or
|
if (tokens.empty() or
|
||||||
(tok_idx == cmd_idx and (tok_idx == tokens.size() or
|
(tok_idx == cmd_idx and (tok_idx == tokens.size() or
|
||||||
tokens[tok_idx].type() == Token::Type::Raw)))
|
tokens[tok_idx].type() == Token::Type::Raw)))
|
||||||
|
@ -589,6 +589,40 @@ Completions CommandManager::complete(const Context& context,
|
||||||
return Completions{};
|
return Completions{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Completions CommandManager::complete(const Context& context,
|
||||||
|
CompletionFlags flags,
|
||||||
|
CommandParameters params,
|
||||||
|
size_t token_to_complete,
|
||||||
|
ByteCount pos_in_token)
|
||||||
|
{
|
||||||
|
StringView prefix = params[token_to_complete].substr(0, pos_in_token);
|
||||||
|
|
||||||
|
if (token_to_complete == 0)
|
||||||
|
{
|
||||||
|
CandidateList candidates;
|
||||||
|
for (auto& command : m_commands)
|
||||||
|
{
|
||||||
|
if (command.second.flags & CommandFlags::Hidden)
|
||||||
|
continue;
|
||||||
|
if (prefix_match(command.first, prefix))
|
||||||
|
candidates.push_back(command.first);
|
||||||
|
}
|
||||||
|
std::sort(candidates.begin(), candidates.end());
|
||||||
|
return {0, pos_in_token, std::move(candidates)};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const String& command_name = params[0];
|
||||||
|
|
||||||
|
auto command_it = find_command(context, command_name);
|
||||||
|
if (command_it != m_commands.end() and command_it->second.completer)
|
||||||
|
return command_it->second.completer(
|
||||||
|
context, flags, params.subrange(1, params.size()-1),
|
||||||
|
token_to_complete-1, pos_in_token);
|
||||||
|
}
|
||||||
|
return Completions{};
|
||||||
|
}
|
||||||
|
|
||||||
Completions PerArgumentCommandCompleter::operator()(const Context& context,
|
Completions PerArgumentCommandCompleter::operator()(const Context& context,
|
||||||
CompletionFlags flags,
|
CompletionFlags flags,
|
||||||
CommandParameters params,
|
CommandParameters params,
|
||||||
|
|
|
@ -67,6 +67,10 @@ public:
|
||||||
Completions complete(const Context& context, CompletionFlags flags,
|
Completions complete(const Context& context, CompletionFlags flags,
|
||||||
StringView command_line, ByteCount cursor_pos);
|
StringView command_line, ByteCount cursor_pos);
|
||||||
|
|
||||||
|
Completions complete(const Context& context, CompletionFlags flags,
|
||||||
|
CommandParameters params,
|
||||||
|
size_t token_to_complete, ByteCount pos_in_token);
|
||||||
|
|
||||||
CommandInfo command_info(const Context& context,
|
CommandInfo command_info(const Context& context,
|
||||||
StringView command_line) const;
|
StringView command_line) const;
|
||||||
|
|
||||||
|
|
|
@ -798,6 +798,16 @@ void define_command(const ParametersParser& parser, Context& context)
|
||||||
return Completions{ 0_byte, pos_in_token, split(output, '\n', 0) };
|
return Completions{ 0_byte, pos_in_token, split(output, '\n', 0) };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
else if (parser.get_switch("command-completion"))
|
||||||
|
{
|
||||||
|
completer = [](const Context& context, CompletionFlags flags,
|
||||||
|
CommandParameters params,
|
||||||
|
size_t token_to_complete, ByteCount pos_in_token)
|
||||||
|
{
|
||||||
|
return CommandManager::instance().complete(
|
||||||
|
context, flags, params, token_to_complete, pos_in_token);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
auto docstring = parser.get_switch("docstring").value_or(StringView{});
|
auto docstring = parser.get_switch("docstring").value_or(StringView{});
|
||||||
|
|
||||||
|
@ -816,6 +826,7 @@ const CommandDesc define_command_cmd = {
|
||||||
{ "file-completion", { false, "complete parameters using filename completion" } },
|
{ "file-completion", { false, "complete parameters using filename completion" } },
|
||||||
{ "client-completion", { false, "complete parameters using client name completion" } },
|
{ "client-completion", { false, "complete parameters using client name completion" } },
|
||||||
{ "buffer-completion", { false, "complete parameters using buffer name completion" } },
|
{ "buffer-completion", { false, "complete parameters using buffer name completion" } },
|
||||||
|
{ "command-completion", { false, "complete parameters using kakoune command completion" } },
|
||||||
{ "shell-completion", { true, "complete the parameters using the given shell-script" } } },
|
{ "shell-completion", { true, "complete the parameters using the given shell-script" } } },
|
||||||
ParameterDesc::Flags::None,
|
ParameterDesc::Flags::None,
|
||||||
2, 2
|
2, 2
|
||||||
|
|
|
@ -345,7 +345,10 @@ void command(Context& context, NormalParams)
|
||||||
|
|
||||||
context.input_handler().prompt(
|
context.input_handler().prompt(
|
||||||
":", "", get_face("Prompt"),
|
":", "", get_face("Prompt"),
|
||||||
std::bind(&CommandManager::complete, &CommandManager::instance(), _1, _2, _3, _4),
|
[](const Context& context, CompletionFlags flags,
|
||||||
|
StringView cmd_line, ByteCount pos) {
|
||||||
|
return CommandManager::instance().complete(context, flags, cmd_line, pos);
|
||||||
|
},
|
||||||
[](StringView cmdline, PromptEvent event, Context& context) {
|
[](StringView cmdline, PromptEvent event, Context& context) {
|
||||||
if (context.has_ui())
|
if (context.has_ui())
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user