summaryrefslogtreecommitdiff
path: root/src/commands.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2019-05-12 21:25:08 +1000
committerMaxime Coste <mawww@kakoune.org>2019-05-17 19:52:22 +1000
commitc972dfd2d7875dd3780d4abd4ef0df0c09be421a (patch)
treee726e886af03dff4989d20d3e5af54da286980e9 /src/commands.cc
parent4916471029dfa9853473679823bf557bad2c4a52 (diff)
Introduce Menu completion flags to auto select best candidate
Diffstat (limited to 'src/commands.cc')
-rw-r--r--src/commands.cc95
1 files changed, 63 insertions, 32 deletions
diff --git a/src/commands.cc b/src/commands.cc
index e368dca8..ad3ed547 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -102,12 +102,30 @@ make_completer(Completers&&... completers)
return {std::forward<Completers>(completers)...};
}
+template<typename Completer>
+auto add_flags(Completer&& completer, Completions::Flags completions_flags)
+{
+ return [=](const Context& context, CompletionFlags flags, const String& prefix, ByteCount cursor_pos) {
+ Completions res = completer(context, flags, prefix, cursor_pos);
+ res.flags |= completions_flags;
+ return res;
+ };
+}
+
+template<typename Completer>
+auto menu(Completer&& completer)
+{
+ return add_flags(std::forward<Completer>(completer), Completions::Flags::Menu);
+}
+
+template<bool menu>
auto filename_completer = make_completer(
[](const Context& context, CompletionFlags flags, const String& prefix, ByteCount cursor_pos)
{ return Completions{ 0_byte, cursor_pos,
complete_filename(prefix,
context.options()["ignored_files"].get<Regex>(),
- cursor_pos, FilenameFlags::Expand) }; });
+ cursor_pos, FilenameFlags::Expand),
+ menu ? Completions::Flags::Menu : Completions::Flags::None}; });
template<bool ignore_current = false>
static Completions complete_buffer_name(const Context& context, CompletionFlags flags,
@@ -165,9 +183,6 @@ auto make_single_word_completer(std::function<String (const Context&)> func)
return { 0_byte, cursor_pos, complete(prefix, cursor_pos, candidate) }; });
}
-auto buffer_completer = make_completer(complete_buffer_name<false>);
-auto other_buffer_completer = make_completer(complete_buffer_name<true>);
-
const ParameterDesc no_params{ {}, ParameterDesc::Flags::None, 0, 0 };
const ParameterDesc single_param{ {}, ParameterDesc::Flags::None, 1, 1 };
const ParameterDesc single_optional_param{ {}, ParameterDesc::Flags::None, 0, 1 };
@@ -190,7 +205,9 @@ static Completions complete_command_name(const Context& context, CompletionFlags
struct ShellScriptCompleter
{
- ShellScriptCompleter(String shell_script) : m_shell_script{std::move(shell_script)} {}
+ ShellScriptCompleter(String shell_script,
+ Completions::Flags flags = Completions::Flags::None)
+ : m_shell_script{std::move(shell_script)}, m_flags(flags) {}
Completions operator()(const Context& context, CompletionFlags flags,
CommandParameters params, size_t token_to_complete,
@@ -211,15 +228,18 @@ struct ShellScriptCompleter
for (auto&& candidate : output | split<StringView>('\n'))
candidates.push_back(candidate.str());
- return {0_byte, pos_in_token, std::move(candidates)};
+ return {0_byte, pos_in_token, std::move(candidates), m_flags};
}
private:
String m_shell_script;
+ Completions::Flags m_flags;
};
struct ShellCandidatesCompleter
{
- ShellCandidatesCompleter(String shell_script) : m_shell_script{std::move(shell_script)} {}
+ ShellCandidatesCompleter(String shell_script,
+ Completions::Flags flags = Completions::Flags::None)
+ : m_shell_script{std::move(shell_script)}, m_flags(flags) {}
Completions operator()(const Context& context, CompletionFlags flags,
CommandParameters params, size_t token_to_complete,
@@ -263,13 +283,14 @@ struct ShellCandidatesCompleter
return true;
});
- return Completions{ 0_byte, pos_in_token, std::move(res) };
+ return Completions{0_byte, pos_in_token, std::move(res), m_flags};
}
private:
String m_shell_script;
Vector<std::pair<String, UsedLetters>, MemoryDomain::Completion> m_candidates;
int m_token = -1;
+ Completions::Flags m_flags;
};
template<typename Completer>
@@ -421,7 +442,7 @@ const CommandDesc edit_cmd = {
edit_params,
CommandFlags::None,
CommandHelper{},
- filename_completer,
+ filename_completer<false>,
edit<false>
};
@@ -433,7 +454,7 @@ const CommandDesc force_edit_cmd = {
edit_params,
CommandFlags::None,
CommandHelper{},
- filename_completer,
+ filename_completer<false>,
edit<true>
};
@@ -480,7 +501,7 @@ const CommandDesc write_cmd = {
write_params,
CommandFlags::None,
CommandHelper{},
- filename_completer,
+ filename_completer<false>,
write_buffer,
};
@@ -492,7 +513,7 @@ const CommandDesc force_write_cmd = {
write_params,
CommandFlags::None,
CommandHelper{},
- filename_completer,
+ filename_completer<false>,
write_buffer<true>,
};
@@ -688,7 +709,7 @@ const CommandDesc buffer_cmd = {
single_param,
CommandFlags::None,
CommandHelper{},
- other_buffer_completer,
+ make_completer(menu(complete_buffer_name<true>)),
[](const ParametersParser& parser, Context& context, const ShellContext&)
{
Buffer& buffer = BufferManager::instance().get_buffer(parser[0]);
@@ -775,7 +796,7 @@ const CommandDesc delete_buffer_cmd = {
single_optional_param,
CommandFlags::None,
CommandHelper{},
- buffer_completer,
+ make_completer(menu(complete_buffer_name<false>)),
delete_buffer<false>
};
@@ -787,7 +808,7 @@ const CommandDesc force_delete_buffer_cmd = {
single_optional_param,
CommandFlags::None,
CommandHelper{},
- buffer_completer,
+ make_completer(menu(complete_buffer_name<false>)),
delete_buffer<true>
};
@@ -1037,6 +1058,9 @@ void define_command(const ParametersParser& parser, Context& context, const Shel
if (parser.get_switch("hidden"))
flags = CommandFlags::Hidden;
+ const Completions::Flags completions_flags = parser.get_switch("menu") ?
+ Completions::Flags::Menu : Completions::Flags::None;
+
const String& commands = parser[1];
CommandFunc cmd;
ParameterDesc desc;
@@ -1073,45 +1097,48 @@ void define_command(const ParametersParser& parser, Context& context, const Shel
CommandCompleter completer;
if (parser.get_switch("file-completion"))
{
- completer = [](const Context& context, CompletionFlags flags,
+ completer = [=](const Context& context, CompletionFlags flags,
CommandParameters params,
size_t token_to_complete, ByteCount pos_in_token)
{
const String& prefix = params[token_to_complete];
auto& ignored_files = context.options()["ignored_files"].get<Regex>();
- return Completions{ 0_byte, pos_in_token,
- complete_filename(prefix, ignored_files,
- pos_in_token, FilenameFlags::Expand) };
+ return Completions{0_byte, pos_in_token,
+ complete_filename(prefix, ignored_files,
+ pos_in_token, FilenameFlags::Expand),
+ completions_flags};
};
}
else if (parser.get_switch("client-completion"))
{
- completer = [](const Context& context, CompletionFlags flags,
+ completer = [=](const Context& context, CompletionFlags flags,
CommandParameters params,
size_t token_to_complete, ByteCount pos_in_token)
{
const String& prefix = params[token_to_complete];
auto& cm = ClientManager::instance();
- return Completions{ 0_byte, pos_in_token,
- cm.complete_client_name(prefix, pos_in_token) };
+ return Completions{0_byte, pos_in_token,
+ cm.complete_client_name(prefix, pos_in_token),
+ completions_flags};
};
}
else if (parser.get_switch("buffer-completion"))
{
- completer = [](const Context& context, CompletionFlags flags,
+ completer = [=](const Context& context, CompletionFlags flags,
CommandParameters params,
size_t token_to_complete, ByteCount pos_in_token)
{
- return complete_buffer_name(context, flags, params[token_to_complete], pos_in_token);
+ return add_flags(complete_buffer_name, completions_flags)(
+ context, flags, params[token_to_complete], pos_in_token);
};
}
else if (auto shell_script = parser.get_switch("shell-script-completion"))
{
- completer = ShellScriptCompleter{shell_script->str()};
+ completer = ShellScriptCompleter{shell_script->str(), completions_flags};
}
else if (auto shell_script = parser.get_switch("shell-script-candidates"))
{
- completer = ShellCandidatesCompleter{shell_script->str()};
+ completer = ShellCandidatesCompleter{shell_script->str(), completions_flags};
}
else if (parser.get_switch("command-completion"))
{
@@ -1125,11 +1152,12 @@ void define_command(const ParametersParser& parser, Context& context, const Shel
}
else if (parser.get_switch("shell-completion"))
{
- completer = [](const Context& context, CompletionFlags flags,
- CommandParameters params,
- size_t token_to_complete, ByteCount pos_in_token)
+ completer = [=](const Context& context, CompletionFlags flags,
+ CommandParameters params,
+ size_t token_to_complete, ByteCount pos_in_token)
{
- return shell_complete(context, flags, params[token_to_complete], pos_in_token);
+ return add_flags(shell_complete, completions_flags)(
+ context, flags, params[token_to_complete], pos_in_token);
};
}
@@ -1148,6 +1176,7 @@ const CommandDesc define_command_cmd = {
{ "override", { false, "allow overriding an existing command" } },
{ "hidden", { false, "do not display the command in completion candidates" } },
{ "docstring", { true, "define the documentation string for command" } },
+ { "menu", { false, "treat completions as the only valid inputs" } },
{ "file-completion", { false, "complete parameters using filename completion" } },
{ "client-completion", { false, "complete parameters using client name completion" } },
{ "buffer-completion", { false, "complete parameters using buffer name completion" } },
@@ -1368,7 +1397,7 @@ const CommandDesc source_cmd = {
ParameterDesc{ {}, ParameterDesc::Flags::None, 1, (size_t)-1 },
CommandFlags::None,
CommandHelper{},
- filename_completer,
+ filename_completer<true>,
[](const ParametersParser& parser, Context& context, const ShellContext&)
{
const DebugFlags debug_flags = context.options()["debug"].get<DebugFlags>();
@@ -1447,7 +1476,9 @@ const CommandDesc set_option_cmd = {
GlobalScope::instance().option_registry().option_exists(params[start + 1]))
{
OptionManager& options = get_scope(params[start], context).options();
- return { 0_byte, params[start + 2].length(), { options[params[start + 1]].get_as_string(Quoting::Kakoune) }, true };
+ return {0_byte, params[start + 2].length(),
+ {options[params[start + 1]].get_as_string(Quoting::Kakoune)},
+ Completions::Flags::Quoted};
}
return Completions{};
},