diff options
| author | Maxime Coste <mawww@kakoune.org> | 2020-10-19 21:01:18 +1100 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2020-10-19 21:43:03 +1100 |
| commit | 65587d1eee9eddedafbba0ecd9c102d87149554f (patch) | |
| tree | 9175f0409b12c36936b178e12e31ea239f5c79ee /src/command_manager.cc | |
| parent | 2cd323b314e9f2b2cdf11bbf2974e9390914d5ea (diff) | |
Auto-insert best completion on space for menu completions
The menu flag signifies that only the completions are valid arguments,
hence it makes sense to auto insert the best one on space.
Because full match is always considered the best match in completion
ranking, this should always have a reasonable behaviour.
This makes it harder to enter a hidden command, but completion can
always be disabled via <c-o> or by quoting in those rare cases.
Diffstat (limited to 'src/command_manager.cc')
| -rw-r--r-- | src/command_manager.cc | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/src/command_manager.cc b/src/command_manager.cc index a66134f5..c2da22a2 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -628,10 +628,9 @@ Completions CommandManager::complete_command_name(const Context& context, String | transform(&CommandMap::Item::key); auto aliases = context.aliases().flatten_aliases() - | transform(&HashItem<String, String>::key) - | filter([](auto& alias) { return alias.length() > 3; }); + | transform(&HashItem<String, String>::key); - return {0, query.length(), Kakoune::complete(query, query.length(), concatenated(commands, aliases))}; + return {0, query.length(), Kakoune::complete(query, query.length(), concatenated(commands, aliases)), Completions::Flags::Menu}; } Completions CommandManager::complete_module_name(StringView query) const @@ -672,18 +671,43 @@ Completions CommandManager::complete(const Context& context, kak_assert(not tokens.empty()); const auto& token = tokens.back(); + auto requote = [](Completions completions, Token::Type token_type) { + if (completions.flags & Completions::Flags::Quoted) + return completions; + + if (token_type == Token::Type::Raw) + { + for (auto& c : completions.candidates) + { + if (c.substr(0_byte, 1_byte) == "%" or any_of(c, [](auto i) { return contains("; \t'\"", i); })) + c = quote(c); + } + } + else if (token_type == Token::Type::RawQuoted) + { + kak_assert(completions.start > 0); + --completions.start; + completions.flags |= Completions::Flags::Quoted; + for (auto& c : completions.candidates) + c = quote(c); + } + else + kak_assert(false); + + return completions; + }; + + const ByteCount start = token.pos; + const ByteCount cursor_pos_in_token = cursor_pos - start; + // command name completion if (tokens.size() == 1 and (token.type == Token::Type::Raw or token.type == Token::Type::RawQuoted)) { - auto cmd_start = token.pos; - StringView query = command_line.substr(cmd_start, cursor_pos - cmd_start); - return offset_pos(complete_command_name(context, query), cmd_start); + StringView query = command_line.substr(start, cursor_pos_in_token); + return requote(offset_pos(complete_command_name(context, query), start), token.type); } - const ByteCount start = token.pos; - const ByteCount cursor_pos_in_token = cursor_pos - start; - switch (token.type) { case Token::Type::RegisterExpand: @@ -714,11 +738,7 @@ Completions CommandManager::complete(const Context& context, case Token::Type::Raw: case Token::Type::RawQuoted: - case Token::Type::RawEval: { - if (token.type != Token::Type::Raw and token.type != Token::Type::RawQuoted) - return Completions{}; - StringView command_name = tokens.front().content; if (command_name != m_last_complete_command) { @@ -744,20 +764,11 @@ Completions CommandManager::complete(const Context& context, Vector<String> params; for (auto it = tokens.begin() + 1; it != tokens.end(); ++it) params.push_back(it->content); - Completions completions = offset_pos(command_it->value.completer( + return requote(offset_pos(command_it->value.completer( context, flags, params, tokens.size() - 2, - cursor_pos_in_token), start); - - if (not (completions.flags & Completions::Flags::Quoted) and token.type == Token::Type::Raw) - { - for (auto& c : completions.candidates) - c = (not c.empty() and c[0] == '%') or - any_of(c, [](auto i) { return contains("; \t'\"", i); }) ? - format("'{}'", replace(c, "'", "''")) : c; - } - - return completions; + cursor_pos_in_token), start), token.type); } + case Token::Type::RawEval: default: break; } |
