diff options
| author | Johannes Altmanninger <aclopte@gmail.com> | 2025-03-23 16:16:25 +0100 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2025-03-24 08:28:55 +1100 |
| commit | b242a4e049cb94e304183472ab81b027d67c31d6 (patch) | |
| tree | 2fe1778f962473dace42d269d8d28cf982c23e03 /src | |
| parent | 6fa99d403c0d5884610fd23e59a2fc10ed258a9a (diff) | |
Fix prompt history recording when using mapped keys
Commit e3122ab2c (Refactor prompt history handling, 2023-07-05) was a nice
simplification but it breaks a rare edge case. It suppresses history
recording if all keys the prompt receives were synthesized. That's not
quite the right criteria:
it means that if prompt is created, edited and and executed, all via mapped
keys, we fail to add to history.
The criteria should rather be something like "if all keys the prompt receives
came from synthesized events".
Make it so. This allows us to get rid of the "noninteractive" nested bool
that was only used for disabling history.
Diffstat (limited to 'src')
| -rw-r--r-- | src/commands.cc | 11 | ||||
| -rw-r--r-- | src/context.hh | 4 | ||||
| -rw-r--r-- | src/hook_manager.cc | 2 | ||||
| -rw-r--r-- | src/input_handler.cc | 34 | ||||
| -rw-r--r-- | src/normal.cc | 1 |
5 files changed, 20 insertions, 32 deletions
diff --git a/src/commands.cc b/src/commands.cc index 6da92d67..114c1bdc 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -2085,11 +2085,7 @@ void context_wrap(const ParametersParser& parser, Context& context, StringView d auto context_wrap_for_buffer = [&](Buffer& buffer) { InputHandler input_handler{{ buffer, Selection{} }, Context::Flags::Draft}; - Context& c = input_handler.context(); - - ScopedSetBool noninteractive(c.noninteractive()); - - func(parser, c); + func(parser, input_handler.context()); }; if (*bufnames == "*") { @@ -2140,7 +2136,6 @@ void context_wrap(const ParametersParser& parser, Context& context, StringView d Context& c = *effective_context; - ScopedSetBool noninteractive(c.noninteractive()); ScopedEdition edition{c}; ScopedSelectionEdition selection_edition{c}; @@ -2320,8 +2315,6 @@ const CommandDesc prompt_cmd = { sc.env_vars.erase("text"_sv); }); - ScopedSetBool noninteractive{context.noninteractive()}; - StringView cmd; switch (event) { @@ -2363,7 +2356,6 @@ const CommandDesc on_key_cmd = { parser.get_switch("mode-name").value_or("on-key"), KeymapMode::None, [=](Key key, Context& context) mutable { sc.env_vars["key"_sv] = to_string(key); - ScopedSetBool noninteractive{context.noninteractive()}; CommandManager::instance().execute(command, context, sc); }); @@ -2690,7 +2682,6 @@ void enter_user_mode(Context& context, String mode_name, KeymapMode mode, bool l if (context.keymaps().is_mapped(key, mode)) { ScopedSetBool disable_keymaps(context.keymaps_disabled()); - ScopedSetBool noninteractive(context.noninteractive()); InputHandler::ScopedForceNormal force_normal{context.input_handler(), {}}; diff --git a/src/context.hh b/src/context.hh index ce17c3f7..7302c865 100644 --- a/src/context.hh +++ b/src/context.hh @@ -131,9 +131,6 @@ public: NestedBool& keymaps_disabled() { return m_keymaps_disabled; } const NestedBool& keymaps_disabled() const { return m_keymaps_disabled; } - NestedBool& noninteractive() { return m_noninteractive; } - const NestedBool& noninteractive() const { return m_noninteractive; } - Flags flags() const { return m_flags; } JumpList& jump_list() { return m_jump_list; } @@ -211,7 +208,6 @@ private: NestedBool m_hooks_disabled; NestedBool m_keymaps_disabled; - NestedBool m_noninteractive; }; struct ScopedEdition diff --git a/src/hook_manager.cc b/src/hook_manager.cc index ae3acf65..ee461a83 100644 --- a/src/hook_manager.cc +++ b/src/hook_manager.cc @@ -37,8 +37,6 @@ struct HookManager::HookData enum_desc(Meta::Type<Hook>{})[to_underlying(hook)].name, param, group)); - ScopedSetBool noninteractive{context.noninteractive()}; - EnvVarMap env_vars{ {"hook_param", param.str()} }; for (size_t i = 0; i < captures.size(); ++i) env_vars.insert({format("hook_param_capture_{}", i), diff --git a/src/input_handler.cc b/src/input_handler.cc index b6539ce2..d5f010c7 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -30,8 +30,9 @@ public: InputMode(const InputMode&) = delete; InputMode& operator=(const InputMode&) = delete; - void handle_key(Key key, bool synthesized) { RefPtr<InputMode> keep_alive{this}; on_key(key, synthesized); } + void handle_key(Key key) { RefPtr<InputMode> keep_alive{this}; on_key(key); } virtual void paste(StringView content); + virtual void on_raw_key() {} virtual void on_enabled(bool from_pop) {} virtual void on_disabled(bool from_push) {} @@ -57,7 +58,7 @@ public: using Insertion = InputHandler::Insertion; protected: - virtual void on_key(Key key, bool synthesized) = 0; + virtual void on_key(Key key) = 0; void push_mode(InputMode* new_mode) { m_input_handler.push_mode(new_mode); } void pop_mode() { m_input_handler.pop_mode(this); } @@ -279,7 +280,7 @@ public: } } - void on_key(Key key, bool) override + void on_key(Key key) override { bool should_clear = false; @@ -682,7 +683,6 @@ public: m_empty_text{std::move(emptystr)}, // This prompt may outlive local scopes so ignore local faces. m_line_editor{context().faces(false)}, m_flags(flags), - m_was_interactive{not context().noninteractive()}, m_history{RegisterManager::instance()[history_register]}, m_current_history{-1}, m_auto_complete{context().options()["autocomplete"].get<AutoComplete>() & AutoComplete::Prompt}, @@ -702,11 +702,9 @@ public: m_line_editor.reset(std::move(initstr), m_empty_text); } - void on_key(Key key, bool synthesized) override + void on_key(Key key) override { const String& line = m_line_editor.line(); - if (not synthesized) - m_was_interactive = true; auto can_auto_insert_completion = [&] { const bool has_completions = not m_completions.candidates.empty(); @@ -968,6 +966,10 @@ public: m_idle_timer.set_next_date(Clock::now() + get_idle_timeout(context())); } + void on_raw_key() override { + m_was_interactive = true; + } + void set_prompt_face(Face face) { if (face != m_prompt_face) @@ -1117,7 +1119,7 @@ private: LineEditor m_line_editor; bool m_line_changed = false; PromptFlags m_flags; - bool m_was_interactive; + bool m_was_interactive = false; Register& m_history; int m_current_history; bool m_auto_complete; @@ -1143,7 +1145,7 @@ public: : InputMode(input_handler), m_name{std::move(name)}, m_callback(std::move(callback)), m_keymap_mode(keymap_mode), m_idle_timer{Clock::now() + get_idle_timeout(context()), std::move(idle_callback)} {} - void on_key(Key key, bool) override + void on_key(Key key) override { // maintain hooks disabled in the callback if they were before pop_mode ScopedSetBool disable_hooks(context().hooks_disabled(), @@ -1229,7 +1231,7 @@ public: } } - void on_key(Key key, bool synthesized) override + void on_key(Key key) override { auto& buffer = context().buffer(); @@ -1682,21 +1684,23 @@ void InputHandler::handle_key(Key key, bool synthesized) ++m_handle_key_level; auto dec = on_scope_end([this]{ --m_handle_key_level;} ); - auto process_key = [this](Key k, bool synthesized) { + if (not synthesized) + current_mode().on_raw_key(); + + auto process_key = [this](Key k) { record_key(k); - current_mode().handle_key(k, synthesized); + current_mode().handle_key(k); }; const auto keymap_mode = current_mode().keymap_mode(); KeymapManager& keymaps = m_context.keymaps(); if (keymaps.is_mapped(key, keymap_mode) and not m_context.keymaps_disabled()) { - ScopedSetBool noninteractive{context().noninteractive()}; for (auto& k : keymaps.get_mapping_keys(key, keymap_mode)) - process_key(k, true); + process_key(k); } else - process_key(key, synthesized or m_handle_key_level > 1); + process_key(key); if (m_handle_key_level < m_recording_level) { diff --git a/src/normal.cc b/src/normal.cc index 6be1a857..8a8b958d 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -2078,7 +2078,6 @@ void exec_user_mappings(Context& context, NormalParams params) return; ScopedSetBool disable_keymaps(context.keymaps_disabled()); - ScopedSetBool noninteractive(context.noninteractive()); InputHandler::ScopedForceNormal force_normal{context.input_handler(), params}; |
