diff --git a/src/command_manager.cc b/src/command_manager.cc index caae27765..22b365ea5 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -831,7 +831,12 @@ Completions CommandManager::complete(const Context& context, : Completions{start+1, cursor_pos, std::move(switches), Completions::Flags::Menu}; } case ParametersParser::State::SwitchArgument: - return Completions{}; + { + const auto& switch_desc = command.param_desc.switches.get(raw_params.at(raw_params.size() - 2).substr(1_byte)); + if (not *switch_desc.arg_completer) + return Completions{}; + return offset_pos(requote((*switch_desc.arg_completer)(context, flags, raw_params.back(), pos_in_token), token.type), start); + } case ParametersParser::State::Positional: break; } diff --git a/src/commands.cc b/src/commands.cc index 5dc5f3f7c..6edc308b6 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -128,6 +128,27 @@ auto filename_completer = make_completer( cursor_pos, FilenameFlags::Expand), menu ? Completions::Flags::Menu : Completions::Flags::None}; }); +template +auto filename_arg_completer = + [](const Context& context, CompletionFlags flags, StringView prefix, ByteCount cursor_pos) -> Completions + { return { 0_byte, cursor_pos, + complete_filename(prefix, + context.options()["ignored_files"].get(), + cursor_pos, FilenameFlags::OnlyDirectories), + menu ? Completions::Flags::Menu : Completions::Flags::None }; }; + +auto client_arg_completer = + [](const Context& context, CompletionFlags flags, StringView prefix, ByteCount cursor_pos) -> Completions + { return { 0_byte, cursor_pos, + ClientManager::instance().complete_client_name(prefix, cursor_pos), + Completions::Flags::Menu }; }; + +auto arg_completer = [](auto candidates) -> PromptCompleter { + return [=](const Context& context, CompletionFlags flags, StringView prefix, ByteCount cursor_pos) -> Completions { + return Completions{ 0_byte, cursor_pos, complete(prefix, cursor_pos, candidates), Completions::Flags::Menu }; + }; +}; + template static Completions complete_buffer_name(const Context& context, CompletionFlags flags, StringView prefix, ByteCount cursor_pos) @@ -444,12 +465,12 @@ void edit(const ParametersParser& parser, Context& context, const ShellContext&) } ParameterDesc edit_params{ - { { "existing", { false, "fail if the file does not exist, do not open a new file" } }, - { "scratch", { false, "create a scratch buffer, not linked to a file" } }, - { "debug", { false, "create buffer as debug output" } }, - { "fifo", { true, "create a buffer reading its content from a named fifo" } }, - { "readonly", { false, "create a buffer in readonly mode" } }, - { "scroll", { false, "place the initial cursor so that the fifo will scroll to show new data" } } }, + { { "existing", { {}, "fail if the file does not exist, do not open a new file" } }, + { "scratch", { {}, "create a scratch buffer, not linked to a file" } }, + { "debug", { {}, "create buffer as debug output" } }, + { "fifo", { {filename_arg_completer}, "create a buffer reading its content from a named fifo" } }, + { "readonly", { {}, "create a buffer in readonly mode" } }, + { "scroll", { {}, "place the initial cursor so that the fifo will scroll to show new data" } } }, ParameterDesc::Flags::None, 0, 3 }; const CommandDesc edit_cmd = { @@ -477,17 +498,17 @@ const CommandDesc force_edit_cmd = { const ParameterDesc write_params = { { - { "sync", { false, "force the synchronization of the file onto the filesystem" } }, - { "method", { true, "explicit writemethod (replace|overwrite)" } }, - { "force", { false, "Allow overwriting existing file with explicit filename" } } + { "sync", { {}, "force the synchronization of the file onto the filesystem" } }, + { "method", { {arg_completer(Array{"replace", "overwrite"})}, "explicit writemethod (replace|overwrite)" } }, + { "force", { {}, "Allow overwriting existing file with explicit filename" } } }, ParameterDesc::Flags::None, 0, 1 }; const ParameterDesc write_params_except_force = { { - { "sync", { false, "force the synchronization of the file onto the filesystem" } }, - { "method", { true, "explicit writemethod (replace|overwrite)" } }, + { "sync", { {}, "force the synchronization of the file onto the filesystem" } }, + { "method", { {arg_completer(Array{"replace", "overwrite"})}, "explicit writemethod (replace|overwrite)" } }, }, ParameterDesc::Flags::None, 0, 1 }; @@ -872,8 +893,8 @@ const CommandDesc rename_buffer_cmd = { "rename-buffer : change current buffer name", ParameterDesc{ { - { "scratch", { false, "convert a file buffer to a scratch buffer" } }, - { "file", { false, "convert a scratch buffer to a file buffer" } } + { "scratch", { {}, "convert a file buffer to a scratch buffer" } }, + { "file", { {}, "convert a scratch buffer to a file buffer" } } }, ParameterDesc::Flags::None, 1, 1 }, @@ -997,7 +1018,7 @@ const CommandDesc add_highlighter_cmd = { " is a '/' delimited path or the parent highlighter, starting with either\n" " 'global', 'buffer', 'window' or 'shared', if is empty, it will be autogenerated", ParameterDesc{ - { { "override", { false, "replace existing highlighter with same path if it exists" } }, }, + { { "override", { {}, "replace existing highlighter with same path if it exists" } }, }, ParameterDesc::Flags::SwitchesOnlyAtStart, 2 }, CommandFlags::None, @@ -1097,9 +1118,9 @@ const CommandDesc add_hook_cmd = { " (and any window for that buffer)\n" " * window: hook is executed only for the current window\n", ParameterDesc{ - { { "group", { true, "set hook group, see remove-hooks" } }, - { "always", { false, "run hook even if hooks are disabled" } }, - { "once", { false, "run the hook only once" } } }, + { { "group", { ArgCompleter{}, "set hook group, see remove-hooks" } }, + { "always", { {}, "run hook even if hooks are disabled" } }, + { "once", { {}, "run the hook only once" } } }, ParameterDesc::Flags::None, 4, 4 }, CommandFlags::None, @@ -1335,19 +1356,19 @@ const CommandDesc define_command_cmd = { "def", "define-command [] : define a command executing ", ParameterDesc{ - { { "params", { true, "take parameters, accessible to each shell escape as $0..$N\n" + { { "params", { ArgCompleter{}, "take parameters, accessible to each shell escape as $0..$N\n" "parameter should take the form or .. (both omittable)" } }, - { "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" } }, - { "command-completion", { false, "complete parameters using kakoune command completion" } }, - { "shell-completion", { false, "complete parameters using shell command completion" } }, - { "shell-script-completion", { true, "complete parameters using the given shell-script" } }, - { "shell-script-candidates", { true, "get the parameter candidates using the given shell-script" } } }, + { "override", { {}, "allow overriding an existing command" } }, + { "hidden", { {}, "do not display the command in completion candidates" } }, + { "docstring", { ArgCompleter{}, "define the documentation string for command" } }, + { "menu", { {}, "treat completions as the only valid inputs" } }, + { "file-completion", { {}, "complete parameters using filename completion" } }, + { "client-completion", { {}, "complete parameters using client name completion" } }, + { "buffer-completion", { {}, "complete parameters using buffer name completion" } }, + { "command-completion", { {}, "complete parameters using kakoune command completion" } }, + { "shell-completion", { {}, "complete parameters using shell command completion" } }, + { "shell-script-completion", { ArgCompleter{}, "complete parameters using the given shell-script" } }, + { "shell-script-candidates", { ArgCompleter{}, "get the parameter candidates using the given shell-script" } } }, ParameterDesc::Flags::None, 2, 2 }, @@ -1408,7 +1429,7 @@ const CommandDesc complete_command_cmd = { "complete-command [] []\n" "define command completion", ParameterDesc{ - { { "menu", { false, "treat completions as the only valid inputs" } }, }, + { { "menu", { {}, "treat completions as the only valid inputs" } }, }, ParameterDesc::Flags::None, 2, 3}, CommandFlags::None, CommandHelper{}, @@ -1426,11 +1447,11 @@ const CommandDesc echo_cmd = { nullptr, "echo ...: display given parameters in the status line", ParameterDesc{ - { { "markup", { false, "parse markup" } }, - { "quoting", { true, "quote each argument separately using the given style (raw|kakoune|shell)" } }, - { "to-file", { true, "echo contents to given filename" } }, - { "to-shell-script", { true, "pipe contents to given shell script" } }, - { "debug", { false, "write to debug buffer instead of status line" } } }, + { { "markup", { {}, "parse markup" } }, + { "quoting", { {arg_completer(Array{"raw", "kakoune", "shell"})}, "quote each argument separately using the given style (raw|kakoune|shell)" } }, + { "to-file", { {filename_arg_completer}, "echo contents to given filename" } }, + { "to-shell-script", { ArgCompleter{}, "pipe contents to given shell script" } }, + { "debug", { {}, "write to debug buffer instead of status line" } } }, ParameterDesc::Flags::SwitchesOnlyAtStart }, CommandFlags::None, @@ -1666,8 +1687,8 @@ const CommandDesc set_option_cmd = { " can be global, buffer, window, or current which refers to the narrowest " "scope the option is set in", ParameterDesc{ - { { "add", { false, "add to option rather than replacing it" } }, - { "remove", { false, "remove from option rather than replacing it" } } }, + { { "add", { {}, "add to option rather than replacing it" } }, + { "remove", { {}, "remove from option rather than replacing it" } } }, ParameterDesc::Flags::SwitchesOnlyAtStart, 2, (size_t)-1 }, CommandFlags::None, @@ -1776,8 +1797,8 @@ const CommandDesc declare_option_cmd = { " range-specs: list of range specs\n" " str-to-str-map: map from strings to strings\n", ParameterDesc{ - { { "hidden", { false, "do not display option name when completing" } }, - { "docstring", { true, "specify option description" } } }, + { { "hidden", { {}, "do not display option name when completing" } }, + { "docstring", { ArgCompleter{}, "specify option description" } } }, ParameterDesc::Flags::SwitchesOnlyAtStart, 2, (size_t)-1 }, CommandFlags::None, @@ -1862,7 +1883,7 @@ const CommandDesc map_key_cmd = { nullptr, "map [] : map to in given in ", ParameterDesc{ - { { "docstring", { true, "specify mapping description" } } }, + { { "docstring", { ArgCompleter{}, "specify mapping description" } } }, ParameterDesc::Flags::None, 4, 4 }, CommandFlags::None, @@ -1920,11 +1941,11 @@ template ParameterDesc make_context_wrap_params_impl(Array, sizeof...(P)>&& additional_params, std::index_sequence) { - return { { { "client", { true, "run in given client context" } }, - { "try-client", { true, "run in given client context if it exists, or else in the current one" } }, - { "buffer", { true, "run in a disposable context for each given buffer in the comma separated list argument" } }, - { "draft", { false, "run in a disposable context" } }, - { "itersel", { false, "run once for each selection with that selection as the only one" } }, + return { { { "client", { {client_arg_completer}, "run in given client context" } }, + { "try-client", { {client_arg_completer}, "run in given client context if it exists, or else in the current one" } }, + { "buffer", { {complete_buffer_name}, "run in a disposable context for each given buffer in the comma separated list argument" } }, + { "draft", { {}, "run in a disposable context" } }, + { "itersel", { {}, "run once for each selection with that selection as the only one" } }, std::move(additional_params[P])...}, ParameterDesc::Flags::SwitchesOnlyAtStart, 1 }; @@ -2089,9 +2110,9 @@ const CommandDesc execute_keys_cmd = { "exec", "execute-keys [] : execute given keys as if entered by user", make_context_wrap_params<3>({{ - {"save-regs", {true, "restore all given registers after execution (default: '/\"|^@:')"}}, - {"with-maps", {false, "use user defined key mapping when executing keys"}}, - {"with-hooks", {false, "trigger hooks while executing keys"}} + {"save-regs", {ArgCompleter{}, "restore all given registers after execution (default: '/\"|^@:')"}}, + {"with-maps", {{}, "use user defined key mapping when executing keys"}}, + {"with-hooks", {{}, "trigger hooks while executing keys"}} }}), CommandFlags::None, CommandHelper{}, @@ -2113,9 +2134,9 @@ const CommandDesc evaluate_commands_cmd = { "eval", "evaluate-commands [] ...: execute commands as if entered by user", make_context_wrap_params<3>({{ - {"save-regs", {true, "restore all given registers after execution (default: '')"}}, - {"no-hooks", { false, "disable hooks while executing commands" }}, - {"verbatim", { false, "do not reparse argument" }} + {"save-regs", {ArgCompleter{}, "restore all given registers after execution (default: '')"}}, + {"no-hooks", { {}, "disable hooks while executing commands" }}, + {"verbatim", { {}, "do not reparse argument" }} }}), CommandFlags::None, CommandHelper{}, @@ -2151,18 +2172,18 @@ const CommandDesc prompt_cmd = { "prompt [] : prompt the user to enter a text string " "and then executes , entered text is available in the 'text' value", ParameterDesc{ - { { "init", { true, "set initial prompt content" } }, - { "password", { false, "Do not display entered text and clear reg after command" } }, - { "menu", { false, "treat completions as the only valid inputs" } }, - { "file-completion", { false, "use file completion for prompt" } }, - { "client-completion", { false, "use client completion for prompt" } }, - { "buffer-completion", { false, "use buffer completion for prompt" } }, - { "command-completion", { false, "use command completion for prompt" } }, - { "shell-completion", { false, "use shell command completion for prompt" } }, - { "shell-script-completion", { true, "use shell command completion for prompt" } }, - { "shell-script-candidates", { true, "use shell command completion for prompt" } }, - { "on-change", { true, "command to execute whenever the prompt changes" } }, - { "on-abort", { true, "command to execute whenever the prompt is canceled" } } }, + { { "init", { ArgCompleter{}, "set initial prompt content" } }, + { "password", { {}, "Do not display entered text and clear reg after command" } }, + { "menu", { {}, "treat completions as the only valid inputs" } }, + { "file-completion", { {}, "use file completion for prompt" } }, + { "client-completion", { {}, "use client completion for prompt" } }, + { "buffer-completion", { {}, "use buffer completion for prompt" } }, + { "command-completion", { {}, "use command completion for prompt" } }, + { "shell-completion", { {}, "use shell command completion for prompt" } }, + { "shell-script-completion", { ArgCompleter{}, "use shell command completion for prompt" } }, + { "shell-script-candidates", { ArgCompleter{}, "use shell command completion for prompt" } }, + { "on-change", { ArgCompleter{}, "command to execute whenever the prompt changes" } }, + { "on-abort", { ArgCompleter{}, "command to execute whenever the prompt is canceled" } } }, ParameterDesc::Flags::None, 2, 2 }, CommandFlags::None, @@ -2226,9 +2247,9 @@ const CommandDesc menu_cmd = { "menu [] ...: display a " "menu and execute commands for the selected item", ParameterDesc{ - { { "auto-single", { false, "instantly validate if only one item is available" } }, - { "select-cmds", { false, "each item specify an additional command to run when selected" } }, - { "markup", { false, "parse menu entries as markup text" } } } + { { "auto-single", { {}, "instantly validate if only one item is available" } }, + { "select-cmds", { {}, "each item specify an additional command to run when selected" } }, + { "markup", { {}, "parse menu entries as markup text" } } } }, CommandFlags::None, CommandHelper{}, @@ -2285,7 +2306,7 @@ const CommandDesc on_key_cmd = { "on-key [] : wait for next user key and then execute , " "with key available in the `key` value", ParameterDesc{ - { { "mode-name", { true, "set mode name to use" } } }, + { { "mode-name", { ArgCompleter{}, "set mode name to use" } } }, ParameterDesc::Flags::None, 1, 1 }, CommandFlags::None, @@ -2312,10 +2333,10 @@ const CommandDesc info_cmd = { nullptr, "info [] : display an info box containing ", ParameterDesc{ - { { "anchor", { true, "set info anchoring ." } }, - { "style", { true, "set info style (above, below, menu, modal)" } }, - { "markup", { false, "parse markup" } }, - { "title", { true, "set info title" } } }, + { { "anchor", { ArgCompleter{}, "set info anchoring ." } }, + { "style", { {arg_completer(Array{"above", "below", "menu", "modal"})}, "set info style (above, below, menu, modal)" } }, + { "markup", { {}, "parse markup" } }, + { "title", { ArgCompleter{}, "set info title" } } }, ParameterDesc::Flags::None, 0, 1 }, CommandFlags::None, @@ -2518,9 +2539,9 @@ const CommandDesc select_cmd = { "\n" "selection_desc format is .,.", ParameterDesc{{ - {"timestamp", {true, "specify buffer timestamp at which those selections are valid"}}, - {"codepoint", {false, "columns are specified in codepoints, not bytes"}}, - {"display-column", {false, "columns are specified in display columns, not bytes"}} + {"timestamp", {ArgCompleter{}, "specify buffer timestamp at which those selections are valid"}}, + {"codepoint", {{}, "columns are specified in codepoints, not bytes"}}, + {"display-column", {{}, "columns are specified in display columns, not bytes"}} }, ParameterDesc::Flags::SwitchesOnlyAtStart, 1 }, @@ -2642,7 +2663,7 @@ const CommandDesc enter_user_mode_cmd = { nullptr, "enter-user-mode [] : enable keymap mode for next key", ParameterDesc{ - { { "lock", { false, "stay in mode until is pressed" } } }, + { { "lock", { {}, "stay in mode until is pressed" } } }, ParameterDesc::Flags::None, 1, 1 }, CommandFlags::None, @@ -2672,7 +2693,7 @@ const CommandDesc provide_module_cmd = { nullptr, "provide-module [] : declares a module provided by ", ParameterDesc{ - { { "override", { false, "allow overriding an existing module" } } }, + { { "override", { {}, "allow overriding an existing module" } } }, ParameterDesc::Flags::None, 2, 2 }, diff --git a/src/highlighters.cc b/src/highlighters.cc index 9d7335212..5a84a522b 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -678,10 +678,10 @@ const HighlighterDesc wrap_desc = { "Parameters: [-word] [-indent] [-width ] [-marker ]\n" "Wrap lines to window width", { { - { "word", { false, "wrap at word boundaries instead of codepoint boundaries" } }, - { "indent", { false, "preserve line indentation of the wrapped line" } }, - { "width", { true, "wrap at the given column instead of the window's width" } }, - { "marker", { true, "insert the given text at the beginning of the wrapped line" } }, }, + { "word", { {}, "wrap at word boundaries instead of codepoint boundaries" } }, + { "indent", { {}, "preserve line indentation of the wrapped line" } }, + { "width", { ArgCompleter{}, "wrap at the given column instead of the window's width" } }, + { "marker", { ArgCompleter{}, "insert the given text at the beginning of the wrapped line" } }, }, ParameterDesc::Flags::None, 0, 0 } }; @@ -1047,11 +1047,11 @@ const HighlighterDesc show_whitespace_desc = { "Parameters: [-tab ] [-tabpad ] [-lf ] [-spc ] [-nbsp ]\n" "Display whitespaces using symbols", { { - { "tab", { true, "replace tabulations with the given character" } }, - { "tabpad", { true, "append as many of the given character as is necessary to honor `tabstop`" } }, - { "spc", { true, "replace spaces with the given character" } }, - { "lf", { true, "replace line feeds with the given character" } }, - { "nbsp", { true, "replace non-breakable spaces with the given character" } } }, + { "tab", { ArgCompleter{}, "replace tabulations with the given character" } }, + { "tabpad", { ArgCompleter{}, "append as many of the given character as is necessary to honor `tabstop`" } }, + { "spc", { ArgCompleter{}, "replace spaces with the given character" } }, + { "lf", { ArgCompleter{}, "replace line feeds with the given character" } }, + { "nbsp", { ArgCompleter{}, "replace non-breakable spaces with the given character" } } }, ParameterDesc::Flags::None, 0, 0 } }; @@ -1131,11 +1131,11 @@ const HighlighterDesc line_numbers_desc = { "Parameters: [-relative] [-hlcursor] [-separators ] [-min-digits ]\n" "Display line numbers", { { - { "relative", { false, "show line numbers relative to the main cursor line" } }, - { "separator", { true, "string to separate the line numbers column from the rest of the buffer (default '|')" } }, - { "cursor-separator", { true, "identical to -separator but applies only to the line of the cursor (default is the same value passed to -separator)" } }, - { "min-digits", { true, "use at least the given number of columns to display line numbers (default 2)" } }, - { "hlcursor", { false, "highlight the cursor line with a separate face" } } }, + { "relative", { {}, "show line numbers relative to the main cursor line" } }, + { "separator", { ArgCompleter{}, "string to separate the line numbers column from the rest of the buffer (default '|')" } }, + { "cursor-separator", { ArgCompleter{}, "identical to -separator but applies only to the line of the cursor (default is the same value passed to -separator)" } }, + { "min-digits", { ArgCompleter{}, "use at least the given number of columns to display line numbers (default 2)" } }, + { "hlcursor", { {}, "highlight the cursor line with a separate face" } } }, ParameterDesc::Flags::None, 0, 0 } }; @@ -1777,9 +1777,9 @@ const HighlighterDesc higlighter_group_desc = { "Parameters: [-passes ]\n" "Creates a group that can contain other highlighters", { { - { "passes", { true, "flags(colorize|move|wrap) " - "kind of highlighters can be put in the group " - "(default colorize)" } } }, + { "passes", { ArgCompleter{}, "flags(colorize|move|wrap) " + "kind of highlighters can be put in the group " + "(default colorize)" } } }, ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 0 } }; @@ -1795,9 +1795,9 @@ const HighlighterDesc ref_desc = { "Parameters: [-passes ] \n" "Reference the highlighter at in shared highlighters", { { - { "passes", { true, "flags(colorize|move|wrap) " - "kind of highlighters that can be referenced " - "(default colorize)" } } }, + { "passes", { ArgCompleter{}, "flags(colorize|move|wrap) " + "kind of highlighters that can be referenced " + "(default colorize)" } } }, ParameterDesc::Flags::SwitchesOnlyAtStart, 1, 1 } }; @@ -1885,8 +1885,8 @@ const HighlighterDesc region_desc = { "highlighter as defined by and eventual ...\n" "The region starts at match and ends at the first ", { { - { "match-capture", { false, "only consider region ending/recurse delimiters whose first capture group match the region beginning delimiter" } }, - { "recurse", { true, "make the region end on the first ending delimiter that does not close the given parameter" } } }, + { "match-capture", { {}, "only consider region ending/recurse delimiters whose first capture group match the region beginning delimiter" } }, + { "recurse", { ArgCompleter{}, "make the region end on the first ending delimiter that does not close the given parameter" } } }, ParameterDesc::Flags::SwitchesOnlyAtStart | ParameterDesc::Flags::IgnoreUnknownSwitches, 3 } diff --git a/src/input_handler.cc b/src/input_handler.cc index 2564529ac..69ef33858 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -941,7 +941,7 @@ public: { on_next_key_with_autoinfo(context(), "explicit-completion", KeymapMode::None, [this](Key key, Context&) { - m_explicit_completer = PromptCompleter{}; + m_explicit_completer = ArgCompleter{}; if (key.key == 'f') use_explicit_completer([](const Context& context, StringView token) { @@ -968,7 +968,7 @@ public: } else if (key == ctrl('o')) { - m_explicit_completer = PromptCompleter{}; + m_explicit_completer = ArgCompleter{}; m_auto_complete = not m_auto_complete; if (m_auto_complete) diff --git a/src/main.cc b/src/main.cc index 3e5ba3709..6e4415cf7 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1071,23 +1071,23 @@ int main(int argc, char* argv[]) set_signal_handler(SIGTTOU, SIG_IGN); const ParameterDesc param_desc{ - SwitchMap{ { "c", { true, "connect to given session" } }, - { "e", { true, "execute argument on client initialisation" } }, - { "E", { true, "execute argument on server initialisation" } }, - { "n", { false, "do not source kakrc files on startup" } }, - { "s", { true, "set session name" } }, - { "d", { false, "run as a headless session (requires -s)" } }, - { "p", { true, "just send stdin as commands to the given session" } }, - { "f", { true, "filter: for each file, select the entire buffer and execute the given keys" } }, - { "i", { true, "backup the files on which a filter is applied using the given suffix" } }, - { "q", { false, "in filter mode, be quiet about errors applying keys" } }, - { "ui", { true, "set the type of user interface to use (terminal, dummy, or json)" } }, - { "l", { false, "list existing sessions" } }, - { "clear", { false, "clear dead sessions" } }, - { "debug", { true, "initial debug option value" } }, - { "version", { false, "display kakoune version and exit" } }, - { "ro", { false, "readonly mode" } }, - { "help", { false, "display a help message and quit" } } } + SwitchMap{ { "c", { ArgCompleter{}, "connect to given session" } }, + { "e", { ArgCompleter{}, "execute argument on client initialisation" } }, + { "E", { ArgCompleter{}, "execute argument on server initialisation" } }, + { "n", { {}, "do not source kakrc files on startup" } }, + { "s", { ArgCompleter{}, "set session name" } }, + { "d", { {}, "run as a headless session (requires -s)" } }, + { "p", { ArgCompleter{}, "just send stdin as commands to the given session" } }, + { "f", { ArgCompleter{}, "filter: for each file, select the entire buffer and execute the given keys" } }, + { "i", { ArgCompleter{}, "backup the files on which a filter is applied using the given suffix" } }, + { "q", { {}, "in filter mode, be quiet about errors applying keys" } }, + { "ui", { ArgCompleter{}, "set the type of user interface to use (terminal, dummy, or json)" } }, + { "l", { {}, "list existing sessions" } }, + { "clear", { {}, "clear dead sessions" } }, + { "debug", { ArgCompleter{}, "initial debug option value" } }, + { "version", { {}, "display kakoune version and exit" } }, + { "ro", { {}, "readonly mode" } }, + { "help", { {}, "display a help message and quit" } } } }; try diff --git a/src/parameters_parser.cc b/src/parameters_parser.cc index 633cb0927..755753239 100644 --- a/src/parameters_parser.cc +++ b/src/parameters_parser.cc @@ -11,14 +11,14 @@ String generate_switches_doc(const SwitchMap& switches) if (switches.empty()) return res; - auto switch_len = [](auto& sw) { return sw.key.column_length() + (sw.value.takes_arg ? 5 : 0); }; + auto switch_len = [](auto& sw) { return sw.key.column_length() + (sw.value.arg_completer ? 5 : 0); }; auto switches_len = switches | transform(switch_len); const ColumnCount maxlen = *std::max_element(switches_len.begin(), switches_len.end()); for (auto& sw : switches) { res += format("-{} {}{}{}\n", sw.key, - sw.value.takes_arg ? "" : "", + sw.value.arg_completer ? "" : "", String{' ', maxlen - switch_len(sw) + 1}, sw.value.description); } @@ -69,7 +69,7 @@ ParametersParser::ParametersParser(ParameterList params, const ParameterDesc& de } switch_seen[switch_index] = true; - if (it->value.takes_arg) + if (it->value.arg_completer) { if (++i == params.size()) { @@ -80,7 +80,7 @@ ParametersParser::ParametersParser(ParameterList params, const ParameterDesc& de m_state = State::SwitchArgument; } - m_switches[switch_name.str()] = it->value.takes_arg ? params[i] : StringView{}; + m_switches[switch_name.str()] = it->value.arg_completer ? params[i] : StringView{}; } else // positional { diff --git a/src/parameters_parser.hh b/src/parameters_parser.hh index 680c6f939..86ba88ced 100644 --- a/src/parameters_parser.hh +++ b/src/parameters_parser.hh @@ -10,6 +10,8 @@ #include "string.hh" #include "string_utils.hh" +#include + namespace Kakoune { @@ -37,9 +39,15 @@ struct wrong_argument_count : public parameter_error wrong_argument_count() : parameter_error("wrong argument count") {} }; +class Context; +struct Completions; +enum class CompletionFlags; +using ArgCompleter = std::function; + struct SwitchDesc { - bool takes_arg; + Optional arg_completer; String description; };