summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2014-02-14 02:21:06 +0000
committerMaxime Coste <frrrwww@gmail.com>2014-03-02 01:08:11 +0000
commit8aaeaa3187aa6cda3f2b264d474f15b4486c44b5 (patch)
tree7e7d07107add1ee14d141704115845ef3e6e160a
parent8ac19edf674382a33a7ab0acd1bd71175dfe9556 (diff)
Declare commands in a CommandDesc structure
-rw-r--r--src/commands.cc1262
1 files changed, 720 insertions, 542 deletions
diff --git a/src/commands.cc b/src/commands.cc
index e39bac81..addc67ee 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -84,13 +84,42 @@ Buffer* open_fifo(const String& name , const String& filename, Context& context)
return buffer;
}
-static const ParameterDesc edit_params{
- SwitchMap{ { "scratch", { false, "create a scratch buffer, not linked to a file" } },
- { "fifo", { true, "create a buffer reading its content from a named fifo" } } },
- ParameterDesc::Flags::None, 1, 3
+const PerArgumentCommandCompleter filename_completer({
+ [](const Context& context, CompletionFlags flags, const String& prefix, ByteCount cursor_pos)
+ { return Completions{ 0_byte, prefix.length(),
+ complete_filename(prefix,
+ context.options()["ignored_files"].get<Regex>(),
+ cursor_pos) }; }
+});
+
+const PerArgumentCommandCompleter buffer_completer({
+ [](const Context& context, CompletionFlags flags, const String& prefix, ByteCount cursor_pos)
+ { return Completions{ 0_byte, prefix.length(),
+ BufferManager::instance().complete_buffername(prefix, cursor_pos) }; }
+});
+
+const ParameterDesc no_params{
+ SwitchMap{}, ParameterDesc::Flags::None, 0, 0
+};
+
+const ParameterDesc single_name_param{
+ SwitchMap{}, ParameterDesc::Flags::None, 1, 1
+};
+
+const ParameterDesc single_optional_name_param{
+ SwitchMap{}, ParameterDesc::Flags::None, 0, 1
};
-static const char* edit_desc = "edit <switches> <filename>: open the given filename in a buffer";
+struct CommandDesc
+{
+ const char* name;
+ const char* alias;
+ const char* docstring;
+ ParameterDesc params;
+ CommandFlags flags;
+ CommandCompleter completer;
+ void (*func)(const ParametersParser&, Context&);
+};
template<bool force_reload>
void edit(const ParametersParser& parser, Context& context)
@@ -134,12 +163,31 @@ void edit(const ParametersParser& parser, Context& context)
}
}
-static const ParameterDesc write_params{
- SwitchMap{},
- ParameterDesc::Flags::None, 0, 1
+ParameterDesc edit_params{
+ SwitchMap{ { "scratch", { false, "create a scratch buffer, not linked to a file" } },
+ { "fifo", { true, "create a buffer reading its content from a named fifo" } } },
+ ParameterDesc::Flags::None, 1, 3
+};
+
+const CommandDesc edit_cmd = {
+ "edit",
+ "e",
+ "edit <switches> <filename>: open the given filename in a buffer",
+ edit_params,
+ CommandFlags::None,
+ filename_completer,
+ edit<false>
};
-static const char* write_desc = "write [filename]: write the current buffer to it's file or to [filename] if specified";
+const CommandDesc force_edit_cmd = {
+ "edit!",
+ "e!",
+ "edit! <switches> <filename>: open the given filename in a buffer, force reload if needed",
+ edit_params,
+ CommandFlags::None,
+ filename_completer,
+ edit<true>
+};
void write_buffer(const ParametersParser& parser, Context& context)
{
@@ -154,23 +202,32 @@ void write_buffer(const ParametersParser& parser, Context& context)
write_buffer_to_file(buffer, filename);
}
-static const ParameterDesc no_params{
- SwitchMap{},
- ParameterDesc::Flags::None, 0, 0
+const CommandDesc write_cmd = {
+ "write",
+ "w",
+ "write [filename]: write the current buffer to it's file or to [filename] if specified",
+ single_optional_name_param,
+ CommandFlags::None,
+ filename_completer,
+ write_buffer,
};
-static const char* write_all_desc = "write all buffers that are associated to a file";
-
-void write_all_buffers(const ParametersParser& parser, Context& context)
-{
- for (auto& buffer : BufferManager::instance())
+const CommandDesc writeall_cmd = {
+ "writeall",
+ "wa",
+ "write all buffers that are associated to a file",
+ no_params,
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
{
- if ((buffer->flags() & Buffer::Flags::File) and buffer->is_modified())
- write_buffer_to_file(*buffer, buffer->name());
+ for (auto& buffer : BufferManager::instance())
+ {
+ if ((buffer->flags() & Buffer::Flags::File) and buffer->is_modified())
+ write_buffer_to_file(*buffer, buffer->name());
+ }
}
-}
-
-static const char* quit_desc = "quit current client, and the kakoune session if the client is the last (if not running in daemon mode)";
+};
template<bool force>
void quit(const ParametersParser& parser, Context& context)
@@ -200,34 +257,74 @@ void quit(const ParametersParser& parser, Context& context)
throw client_removed{};
}
-static const char* write_and_quit_desc = "write current buffer and quit current client";
-
-template<bool force>
-void write_and_quit(const ParametersParser& parser, Context& context)
-{
- write_buffer(parser, context);
- quit<force>(ParametersParser{memoryview<String>{}, no_params}, context);
-}
-
-static const ParameterDesc single_name_params{ SwitchMap{}, ParameterDesc::Flags::None, 1, 1 };
+const CommandDesc quit_cmd = {
+ "quit",
+ "q",
+ "quit current client, and the kakoune session if the client is the last (if not running in daemon mode)",
+ no_params,
+ CommandFlags::None,
+ CommandCompleter{},
+ quit<false>
+};
-static const char* show_buffer_desc = "buffer <name>: set buffer to edit in current client";
+const CommandDesc force_quit_cmd = {
+ "quit!",
+ "q!",
+ "quit current client, and the kakoune session if the client is the last (if not running in daemon mode)\n"
+ "force quit even if the client is the last and some buffers are not saved.",
+ no_params,
+ CommandFlags::None,
+ CommandCompleter{},
+ quit<true>
+};
-void show_buffer(const ParametersParser& parser, Context& context)
-{
- Buffer& buffer = BufferManager::instance().get_buffer(parser[0]);
- BufferManager::instance().set_last_used_buffer(buffer);
+const CommandDesc write_quit_cmd = {
+ "wq",
+ nullptr,
+ "write current buffer and quit current client",
+ no_params,
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
+ {
+ write_buffer(parser, context);
+ quit<false>(ParametersParser{memoryview<String>{}, no_params}, context);
+ }
+};
- if (&buffer != &context.buffer())
+const CommandDesc force_write_quit_cmd = {
+ "wq!",
+ nullptr,
+ "write current buffer and quit current client, even if other buffers are not saved",
+ no_params,
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
{
- context.push_jump();
- context.change_buffer(buffer);
+ write_buffer(parser, context);
+ quit<true>(ParametersParser{memoryview<String>{}, no_params}, context);
}
-}
+};
-static const ParameterDesc single_opt_name_params{ SwitchMap{}, ParameterDesc::Flags::None, 0, 1 };
+const CommandDesc buffer_cmd = {
+ "buffer",
+ "b",
+ "buffer <name>: set buffer to edit in current client",
+ single_name_param,
+ CommandFlags::None,
+ buffer_completer,
+ [](const ParametersParser& parser, Context& context)
+ {
+ Buffer& buffer = BufferManager::instance().get_buffer(parser[0]);
+ BufferManager::instance().set_last_used_buffer(buffer);
-static const char* delete_buffer_desc = "delbuf [name]: delete the current buffer or the buffer named <name> if given";
+ if (&buffer != &context.buffer())
+ {
+ context.push_jump();
+ context.change_buffer(buffer);
+ }
+ }
+};
template<bool force>
void delete_buffer(const ParametersParser& parser, Context& context)
@@ -243,76 +340,150 @@ void delete_buffer(const ParametersParser& parser, Context& context)
manager.delete_buffer(buffer);
}
-static const char* set_buffer_name_desc = "namebuf <name>: change current buffer name";
+const CommandDesc delbuf_cmd = {
+ "delbuf",
+ "db",
+ "delbuf [name]: delete the current buffer or the buffer named <name> if given",
+ single_optional_name_param,
+ CommandFlags::None,
+ buffer_completer,
+ delete_buffer<false>
+};
-void set_buffer_name(const ParametersParser& parser, Context& context)
+const CommandDesc force_delbuf_cmd = {
+ "delbuf!",
+ "db!",
+ "delbuf! [name]: delete the current buffer or the buffer named <name> if given, even if the buffer is unsaved",
+ single_optional_name_param,
+ CommandFlags::None,
+ buffer_completer,
+ delete_buffer<false>
+};
+
+const CommandDesc namebuf_cmd = {
+ "namebuf",
+ nullptr,
+ "namebuf <name>: change current buffer name",
+ single_name_param,
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
+ {
+ if (not context.buffer().set_name(parser[0]))
+ throw runtime_error("unable to change buffer name to " + parser[0]);
+ }
+};
+
+const CommandDesc define_highlighter_cmd = {
+ "defhl",
+ "dh",
+ "defhl <name>: define a new reusable highlighter",
+ single_name_param,
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
+ {
+ const String& name = parser[0];
+ DefinedHighlighters::instance().append({name, HighlighterGroup{}});
+ }
+};
+
+template<typename GetRootGroup>
+CommandCompleter group_rm_completer(GetRootGroup get_root_group)
{
- if (not context.buffer().set_name(parser[0]))
- throw runtime_error("unable to change buffer name to " + parser[0]);
+ return [=](const Context& context, CompletionFlags flags,
+ CommandParameters params, size_t token_to_complete,
+ ByteCount pos_in_token) -> Completions {
+ auto& root_group = get_root_group(context);
+ const String& arg = params[token_to_complete];
+ if (token_to_complete == 1 and params[0] == "-group")
+ return { 0_byte, arg.length(), root_group.complete_group_id(arg, pos_in_token) };
+ else if (token_to_complete == 2 and params[0] == "-group")
+ return { 0_byte, arg.length(), root_group.get_group(params[1], '/').complete_id(arg, pos_in_token) };
+ return { 0_byte, arg.length(), root_group.complete_id(arg, pos_in_token) };
+ };
}
-static const char* define_highlighter_desc = "defhl <name>: define a new reusable highlighter";
-
-void define_highlighter(const ParametersParser& parser, Context& context)
+template<typename FactoryRegistry, typename GetRootGroup>
+CommandCompleter group_add_completer(GetRootGroup get_root_group)
{
- const String& name = parser[0];
- DefinedHighlighters::instance().append({name, HighlighterGroup{}});
+ return [=](const Context& context, CompletionFlags flags,
+ CommandParameters params, size_t token_to_complete,
+ ByteCount pos_in_token) -> Completions {
+ auto& root_group = get_root_group(context);
+ const String& arg = params[token_to_complete];
+ if (token_to_complete == 1 and params[0] == "-group")
+ return { 0_byte, arg.length(), root_group.complete_group_id(arg, pos_in_token) };
+ else if (token_to_complete == 0 or (token_to_complete == 2 and params[0] == "-group"))
+ return { 0_byte, arg.length(), FactoryRegistry::instance().complete_name(arg, pos_in_token) };
+ return Completions{};
+ };
}
-static const ParameterDesc add_highlighter_params{
- SwitchMap{ { "group", { true, "add highlighter to named group" } },
- { "def-group", { true, "add highlighter to reusable defined group" } } },
- ParameterDesc::Flags::SwitchesOnlyAtStart, 1
-};
+HighlighterGroup& get_highlighters(const Context& c) { return c.window().highlighters(); }
+
+const CommandDesc add_highlighter_cmd = {
+ "addhl",
+ "ah",
+ "addhl <switches> <type> <type params>...: add an highlighter to current window",
+ ParameterDesc{
+ SwitchMap{ { "group", { true, "add highlighter to named group" } },
+ { "def-group", { true, "add highlighter to reusable defined group" } } },
+ ParameterDesc::Flags::SwitchesOnlyAtStart, 1
+ },
+ CommandFlags::None,
+ group_add_completer<HighlighterRegistry>(get_highlighters),
+ [](const ParametersParser& parser, Context& context)
+ {
+ HighlighterRegistry& registry = HighlighterRegistry::instance();
-static const char* add_highlighter_desc = "addhl <switches> <type> <type params>...: add an highlighter to current window";
+ auto begin = parser.begin();
+ const String& name = *begin;
+ std::vector<String> highlighter_params;
+ for (++begin; begin != parser.end(); ++begin)
+ highlighter_params.push_back(*begin);
-void add_highlighter(const ParametersParser& parser, Context& context)
-{
- HighlighterRegistry& registry = HighlighterRegistry::instance();
+ if (parser.has_option("group") and parser.has_option("def-group"))
+ throw runtime_error("-group and -def-group cannot be specified together");
- auto begin = parser.begin();
- const String& name = *begin;
- std::vector<String> highlighter_params;
- for (++begin; begin != parser.end(); ++begin)
- highlighter_params.push_back(*begin);
+ HighlighterGroup* group = nullptr;
- if (parser.has_option("group") and parser.has_option("def-group"))
- throw runtime_error("-group and -def-group cannot be specified together");
+ if (parser.has_option("def-group"))
+ group = &DefinedHighlighters::instance().get_group(parser.option_value("def-group"), '/');
+ else
+ {
+ HighlighterGroup& window_hl = context.window().highlighters();
+ group = parser.has_option("group") ?
+ &window_hl.get_group(parser.option_value("group"), '/')
+ : &window_hl;
+ }
- HighlighterGroup* group = nullptr;
+ group->append(registry[name](highlighter_params));
+ }
+};
- if (parser.has_option("def-group"))
- group = &DefinedHighlighters::instance().get_group(parser.option_value("def-group"), '/');
- else
+const CommandDesc rm_highlighter_cmd = {
+ "rmhl",
+ "rh",
+ "rmhl <switches> <name>: remove highlighter <name> from current window",
+ ParameterDesc{
+ SwitchMap{ { "group", { true, "remove highlighter from given group" } } },
+ ParameterDesc::Flags::None, 1, 1
+ },
+ CommandFlags::None,
+ group_rm_completer(get_highlighters),
+ [](const ParametersParser& parser, Context& context)
{
HighlighterGroup& window_hl = context.window().highlighters();
- group = parser.has_option("group") ?
- &window_hl.get_group(parser.option_value("group"), '/')
- : &window_hl;
- }
-
- group->append(registry[name](highlighter_params));
-}
+ HighlighterGroup& group = parser.has_option("group") ?
+ window_hl.get_group(parser.option_value("group"), '/')
+ : window_hl;
-static const ParameterDesc rm_highlighter_params{
- SwitchMap{ { "group", { true, "remove highlighter from given group" } } },
- ParameterDesc::Flags::None, 1, 1
+ group.remove(parser[0]);
+ }
};
-static const char* rm_highlighter_desc = "rmhl <switches> <name>: remove highlighter <name> from current window";
-
-void rm_highlighter(const ParametersParser& parser, Context& context)
-{
- HighlighterGroup& window_hl = context.window().highlighters();
- HighlighterGroup& group = parser.has_option("group") ?
- window_hl.get_group(parser.option_value("group"), '/')
- : window_hl;
-
- group.remove(parser[0]);
-}
-
-static HookManager& get_hook_manager(const String& scope, Context& context)
+HookManager& get_hook_manager(const String& scope, Context& context)
{
if (prefix_match("global", scope))
return GlobalHooks::instance();
@@ -323,36 +494,66 @@ static HookManager& get_hook_manager(const String& scope, Context& context)
throw runtime_error("error: no such hook container " + scope);
}
-static const ParameterDesc add_hook_params{
- SwitchMap{ { "id", { true, "set hook id" } } }, ParameterDesc::Flags::None, 4, 4
-};
-
-static const char* add_hook_desc = "hook <switches> <scope> <hook_name> <command>: add <command> to be executed on hook <hook_name> in <scope> context";
-
-void add_hook(const ParametersParser& parser, Context& context)
+CandidateList complete_scope(const String& prefix)
{
- // copy so that the lambda gets a copy as well
- Regex regex(parser[2].begin(), parser[2].end());
- String command = parser[3];
- auto hook_func = [=](const String& param, Context& context) {
- if (boost::regex_match(param.begin(), param.end(), regex))
- CommandManager::instance().execute(command, context, {},
- { { "hook_param", param } });
- };
- String id = parser.has_option("id") ? parser.option_value("id") : "";
- get_hook_manager(parser[0], context).add_hook(parser[1], id, hook_func);
+ CandidateList res;
+ for (auto scope : { "global", "buffer", "window" })
+ {
+ if (prefix_match(scope, prefix))
+ res.emplace_back(scope);
+ }
+ return res;
}
-static const ParameterDesc rm_hooks_params{
- SwitchMap{}, ParameterDesc::Flags::None, 2, 2
+const CommandDesc add_hook_cmd = {
+ "hook",
+ nullptr,
+ "hook <switches> <scope> <hook_name> <command>: add <command> to be executed on hook <hook_name> in <scope> context",
+ ParameterDesc{
+ SwitchMap{ { "id", { true, "set hook id" } } },
+ ParameterDesc::Flags::None, 4, 4
+ },
+ CommandFlags::None,
+ [](const Context& context, CompletionFlags flags,
+ CommandParameters params, size_t token_to_complete, ByteCount pos_in_token)
+ {
+ if (token_to_complete == 0)
+ return Completions{ 0_byte, params[0].length(),
+ complete_scope(params[0].substr(0_byte, pos_in_token)) };
+ else if (token_to_complete == 3)
+ {
+ auto& cm = CommandManager::instance();
+ return cm.complete(context, flags, params[3], pos_in_token);
+ }
+ return Completions{};
+ },
+ [](const ParametersParser& parser, Context& context)
+ {
+ // copy so that the lambda gets a copy as well
+ Regex regex(parser[2].begin(), parser[2].end());
+ String command = parser[3];
+ auto hook_func = [=](const String& param, Context& context) {
+ if (boost::regex_match(param.begin(), param.end(), regex))
+ CommandManager::instance().execute(command, context, {},
+ { { "hook_param", param } });
+ };
+ String id = parser.has_option("id") ? parser.option_value("id") : "";
+ get_hook_manager(parser[0], context).add_hook(parser[1], id, hook_func);
+ }
};
-static const char* rm_hooks_desc = "rmhooks <id>: remove all hooks that whose id is <id>";
-
-void rm_hooks(const ParametersParser& parser, Context& context)
-{
- get_hook_manager(parser[0], context).remove_hooks(parser[1]);
-}
+const CommandDesc rm_hook_cmd = {
+ "rmhooks",
+ nullptr,
+ "rmhooks <id>: remove all hooks that whose id is <id>",
+ ParameterDesc{ SwitchMap{}, ParameterDesc::Flags::None, 2, 2 },
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
+ {
+ get_hook_manager(parser[0], context).remove_hooks(parser[1]);
+ }
+};
EnvVarMap params_to_env_var_map(const ParametersParser& parser)
{
@@ -374,19 +575,6 @@ std::vector<String> params_to_shell(const ParametersParser& parser)
return vars;
}
-static const ParameterDesc define_command_params{
- SwitchMap{ { "env-params", { false, "pass parameters as env variables param0..paramN" } },
- { "shell-params", { false, "pass parameters to each shell escape as $0..$N" } },
- { "allow-override", { false, "allow overriding existing command" } },
- { "file-completion", { false, "complete parameters using filename completion" } },
- { "hidden", { false, "do not display the command as completion candidate" } },
- { "shell-completion", { true, "complete the parameters using the given shell-script" } } },
- ParameterDesc::Flags::None,
- 2, 2
-};
-
-static const char* define_command_desc = "def <switches> <name> <commands>: define a command named <name> corresponding to <commands>";
-
void define_command(const ParametersParser& parser, Context& context)
{
auto begin = parser.begin();
@@ -460,63 +648,87 @@ void define_command(const ParametersParser& parser, Context& context)
CommandManager::instance().register_command(cmd_name, cmd, "", desc, flags, completer);
}
-static const ParameterDesc echo_message_params{
- SwitchMap{ { "color", { true, "set message color" } } },
- ParameterDesc::Flags::SwitchesOnlyAtStart
-};
-
-static const char* echo_message_desc = "echo <params>...: display given parameters in the status line";
-
-void echo_message(const ParametersParser& parser, Context& context)
-{
- String message;
- for (auto& param : parser)
- message += param + " ";
- ColorPair color = get_color(parser.has_option("color") ?
- parser.option_value("color") : "StatusLine");
- context.print_status({ std::move(message), color } );
-}
-
-static const ParameterDesc write_debug_message_params{
- SwitchMap{},
- ParameterDesc::Flags::SwitchesOnlyAtStart
+const CommandDesc define_command_cmd = {
+ "def",
+ nullptr,
+ "def <switches> <name> <commands>: define a command named <name> corresponding to <commands>",
+ ParameterDesc{
+ SwitchMap{ { "env-params", { false, "pass parameters as env variables param0..paramN" } },
+ { "shell-params", { false, "pass parameters to each shell escape as $0..$N" } },
+ { "allow-override", { false, "allow overriding existing command" } },
+ { "file-completion", { false, "complete parameters using filename completion" } },
+ { "hidden", { false, "do not display the command as completion candidate" } },
+ { "shell-completion", { true, "complete the parameters using the given shell-script" } } },
+ ParameterDesc::Flags::None,
+ 2, 2
+ },
+ CommandFlags::None,
+ CommandCompleter{},
+ define_command
};
-static const char* write_debug_message_desc = "debug <params>...: write given parameters in the debug buffer";
-
-void write_debug_message(const ParametersParser& parser, Context&)
-{
- String message;
- for (auto& param : parser)
- message += param + " ";
- write_debug(message);
-}
-
-static const ParameterDesc exec_commands_in_file_params{
- SwitchMap{},
- ParameterDesc::Flags::None,
- 1, 1
+const CommandDesc echo_cmd = {
+ "echo",
+ nullptr,
+ "echo <params>...: display given parameters in the status line",
+ ParameterDesc{
+ SwitchMap{ { "color", { true, "set message color" } } },
+ ParameterDesc::Flags::SwitchesOnlyAtStart
+ },
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
+ {
+ String message;
+ for (auto& param : parser)
+ message += param + " ";
+ ColorPair color = get_color(parser.has_option("color") ?
+ parser.option_value("color") : "StatusLine");
+ context.print_status({ std::move(message), color } );
+ }
};
-static const char* exec_commands_in_file_desc = "source <filename>: execute commands contained in <filename>";
-void exec_commands_in_file(const ParametersParser& parser,
- Context& context)
-{
- String file_content = read_file(parse_filename(parser[0]));
- try
+const CommandDesc debug_cmd = {
+ "debug",
+ nullptr,
+ "debug <params>...: write given parameters in the debug buffer",
+ ParameterDesc{ SwitchMap{}, ParameterDesc::Flags::SwitchesOnlyAtStart },
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context&)
{
- CommandManager::instance().execute(file_content, context);
+ String message;
+ for (auto& param : parser)
+ message += param + " ";
+ write_debug(message);
}
- catch (Kakoune::runtime_error& err)
+};
+
+const CommandDesc source_cmd = {
+ "source",
+ nullptr,
+ "source <filename>: execute commands contained in <filename>",
+ single_name_param,
+ CommandFlags::None,
+ filename_completer,
+ [](const ParametersParser& parser, Context& context)
{
- write_debug("error while executing commands in file '" + parser[0]
- + "'\n " + err.what());
- throw;
+ String file_content = read_file(parse_filename(parser[0]));
+ try
+ {
+ CommandManager::instance().execute(file_content, context);
+ }
+ catch (Kakoune::runtime_error& err)
+ {
+ write_debug("error while executing commands in file '" + parser[0]
+ + "'\n " + err.what());
+ throw;
+ }
}
-}
+};
-static OptionManager& get_options(const String& scope, const Context& context)
+OptionManager& get_options(const String& scope, const Context& context)
{
if (prefix_match("global", scope))
return GlobalOptions::instance();
@@ -529,72 +741,92 @@ static OptionManager& get_options(const String& scope, const Context& context)
throw runtime_error("error: no such option container " + scope);
}
-
-static const ParameterDesc set_option_params{
- SwitchMap{ { "add", { false, "add to option rather than replacing it" } } },
- ParameterDesc::Flags::SwitchesOnlyAtStart,
- 3, 3
+const CommandDesc set_option_cmd = {
+ "set",
+ nullptr,
+ "set <switches> <scope> <name> <value>: set option <name> in <scope> to <value>",
+ ParameterDesc{
+ SwitchMap{ { "add", { false, "add to option rather than replacing it" } } },
+ ParameterDesc::Flags::SwitchesOnlyAtStart,
+ 3, 3
+ },
+ CommandFlags::None,
+ [](const Context& context, CompletionFlags,
+ CommandParameters params, size_t token_to_complete,
+ ByteCount pos_in_token) -> Completions
+ {
+ if (token_to_complete == 0)
+ return { 0_byte, params[0].length(),
+ complete_scope(params[0].substr(0_byte, pos_in_token)) };
+ else if (token_to_complete == 1)
+ {
+ OptionManager& options = get_options(params[0], context);
+ return { 0_byte, params[1].length(),
+ options.complete_option_name(params[1], pos_in_token) };
+ }
+ return Completions{};
+ },
+ [](const ParametersParser& parser, Context& context)
+ {
+ Option& opt = get_options(parser[0], context).get_local_option(parser[1]);
+ if (parser.has_option("add"))
+ opt.add_from_string(parser[2]);
+ else
+ opt.set_from_string(parser[2]);
+ }
};
-static const char* set_option_desc = "set <switches> <scope> <name> <value>: set option <name> in <scope> to <value>";
-
-void set_option(const ParametersParser& parser, Context& context)
-{
- Option& opt = get_options(parser[0], context).get_local_option(parser[1]);
- if (parser.has_option("add"))
- opt.add_from_string(parser[2]);
- else
- opt.set_from_string(parser[2]);
-}
+const CommandDesc declare_option_cmd = {
+ "decl",
+ nullptr,
+ "decl <type> <name> [value]: declare option <name> of type <type>, with initial value <value> if given\n"
+ "Available types:\n"
+ " int: integer\n"
+ " bool: boolean (true/false or yes/no)\n"
+ " str: character string\n"
+ " regex: regular expression\n"
+ " int-list: list of integers\n"
+ " str-list: list of character strings\n"
+ " line-flag-list: list of line flags\n",
+ ParameterDesc{
+ SwitchMap{ { "hidden", { false, "do not display option name when completing" } } },
+ ParameterDesc::Flags::SwitchesOnlyAtStart,
+ 2, 3
+ },
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
+ {
+ Option* opt = nullptr;
+
+ Option::Flags flags = Option::Flags::None;
+ if (parser.has_option("hidden"))
+ flags = Option::Flags::Hidden;
+
+ GlobalOptions& opts = GlobalOptions::instance();
+
+ if (parser[0] == "int")
+ opt = &opts.declare_option<int>(parser[1], 0, flags);
+ if (parser[0] == "bool")
+ opt = &opts.declare_option<bool>(parser[1], 0, flags);
+ else if (parser[0] == "str")
+ opt = &opts.declare_option<String>(parser[1], "", flags);
+ else if (parser[0] == "regex")
+ opt = &opts.declare_option<Regex>(parser[1], Regex{}, flags);
+ else if (parser[0] == "int-list")
+ opt = &opts.declare_option<std::vector<int>>(parser[1], {}, flags);
+ else if (parser[0] == "str-list")
+ opt = &opts.declare_option<std::vector<String>>(parser[1], {}, flags);
+ else if (parser[0] == "line-flag-list")
+ opt = &opts.declare_option<std::vector<LineAndFlag>>(parser[1], {}, flags);
+ else
+ throw runtime_error("unknown type " + parser[0]);
-static const ParameterDesc declare_option_params{
- SwitchMap{ { "hidden", { false, "do not display option name when completing" } } },
- ParameterDesc::Flags::SwitchesOnlyAtStart,
- 2, 3
+ if (parser.positional_count() == 3)
+ opt->set_from_string(parser[2]);
+ }
};
-static const char* declare_option_desc =
-"decl <type> <name> [value]: declare option <name> of type <type>, with initial value <value> if given\n"
-"Available types:\n"
-" int: integer\n"
-" bool: boolean (true/false or yes/no)\n"
-" str: character string\n"
-" regex: regular expression\n"
-" int-list: list of integers\n"
-" str-list: list of character strings\n"
-" line-flag-list: list of line flags\n";
-
-void declare_option(const ParametersParser& parser, Context& context)
-{
- Option* opt = nullptr;
-
- Option::Flags flags = Option::Flags::None;
- if (parser.has_option("hidden"))
- flags = Option::Flags::Hidden;
-
- GlobalOptions& opts = GlobalOptions::instance();
-
- if (parser[0] == "int")
- opt = &opts.declare_option<int>(parser[1], 0, flags);
- if (parser[0] == "bool")
- opt = &opts.declare_option<bool>(parser[1], 0, flags);
- else if (parser[0] == "str")
- opt = &opts.declare_option<String>(parser[1], "", flags);
- else if (parser[0] == "regex")
- opt = &opts.declare_option<Regex>(parser[1], Regex{}, flags);
- else if (parser[0] == "int-list")
- opt = &opts.declare_option<std::vector<int>>(parser[1], {}, flags);
- else if (parser[0] == "str-list")
- opt = &opts.declare_option<std::vector<String>>(parser[1], {}, flags);
- else if (parser[0] == "line-flag-list")
- opt = &opts.declare_option<std::vector<LineAndFlag>>(parser[1], {}, flags);
- else
- throw runtime_error("unknown type " + parser[0]);
-
- if (parser.positional_count() == 3)
- opt->set_from_string(parser[2]);
-}
-
KeymapManager& get_keymap_manager(const String& scope, Context& context)
{
@@ -616,30 +848,31 @@ KeymapMode parse_keymap_mode(const String& str)
throw runtime_error("unknown keymap mode '" + str + "'");
}
-static const ParameterDesc map_key_params{
- SwitchMap{}, ParameterDesc::Flags::None, 4, 4
-};
-
-static const char* map_key_desc =
-"map <mode> <key> <keys>: map <key> to <keys> in given mode.\n"
-"Valid modes:\n"
-" normal\n"
-" insert\n"
-" menu\n"
-" prompt\n";
-
-void map_key(const ParametersParser& parser, Context& context)
-{
- KeymapManager& keymaps = get_keymap_manager(parser[0], context);
- KeymapMode keymap_mode = parse_keymap_mode(parser[1]);
+const CommandDesc map_key_cmd = {
+ "map",
+ nullptr,
+ "map <mode> <key> <keys>: map <key> to <keys> in given mode.\n"
+ "Valid modes:\n"
+ " normal\n"
+ " insert\n"
+ " menu\n"
+ " prompt\n",
+ ParameterDesc{ SwitchMap{}, ParameterDesc::Flags::None, 4, 4 },
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
+ {
+ KeymapManager& keymaps = get_keymap_manager(parser[0], context);
+ KeymapMode keymap_mode = parse_keymap_mode(parser[1]);
- KeyList key = parse_keys(parser[2]);
- if (key.size() != 1)
- throw runtime_error("only a single key can be mapped");
+ KeyList key = parse_keys(parser[2]);
+ if (key.size() != 1)
+ throw runtime_error("only a single key can be mapped");
- KeyList mapping = parse_keys(parser[3]);
- keymaps.map_key(key[0], keymap_mode, std::move(mapping));
-}
+ KeyList mapping = parse_keys(parser[3]);
+ keymaps.map_key(key[0], keymap_mode, std::move(mapping));
+ }
+};
const ParameterDesc context_wrap_params = {
SwitchMap{ { "client", { true, "run in given client context" } },
@@ -697,220 +930,219 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func)
real_context->window().forget_timestamp();
}
-static const char* exec_string_desc = "exec <switches> <keys>: execute given keys as if entered by user";
-
-void exec_string(const ParametersParser& parser, Context& context)
-{
- context_wrap(parser, context, [](const ParametersParser& parser, Context& context) {
- KeyList keys;
- for (auto& param : parser)
- {
- KeyList param_keys = parse_keys(param);
- keys.insert(keys.end(), param_keys.begin(), param_keys.end());
- }
- exec_keys(keys, context);
- });
-}
-
-static const char* eval_string_desc = "eval <switches> <keys>: execute commands as if entered by user";
-
-void eval_string(const ParametersParser& parser, Context& context)
-{
- context_wrap(parser, context, [](const ParametersParser& parser, Context& context) {
- String command;
- for (auto& param : parser)
- command += param + " ";
- CommandManager::instance().execute(command, context);
- });
-}
-
-static const ParameterDesc menu_params{
- SwitchMap{ { "auto-single", { false, "instantly validate if only one item is available" } },
- { "select-cmds", { false, "each item specify an additional command to run when selected" } } }
+const CommandDesc exec_string_cmd = {
+ "exec",
+ nullptr,
+ "exec <switches> <keys>: execute given keys as if entered by user",
+ context_wrap_params,
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
+ {
+ context_wrap(parser, context, [](const ParametersParser& parser, Context& context) {
+ KeyList keys;
+ for (auto& param : parser)
+ {
+ KeyList param_keys = parse_keys(param);
+ keys.insert(keys.end(), param_keys.begin(), param_keys.end());
+ }
+ exec_keys(keys, context);
+ });
+ }
};
-static const char* menu_desc = "menu <switches> <name1> <commands1> <name2> <commands2>...: display a menu and execute commands for the selected item";
-
-
-void menu(const ParametersParser& parser, Context& context)
-{
- const bool with_select_cmds = parser.has_option("select-cmds");
- const size_t modulo = with_select_cmds ? 3 : 2;
-
- const size_t count = parser.positional_count();
- if (count == 0 or (count % modulo) != 0)
- throw wrong_argument_count();
-
- if (count == modulo and parser.has_option("auto-single"))
+const CommandDesc eval_string_cmd = {
+ "eval",
+ nullptr,
+ "eval <switches> <keys>: execute commands as if entered by user",
+ context_wrap_params,
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
{
- CommandManager::instance().execute(parser[1], context);
- return;
+ context_wrap(parser, context, [](const ParametersParser& parser, Context& context) {
+ String command;
+ for (auto& param : parser)
+ command += param + " ";
+ CommandManager::instance().execute(command, context);
+ });
}
+};
- std::vector<String> choices;
- std::vector<String> commands;
- std::vector<String> select_cmds;
- for (int i = 0; i < count; i += modulo)
+const CommandDesc menu_cmd = {
+ "menu",
+ nullptr,
+ "menu <switches> <name1> <commands1> <name2> <commands2>...: display a menu and execute commands for the selected item",
+ ParameterDesc{
+ SwitchMap{ { "auto-single", { false, "instantly validate if only one item is available" } },
+ { "select-cmds", { false, "each item specify an additional command to run when selected" } } }
+ },
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
{
- choices.push_back(parser[i]);
- commands.push_back(parser[i+1]);
- if (with_select_cmds)
- select_cmds.push_back(parser[i+2]);
- }
+ const bool with_select_cmds = parser.has_option("select-cmds");
+ const size_t modulo = with_select_cmds ? 3 : 2;
- context.input_handler().menu(choices,
- [=](int choice, MenuEvent event, Context& context) {
- if (event == MenuEvent::Validate and choice >= 0 and choice < commands.size())
- CommandManager::instance().execute(commands[choice], context);
- if (event == MenuEvent::Select and choice >= 0 and choice < select_cmds.size())
- CommandManager::instance().execute(select_cmds[choice], context);
- });
-}
+ const size_t count = parser.positional_count();
+ if (count == 0 or (count % modulo) != 0)
+ throw wrong_argument_count();
-static const ParameterDesc info_params{
- SwitchMap{ { "anchor", { true, "set info anchoring (left, right, or cursor)" } },
- { "title", { true, "set info title" } } },
- ParameterDesc::Flags::None, 0, 1
-};
+ if (count == modulo and parser.has_option("auto-single"))
+ {
+ CommandManager::instance().execute(parser[1], context);
+ return;
+ }
-static const char* info_desc = "info <switches> <params>...: display an info box with the params as content";
+ std::vector<String> choices;
+ std::vector<String> commands;
+ std::vector<String> select_cmds;
+ for (int i = 0; i < count; i += modulo)
+ {
+ choices.push_back(parser[i]);
+ commands.push_back(parser[i+1]);
+ if (with_select_cmds)
+ select_cmds.push_back(parser[i+2]);
+ }
-void info(const ParametersParser& parser, Context& context)
-{
- context.ui().info_hide();
- if (parser.positional_count() > 0)
+ context.input_handler().menu(choices,
+ [=](int choice, MenuEvent event, Context& context) {
+ if (event == MenuEvent::Validate and choice >= 0 and choice < commands.size())
+ CommandManager::instance().execute(commands[choice], context);
+ if (event == MenuEvent::Select and choice >= 0 and choice < select_cmds.size())
+ CommandManager::instance().execute(select_cmds[choice], context);
+ });
+ }
+};
+
+const CommandDesc info_cmd = {
+ "info",
+ nullptr,
+ "info <switches> <params>...: display an info box with the params as content",
+ ParameterDesc{
+ SwitchMap{ { "anchor", { true, "set info anchoring (left, right, or cursor)" } },
+ { "title", { true, "set info title" } } },
+ ParameterDesc::Flags::None, 0, 1
+ },
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
{
- MenuStyle style = MenuStyle::Prompt;
- DisplayCoord pos = context.ui().dimensions();
- pos.column -= 1;
- if (parser.has_option("anchor"))
+ context.ui().info_hide();
+ if (parser.positional_count() > 0)
{
- style = MenuStyle::Inline;
- const auto& sel = context.selections().main();
- auto it = sel.cursor();
- String anchor = parser.option_value("anchor");
- if (anchor == "left")
- it = sel.min();
- else if (anchor == "right")
- it = sel.max();
- else if (anchor != "cursor")
- throw runtime_error("anchor param must be one of [left, right, cursor]");
- pos = context.window().display_position(it);
+ MenuStyle style = MenuStyle::Prompt;
+ DisplayCoord pos = context.ui().dimensions();
+ pos.column -= 1;
+ if (parser.has_option("anchor"))
+ {
+ style = MenuStyle::Inline;
+ const auto& sel = context.selections().main();
+ auto it = sel.cursor();
+ String anchor = parser.option_value("anchor");
+ if (anchor == "left")
+ it = sel.min();
+ else if (anchor == "right")
+ it = sel.max();
+ else if (anchor != "cursor")
+ throw runtime_error("anchor param must be one of [left, right, cursor]");
+ pos = context.window().display_position(it);
+ }
+ const String& title = parser.has_option("title") ? parser.option_value("title") : "";
+ context.ui().info_show(title, parser[0], pos, get_color("Information"), style);
}
- const String& title = parser.has_option("title") ? parser.option_value("title") : "";
- context.ui().info_show(title, parser[0], pos, get_color("Information"), style);
}
-}
-
-static const ParameterDesc try_catch_params{
- SwitchMap{}, ParameterDesc::Flags::None, 1, 3
};
-static const char* try_catch_desc = "try <command> [catch <error_command>]: execute command in current context, and if an error is raised, execute <error_command> if specified.\nThe error is not propagated further.";
-
-void try_catch(const ParametersParser& parser, Context& context)
-{
- if (parser.positional_count() == 2)
- throw wrong_argument_count();
+const CommandDesc try_catch_cmd = {
+ "try",
+ nullptr,
+ "try <command> [catch <error_command>]: execute command in current context.\n"
+ "if an error is raised and <error_command> is specified, execute it.\n"
+ "The error is not propagated further.",
+ ParameterDesc{ SwitchMap{}, ParameterDesc::Flags::None, 1, 3 },
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
+ {
+ if (parser.positional_count() == 2)
+ throw wrong_argument_count();
- const bool do_catch = parser.positional_count() == 3;
- if (do_catch and parser[1] != "catch")
- throw runtime_error("usage: try <commands> [catch <on error commands>]");
+ const bool do_catch = parser.positional_count() == 3;
+ if (do_catch and parser[1] != "catch")
+ throw runtime_error("usage: try <commands> [catch <on error commands>]");
- CommandManager& command_manager = CommandManager::instance();
- try
- {
- command_manager.execute(parser[0], context);
+ CommandManager& command_manager = CommandManager::instance();
+ try
+ {
+ command_manager.execute(parser[0], context);
+ }
+ catch (Kakoune::runtime_error& e)
+ {
+ if (do_catch)
+ command_manager.execute(parser[2], context);
+ }
}
- catch (Kakoune::runtime_error& e)
+};
+
+const CommandDesc define_color_alias_cmd = {
+ "colalias",
+ "ca",
+ "colalias <name> <color>: set <name> to refer to color <color> (which can be an alias itself)",
+ ParameterDesc{ SwitchMap{}, ParameterDesc::Flags::None, 2, 2 },
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
{
- if (do_catch)
- command_manager.execute(parser[2], context);
+ ColorRegistry::instance().register_alias(parser[0], parser[1], true);
}
-}
-
-static const ParameterDesc define_color_alias_params{
- SwitchMap{}, ParameterDesc::Flags::None, 2, 2
};
-static const char* define_color_alias_desc = "colalias <name> <color>: set <name> to refer to color <color> (which can be an alias itself)";
-
-void define_color_alias(const ParametersParser& parser, Context& context)
-{
- ColorRegistry::instance().register_alias(parser[0], parser[1], true);
-}
-
-static const ParameterDesc set_client_name_params{
- SwitchMap{}, ParameterDesc::Flags::None, 1, 1
+const CommandDesc set_client_name_cmd = {
+ "nameclient",
+ "nc",
+ "nameclient <name>: set current client name to <name>",
+ single_name_param,
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
+ {
+ if (ClientManager::instance().validate_client_name(parser[0]))
+ context.set_name(parser[0]);
+ else if (context.name() != parser[0])
+ throw runtime_error("client name '" + parser[0] + "' is not unique");
+ }
};
-static const char* set_client_name_desc = "nameclient <name>: set current client name to <name>";
-
-void set_client_name(const ParametersParser& parser, Context& context)
-{
- if (ClientManager::instance().validate_client_name(parser[0]))
- context.set_name(parser[0]);
- else if (context.name() != parser[0])
- throw runtime_error("client name '" + parser[0] + "' is not unique");
-}
-
-static const ParameterDesc set_register_params{
- SwitchMap{}, ParameterDesc::Flags::None, 2, 2
+const CommandDesc set_register_cmd = {
+ "reg",
+ nullptr,
+ "reg <name> <value>: set register <name> to <value>",
+ ParameterDesc{ SwitchMap{}, ParameterDesc::Flags::None, 2, 2 },
+ CommandFlags::None,
+ CommandCompleter{},
+ [](const ParametersParser& parser, Context& context)
+ {
+ if (parser[0].length() != 1)
+ throw runtime_error("register names are single character");
+ RegisterManager::instance()[parser[0][0]] = memoryview<String>(parser[1]);
+ }
};
-static const char* set_register_desc = "reg <name> <value>: set register <name> to <value>";
-
-void set_register(const ParametersParser& parser, Context& context)
-{
- if (parser[0].length() != 1)
- throw runtime_error("register names are single character");
- RegisterManager::instance()[parser[0][0]] = memoryview<String>(parser[1]);
-}
-
-static const ParameterDesc change_working_directory_params{
- SwitchMap{}, ParameterDesc::Flags::None, 1, 1
+const CommandDesc change_working_directory_cmd = {
+ "cd",
+ nullptr,
+ "cd <dir>: change server working directory to <dir>",
+ single_name_param,
+ CommandFlags::None,
+ filename_completer,
+ [](const ParametersParser& parser, Context&)
+ {
+ if (chdir(parse_filename(parser[0]).c_str()) != 0)
+ throw runtime_error("cannot change to directory " + parser[0]);
+ }
};
-static const char* change_working_directory_desc = "cd <dir>: change server working directory to <dir>";
-
-void change_working_directory(const ParametersParser& parser, Context&)
-{
- if (chdir(parse_filename(parser[0]).c_str()) != 0)
- throw runtime_error("cannot change to directory " + parser[0]);
-}
-
-template<typename GetRootGroup>
-CommandCompleter group_rm_completer(GetRootGroup get_root_group)
-{
- return [=](const Context& context, CompletionFlags flags,
- CommandParameters params, size_t token_to_complete,
- ByteCount pos_in_token) -> Completions {
- auto& root_group = get_root_group(context);
- const String& arg = params[token_to_complete];
- if (token_to_complete == 1 and params[0] == "-group")
- return { 0_byte, arg.length(), root_group.complete_group_id(arg, pos_in_token) };
- else if (token_to_complete == 2 and params[0] == "-group")
- return { 0_byte, arg.length(), root_group.get_group(params[1], '/').complete_id(arg, pos_in_token) };
- return { 0_byte, arg.length(), root_group.complete_id(arg, pos_in_token) };
- };
-}
-
-template<typename FactoryRegistry, typename GetRootGroup>
-CommandCompleter group_add_completer(GetRootGroup get_root_group)
-{
- return [=](const Context& context, CompletionFlags flags,
- CommandParameters params, size_t token_to_complete,
- ByteCount pos_in_token) -> Completions {
- auto& root_group = get_root_group(context);
- const String& arg = params[token_to_complete];
- if (token_to_complete == 1 and params[0] == "-group")
- return { 0_byte, arg.length(), root_group.complete_group_id(arg, pos_in_token) };
- else if (token_to_complete == 0 or (token_to_complete == 2 and params[0] == "-group"))
- return { 0_byte, arg.length(), FactoryRegistry::instance().complete_name(arg, pos_in_token) };
- return Completions{};
- };
-}
-
class RegisterRestorer
{
public:
@@ -942,106 +1174,52 @@ void exec_keys(const KeyList& keys, Context& context)
context.input_handler().handle_key(key);
}
-CandidateList complete_scope(const String& prefix)
+static void register_command(CommandManager& cm, const CommandDesc& c)
{
- CandidateList res;
- for (auto scope : { "global", "buffer", "window" })
- {
- if (prefix_match(scope, prefix))
- res.emplace_back(scope);
- }
- return res;
+ if (c.alias)
+ cm.register_commands({ c.name, c.alias }, c.func, c.docstring, c.params, c.flags, c.completer);
+ else
+ cm.register_command(c.name, c.func, c.docstring, c.params, c.flags, c.completer);
}
void register_commands()
{
CommandManager& cm = CommandManager::instance();
- cm.register_commands({"nop"}, [](const ParametersParser&, Context&){}, "do nothing", {});
-
- PerArgumentCommandCompleter filename_completer({
- [](const Context& context, CompletionFlags flags, const String& prefix, ByteCount cursor_pos)
- { return Completions{ 0_byte, prefix.length(),
- complete_filename(prefix,
- context.options()["ignored_files"].get<Regex>(),
- cursor_pos) }; }
- });
- cm.register_commands({ "edit", "e" }, edit<false>, edit_desc, edit_params, CommandFlags::None, filename_completer);
- cm.register_commands({ "edit!", "e!" }, edit<true>, edit_desc, edit_params, CommandFlags::None, filename_completer);
- cm.register_commands({ "write", "w" }, write_buffer, write_desc, write_params, CommandFlags::None, filename_completer);
- cm.register_commands({ "writeall", "wa" }, write_all_buffers, write_all_desc, no_params);
- cm.register_commands({ "quit", "q" }, quit<false>, quit_desc, no_params);
- cm.register_commands({ "quit!", "q!" }, quit<true>, quit_desc, no_params);
- cm.register_command("wq", write_and_quit<false>, write_and_quit_desc, no_params);
- cm.register_command("wq!", write_and_quit<true>, write_and_quit_desc, no_params);
-
- PerArgumentCommandCompleter buffer_completer({
- [](const Context& context, CompletionFlags flags, const String& prefix, ByteCount cursor_pos)
- { return Completions{ 0_byte, prefix.length(),
- BufferManager::instance().complete_buffername(prefix, cursor_pos) }; }
- });
- cm.register_commands({ "buffer", "b" }, show_buffer, show_buffer_desc, single_name_params, CommandFlags::None, buffer_completer);
- cm.register_commands({ "delbuf", "db" }, delete_buffer<false>, delete_buffer_desc, single_opt_name_params, CommandFlags::None, buffer_completer);
- cm.register_commands({ "delbuf!", "db!" }, delete_buffer<true>, delete_buffer_desc, single_opt_name_params, CommandFlags::None, buffer_completer);
- cm.register_commands({ "namebuf", "nb" }, set_buffer_name, set_buffer_name_desc, single_name_params);
-
- auto get_highlighters = [](const Context& c) -> HighlighterGroup& { return c.window().highlighters(); };
- cm.register_commands({ "addhl", "ah" }, add_highlighter, add_highlighter_desc, add_highlighter_params, CommandFlags::None, group_add_completer<HighlighterRegistry>(get_highlighters));
- cm.register_commands({ "rmhl", "rh" }, rm_highlighter, rm_highlighter_desc, rm_highlighter_params, CommandFlags::None, group_rm_completer(get_highlighters));
- cm.register_commands({ "defhl", "dh" }, define_highlighter, define_highlighter_desc, single_name_params);
-
- cm.register_command("hook", add_hook, add_hook_desc, add_hook_params, CommandFlags::None,
- [](const Context& context, CompletionFlags flags,
- CommandParameters params, size_t token_to_complete, ByteCount pos_in_token)
- {
- if (token_to_complete == 0)
- return Completions{ 0_byte, params[0].length(),
- complete_scope(params[0].substr(0_byte, pos_in_token)) };
- else if (token_to_complete == 3)
- {
- auto& cm = CommandManager::instance();
- return cm.complete(context, flags, params[3], pos_in_token);
- }
- return Completions{};
- });
- cm.register_command("rmhooks", rm_hooks, rm_hooks_desc, rm_hooks_params);
-
- cm.register_command("source", exec_commands_in_file, exec_commands_in_file_desc, exec_commands_in_file_params, CommandFlags::None, filename_completer);
-
- cm.register_command("exec", exec_string, exec_string_desc, context_wrap_params);
- cm.register_command("eval", eval_string, eval_string_desc, context_wrap_params);
- cm.register_command("menu", menu, menu_desc, menu_params);
- cm.register_command("info", info, info_desc, info_params);
- cm.register_command("try", try_catch, try_catch_desc, try_catch_params);
- cm.register_command("reg", set_register, set_register_desc, set_register_params);
-
- cm.register_command("def", define_command, define_command_desc, define_command_params);
- cm.register_command("decl", declare_option, declare_option_desc, declare_option_params);
-
- cm.register_command("echo", echo_message, echo_message_desc, echo_message_params);
- cm.register_command("debug", write_debug_message, write_debug_message_desc, write_debug_message_params);
-
- cm.register_command("set", set_option, set_option_desc, set_option_params, CommandFlags::None,
- [](const Context& context, CompletionFlags,
- CommandParameters params, size_t token_to_complete,
- ByteCount pos_in_token) -> Completions
- {
- if (token_to_complete == 0)
- return { 0_byte, params[0].length(),
- complete_scope(params[0].substr(0_byte, pos_in_token)) };
- else if (token_to_complete == 1)
- {
- OptionManager& options = get_options(params[0], context);
- return { 0_byte, params[1].length(),
- options.complete_option_name(params[1], pos_in_token) };
- }
- return Completions{};
- } );
-
- cm.register_commands({ "colalias", "ca" }, define_color_alias, define_color_alias_desc, define_color_alias_params);
- cm.register_commands({ "nameclient", "nc" }, set_client_name, set_client_name_desc, set_client_name_params);
-
- cm.register_command("cd", change_working_directory, change_working_directory_desc, change_working_directory_params, CommandFlags::None, filename_completer);
- cm.register_command("map", map_key, map_key_desc, map_key_params);
+ cm.register_command("nop", [](const ParametersParser&, Context&){}, "do nothing", {});
+
+ register_command(cm, edit_cmd);
+ register_command(cm, force_edit_cmd);
+ register_command(cm, write_cmd);
+ register_command(cm, writeall_cmd);
+ register_command(cm, quit_cmd);
+ register_command(cm, force_quit_cmd);
+ register_command(cm, write_quit_cmd);
+ register_command(cm, force_write_quit_cmd);
+ register_command(cm, buffer_cmd);
+ register_command(cm, delbuf_cmd);
+ register_command(cm, force_delbuf_cmd);
+ register_command(cm, namebuf_cmd);
+ register_command(cm, define_highlighter_cmd);
+ register_command(cm, add_highlighter_cmd);
+ register_command(cm, rm_highlighter_cmd);
+ register_command(cm, add_hook_cmd);
+ register_command(cm, rm_hook_cmd);
+ register_command(cm, define_command_cmd);
+ register_command(cm, echo_cmd);
+ register_command(cm, debug_cmd);
+ register_command(cm, source_cmd);
+ register_command(cm, set_option_cmd);
+ register_command(cm, declare_option_cmd);
+ register_command(cm, map_key_cmd);
+ register_command(cm, exec_string_cmd);
+ register_command(cm, eval_string_cmd);
+ register_command(cm, menu_cmd);
+ register_command(cm, info_cmd);
+ register_command(cm, try_catch_cmd);
+ register_command(cm, define_color_alias_cmd);
+ register_command(cm, set_client_name_cmd);
+ register_command(cm, set_register_cmd);
+ register_command(cm, change_working_directory_cmd);
}
}