diff --git a/src/commands.cc b/src/commands.cc index 1075c332..446ecd29 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -1993,7 +1993,7 @@ void context_wrap(const ParametersParser& parser, Context& context, StringView d Context::Flags::Draft}; Context& c = input_handler.context(); - ScopedSetBool disable_history(c.history_disabled()); + ScopedSetBool noninteractive(c.noninteractive()); func(parser, c); }; @@ -2044,7 +2044,7 @@ void context_wrap(const ParametersParser& parser, Context& context, StringView d Context& c = *effective_context; - ScopedSetBool disable_history(c.history_disabled()); + ScopedSetBool noninteractive(c.noninteractive()); ScopedEdition edition{c}; ScopedSelectionEdition selection_edition{c}; @@ -2222,7 +2222,7 @@ const CommandDesc prompt_cmd = { sc.env_vars.erase("text"_sv); }); - ScopedSetBool disable_history{context.history_disabled()}; + ScopedSetBool noninteractive{context.noninteractive()}; StringView cmd; switch (event) @@ -2269,7 +2269,7 @@ const CommandDesc menu_cmd = { if (count == modulo and parser.get_switch("auto-single")) { - ScopedSetBool disable_history{context.history_disabled()}; + ScopedSetBool noninteractive{context.noninteractive()}; CommandManager::instance().execute(parser[1], context); return; @@ -2293,7 +2293,7 @@ const CommandDesc menu_cmd = { CapturedShellContext sc{shell_context}; context.input_handler().menu(std::move(choices), [=](int choice, MenuEvent event, Context& context) { - ScopedSetBool disable_history{context.history_disabled()}; + ScopedSetBool noninteractive{context.noninteractive()}; if (event == MenuEvent::Validate and choice >= 0 and choice < commands.size()) CommandManager::instance().execute(commands[choice], context, sc); @@ -2324,7 +2324,7 @@ 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 disable_history{context.history_disabled()}; + ScopedSetBool noninteractive{context.noninteractive()}; CommandManager::instance().execute(command, context, sc); }); @@ -2646,7 +2646,7 @@ void enter_user_mode(Context& context, String mode_name, KeymapMode mode, bool l return; ScopedSetBool disable_keymaps(context.keymaps_disabled()); - ScopedSetBool disable_history(context.history_disabled()); + ScopedSetBool noninteractive(context.noninteractive()); InputHandler::ScopedForceNormal force_normal{context.input_handler(), {}}; diff --git a/src/context.hh b/src/context.hh index 34bb9e12..69377148 100644 --- a/src/context.hh +++ b/src/context.hh @@ -126,8 +126,8 @@ public: NestedBool& keymaps_disabled() { return m_keymaps_disabled; } const NestedBool& keymaps_disabled() const { return m_keymaps_disabled; } - NestedBool& history_disabled() { return m_history_disabled; } - const NestedBool& history_disabled() const { return m_history_disabled; } + NestedBool& noninteractive() { return m_noninteractive; } + const NestedBool& noninteractive() const { return m_noninteractive; } Flags flags() const { return m_flags; } @@ -207,7 +207,7 @@ private: NestedBool m_hooks_disabled; NestedBool m_keymaps_disabled; - NestedBool m_history_disabled; + NestedBool m_noninteractive; }; struct ScopedEdition diff --git a/src/hook_manager.cc b/src/hook_manager.cc index 406b803f..afab5461 100644 --- a/src/hook_manager.cc +++ b/src/hook_manager.cc @@ -37,7 +37,7 @@ struct HookManager::HookData enum_desc(Meta::Type{})[to_underlying(hook)].name, param, group)); - ScopedSetBool disable_history{context.history_disabled()}; + ScopedSetBool noninteractive{context.noninteractive()}; EnvVarMap env_vars{ {"hook_param", param.str()} }; for (size_t i = 0; i < captures.size(); ++i) diff --git a/src/input_handler.cc b/src/input_handler.cc index 08bcdd51..bbf9e7ea 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -788,6 +788,7 @@ public: m_prompt(prompt.str()), m_prompt_face(face), m_empty_text{std::move(emptystr)}, m_line_editor{context().faces()}, 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::Prompt}, @@ -1063,6 +1064,16 @@ public: } } + bool was_interactive() + { + return m_was_interactive; + } + + void set_was_interactive() + { + m_was_interactive = true; + } + DisplayLine mode_line() const override { return { "prompt", context().faces()["StatusLineMode"] }; @@ -1190,6 +1201,7 @@ private: LineEditor m_line_editor; bool m_line_changed = false; PromptFlags m_flags; + bool m_was_interactive; Register& m_history; int m_current_history; bool m_auto_complete; @@ -1198,7 +1210,7 @@ private: void history_push(StringView entry) { - if (entry.empty() or context().history_disabled() or + if (entry.empty() or not was_interactive() or (m_flags & PromptFlags::DropHistoryEntriesWithBlankPrefix and is_horizontal_blank(entry[0_byte]))) return; @@ -1706,11 +1718,17 @@ void InputHandler::prompt(StringView prompt, String initstr, String emptystr, void InputHandler::set_prompt_face(Face prompt_face) { - InputModes::Prompt* prompt = dynamic_cast(¤t_mode()); + auto* prompt = dynamic_cast(¤t_mode()); if (prompt) prompt->set_prompt_face(prompt_face); } +bool InputHandler::history_enabled() const +{ + auto* prompt = dynamic_cast(¤t_mode()); + return prompt and prompt->was_interactive(); +} + void InputHandler::menu(Vector choices, MenuCallback callback) { push_mode(new InputModes::Menu(*this, std::move(choices), std::move(callback))); @@ -1761,7 +1779,13 @@ void InputHandler::handle_key(Key key) const bool was_recording = is_recording(); ++m_handle_key_level; - auto dec = on_scope_end([this]{ --m_handle_key_level; }); + auto dec = on_scope_end([this]{ + --m_handle_key_level; + if (m_handle_key_level == 0) + for (auto& mode : m_mode_stack) + if (auto* prompt = dynamic_cast(&*mode)) + prompt->set_was_interactive(); + }); auto process_key = [&](Key key) { if (m_last_insert.recording) @@ -1773,7 +1797,7 @@ void InputHandler::handle_key(Key key) KeymapManager& keymaps = m_context.keymaps(); if (keymaps.is_mapped(key, keymap_mode) and not m_context.keymaps_disabled()) { - ScopedSetBool disable_history{context().history_disabled()}; + ScopedSetBool noninteractive{context().noninteractive()}; for (auto& k : keymaps.get_mapping_keys(key, keymap_mode)) process_key(k); diff --git a/src/input_handler.hh b/src/input_handler.hh index b7e53aaf..4a776e84 100644 --- a/src/input_handler.hh +++ b/src/input_handler.hh @@ -83,6 +83,7 @@ public: Face prompt_face, PromptFlags flags, char history_register, PromptCompleter completer, PromptCallback callback); void set_prompt_face(Face prompt_face); + bool history_enabled() const; // enter menu mode, callback is called on each selection change, // abort or validation with corresponding MenuEvent value diff --git a/src/normal.cc b/src/normal.cc index 64b67e63..1c264216 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -1022,7 +1022,7 @@ void select_regex(Context& context, NormalParams params) RegisterManager::instance()[reg].restore(context, saved_reg); if (event == PromptEvent::Abort) return; - if (not context.history_disabled()) + if (context.input_handler().history_enabled()) RegisterManager::instance()[reg].set(context, ex.str()); auto& selections = context.selections(); @@ -1044,7 +1044,7 @@ void split_regex(Context& context, NormalParams params) RegisterManager::instance()[reg].restore(context, saved_reg); if (event == PromptEvent::Abort) return; - if (not context.history_disabled()) + if (context.input_handler().history_enabled()) RegisterManager::instance()[reg].set(context, ex.str()); auto& selections = context.selections(); @@ -1148,7 +1148,7 @@ void keep(Context& context, NormalParams params) RegisterManager::instance()[reg].restore(context, saved_reg); if (event == PromptEvent::Abort) return; - if (not context.history_disabled()) + if (context.input_handler().history_enabled()) RegisterManager::instance()[reg].set(context, regex.str()); if (regex.empty() or regex.str().empty()) @@ -2055,7 +2055,7 @@ void exec_user_mappings(Context& context, NormalParams params) return; ScopedSetBool disable_keymaps(context.keymaps_disabled()); - ScopedSetBool disable_history(context.history_disabled()); + ScopedSetBool noninteractive(context.noninteractive()); InputHandler::ScopedForceNormal force_normal{context.input_handler(), params};