Elide temporary vector when completing keymap modes (user modes)

complete() merely iterates over its input, so we can pass it a range
instead of a vector.  For some reason, this requires specifying the
type of the static array, or else its elements become String which
triggers this assertion:

    static_assert(not std::is_same<decltype(*begin(container)), String>::value,
                  "complete require long lived strings, not temporaries");

Specify the type with an explicit Array<StringView, 8>. This is
pretty ugly but the alternative of appending "_sv" to every single
array element seems worse?

If we modify the vector of user modes while complete() is iterating
over, we could crash -- but that scenario is impossible since both
only happen inside the single-threaded server process.
This commit is contained in:
Johannes Altmanninger 2022-07-19 12:58:14 +02:00
parent 559af669c7
commit b2f45a29e4

View File

@ -1450,7 +1450,7 @@ KeymapMode parse_keymap_mode(StringView str, const KeymapManager::UserModeList&
return (KeymapMode)(std::distance(user_modes.begin(), it) + offset); return (KeymapMode)(std::distance(user_modes.begin(), it) + offset);
} }
static constexpr auto modes = { "normal", "insert", "menu", "prompt", "goto", "view", "user", "object" }; static constexpr Array<StringView, 8> modes = { "normal", "insert", "menu", "prompt", "goto", "view", "user", "object" };
const CommandDesc debug_cmd = { const CommandDesc debug_cmd = {
"debug", "debug",
@ -1555,7 +1555,7 @@ const CommandDesc debug_cmd = {
auto& keymaps = context.keymaps(); auto& keymaps = context.keymaps();
auto user_modes = keymaps.user_modes(); auto user_modes = keymaps.user_modes();
write_to_debug_buffer("Mappings:"); write_to_debug_buffer("Mappings:");
for (auto& mode : concatenated(modes, user_modes) | gather<Vector<String>>()) for (auto mode : concatenated(modes, user_modes))
{ {
KeymapMode m = parse_keymap_mode(mode, user_modes); KeymapMode m = parse_keymap_mode(mode, user_modes);
for (auto& key : keymaps.get_mapped_keys(m)) for (auto& key : keymaps.get_mapped_keys(m))
@ -1835,7 +1835,7 @@ static Completions map_key_completer(const Context& context, CompletionFlags fla
{ {
auto& user_modes = get_scope(params[0], context).keymaps().user_modes(); auto& user_modes = get_scope(params[0], context).keymaps().user_modes();
return { 0_byte, params[1].length(), return { 0_byte, params[1].length(),
complete(params[1], pos_in_token, concatenated(modes, user_modes) | gather<Vector<String>>()) }; complete(params[1], pos_in_token, concatenated(modes, user_modes)) };
} }
if (unmap and token_to_complete == 2) if (unmap and token_to_complete == 2)
{ {