diff --git a/doc/pages/commands.asciidoc b/doc/pages/commands.asciidoc index 73930999..0e4f779b 100644 --- a/doc/pages/commands.asciidoc +++ b/doc/pages/commands.asciidoc @@ -129,10 +129,10 @@ command *q!* has to be used). Aliases are mentionned below each commands. *unmap* []:: unbind a key combination (See <>) -*declare-user-mode* :: - declare a new user keymap mode within the context of a scope +*declare-user-mode* :: + declare a new user keymap mode -*enter-user-mode* :: +*enter-user-mode* :: enable keymap mode for next key *-lock*::: diff --git a/doc/pages/expansions.asciidoc b/doc/pages/expansions.asciidoc index f97cb472..40daef7e 100644 --- a/doc/pages/expansions.asciidoc +++ b/doc/pages/expansions.asciidoc @@ -126,6 +126,8 @@ informations about Kakoune's state: *kak_client_env_*:: value of the *name* variable in the client environment (e.g. *$kak_client_env_SHELL* is the SHELL variable) +*kak_user_modes*:: + the user modes list, each modes separated by a colon Note that in order for Kakoune to pass a value in the environment, the variable has to be spelled out within the body of the expansion. diff --git a/doc/pages/modes.asciidoc b/doc/pages/modes.asciidoc index aedd532d..9181e619 100644 --- a/doc/pages/modes.asciidoc +++ b/doc/pages/modes.asciidoc @@ -102,7 +102,7 @@ mostly useful for plugin authors who want to bind their new commands in extensible menus. -------------------------------- -declare-user-mode +declare-user-mode -------------------------------- Declare a new custom mode that can later be referred by the *map* command. @@ -110,7 +110,7 @@ For example a `grep` custom mode to attach keys like `n` or `p` to skim through the output results. ------------------------------- -enter-user-mode +enter-user-mode ------------------------------- Enable the designated mode for the next key. Docstrings are shown in the diff --git a/src/commands.cc b/src/commands.cc index 818002d4..35f6a593 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -1192,10 +1192,11 @@ const CommandDesc debug_cmd = { auto& keymaps = context.keymaps(); auto modes = {"normal", "insert", "prompt", "menu", "goto", "view", "user", "object"}; + auto user_modes = keymaps.user_modes(); write_to_debug_buffer("Mappings:"); - for (auto& mode : modes) + for (auto& mode : concatenated(modes, user_modes) | gather>()) { - KeymapMode m = parse_keymap_mode(mode, keymaps.user_modes()); + KeymapMode m = parse_keymap_mode(mode, user_modes); for (auto& key : keymaps.get_mapped_keys(m)) write_to_debug_buffer(format(" * {} {}: {}", mode, key_to_str(key), @@ -2123,15 +2124,14 @@ const CommandDesc fail_cmd = { const CommandDesc declare_user_mode_cmd = { "declare-user-mode", nullptr, - "declare-user-mode : add a new user keymap mode in given ", - ParameterDesc{ {}, ParameterDesc::Flags::None, 2, 2 }, + "declare-user-mode : add a new user keymap mode", + single_param, CommandFlags::None, CommandHelper{}, - make_completer(complete_scope), + CommandCompleter{}, [](const ParametersParser& parser, Context& context, const ShellContext&) { - KeymapManager& keymaps = get_scope(parser[0], context).keymaps(); - keymaps.add_user_mode(std::move(parser[1])); + context.keymaps().add_user_mode(std::move(parser[0])); } }; @@ -2162,10 +2162,10 @@ void enter_user_mode(Context& context, const String mode_name, KeymapMode mode, const CommandDesc enter_user_mode_cmd = { "enter-user-mode", nullptr, - "enter-user-mode : enable keymap mode for next key", + "enter-user-mode : enable keymap mode for next key", ParameterDesc{ { { "lock", { false, "stay in mode until is pressed" } } }, - ParameterDesc::Flags::SwitchesOnlyAtStart, 2, 2 + ParameterDesc::Flags::SwitchesOnlyAtStart, 1, 1 }, CommandFlags::None, CommandHelper{}, @@ -2174,23 +2174,17 @@ const CommandDesc enter_user_mode_cmd = { ByteCount pos_in_token) -> Completions { if (token_to_complete == 0) - return { 0_byte, params[0].length(), - complete(params[0], pos_in_token, scopes) }; - if (token_to_complete == 1) { - KeymapManager& keymaps = get_scope(params[0], context).keymaps(); - return { 0_byte, params[1].length(), - complete(params[1], pos_in_token, keymaps.user_modes()) }; + return { 0_byte, params[0].length(), + complete(params[0], pos_in_token, context.keymaps().user_modes()) }; } return {}; }, [](const ParametersParser& parser, Context& context, const ShellContext&) { auto lock = (bool)parser.get_switch("lock"); - KeymapManager& keymaps = get_scope(parser[0], context).keymaps(); - KeymapMode mode = parse_keymap_mode(parser[1], keymaps.user_modes()); - - enter_user_mode(context, std::move(parser[1]), mode, lock); + KeymapMode mode = parse_keymap_mode(parser[0], context.keymaps().user_modes()); + enter_user_mode(context, std::move(parser[0]), mode, lock); } }; diff --git a/src/keymap_manager.cc b/src/keymap_manager.cc index 2b560706..658c7e42 100644 --- a/src/keymap_manager.cc +++ b/src/keymap_manager.cc @@ -54,16 +54,17 @@ KeymapManager::KeyList KeymapManager::get_mapped_keys(KeymapMode mode) const void KeymapManager::add_user_mode(String user_mode_name) { auto modes = {"normal", "insert", "prompt", "menu", "goto", "view", "user", "object"}; + if (contains(modes, user_mode_name)) throw runtime_error(format("'{}' is already a regular mode", user_mode_name)); - if (contains(m_user_modes, user_mode_name)) + if (contains(user_modes(), user_mode_name)) throw runtime_error(format("user mode '{}' already defined", user_mode_name)); if (contains_that(user_mode_name, [](char c){ return not isalnum(c); })) throw runtime_error(format("invalid mode name: '{}'", user_mode_name)); - m_user_modes.push_back(std::move(user_mode_name)); + user_modes().push_back(std::move(user_mode_name)); } } diff --git a/src/keymap_manager.hh b/src/keymap_manager.hh index 3c8d52ee..21a291e3 100644 --- a/src/keymap_manager.hh +++ b/src/keymap_manager.hh @@ -45,7 +45,11 @@ public: const KeymapInfo& get_mapping(Key key, KeymapMode mode) const; using UserModeList = Vector; - const UserModeList& user_modes() const { return m_user_modes; } + UserModeList& user_modes() { + if (m_parent) + return m_parent->user_modes(); + return m_user_modes; + } void add_user_mode(const String user_mode_name); private: diff --git a/src/main.cc b/src/main.cc index 8edfe82f..a3802a85 100644 --- a/src/main.cc +++ b/src/main.cc @@ -193,6 +193,10 @@ static const EnvVarDesc builtin_env_vars[] = { { "window_height", false, [](StringView name, const Context& context) -> String { return to_string(context.window().dimensions().line); } + }, { + "user_modes", false, + [](StringView name, const Context& context) -> String + { return join(context.keymaps().user_modes(), ':'); } } }; diff --git a/test/normal/user-modes/lock/rc b/test/normal/user-modes/lock/rc index b3114fef..d9b9a65a 100644 --- a/test/normal/user-modes/lock/rc +++ b/test/normal/user-modes/lock/rc @@ -1,3 +1,3 @@ -declare-user-mode global foo +declare-user-mode foo map global foo f d -map global normal ':enter-user-mode -lock global foo' +map global normal ':enter-user-mode -lock foo' diff --git a/test/normal/user-modes/once/rc b/test/normal/user-modes/once/rc index 102a6163..3c1790f8 100644 --- a/test/normal/user-modes/once/rc +++ b/test/normal/user-modes/once/rc @@ -1,3 +1,3 @@ -declare-user-mode global foo +declare-user-mode foo map global foo f 'wchello from foo' -map global normal ':enter-user-mode global foo' +map global normal ':enter-user-mode foo'