diff --git a/src/commands.cc b/src/commands.cc index 38fd871a..6e3c63fb 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -546,7 +546,7 @@ const CommandDesc add_hook_cmd = { Regex regex(parser[2].begin(), parser[2].end()); String command = parser[3]; auto hook_func = [=](const String& param, Context& context) { - if (GlobalHooks::instance().are_user_hooks_disabled()) + if (context.are_user_hooks_disabled()) return; if (boost::regex_match(param.begin(), param.end(), regex)) @@ -1002,18 +1002,13 @@ struct DisableOption { template void context_wrap(const ParametersParser& parser, Context& context, Func func) { - const bool disable_hooks = parser.has_option("no-hooks"); - if (disable_hooks) - GlobalHooks::instance().disable_user_hooks(); - auto restore_hooks = on_scope_end([&](){ - if (disable_hooks) - GlobalHooks::instance().enable_user_hooks(); - }); - + // Disable these options to avoid costly code paths (and potential screen + // redraws) That are useful only in interactive contexts. DisableOption disable_autoinfo(context, "autoinfo"); DisableOption disable_autoshowcompl(context, "autoshowcompl"); DisableOption disable_incsearch(context, "incsearch"); + const bool disable_hooks = parser.has_option("no-hooks") or context.are_user_hooks_disabled(); ClientManager& cm = ClientManager::instance(); if (parser.has_option("buffer")) @@ -1023,6 +1018,9 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func) { Buffer& buffer = BufferManager::instance().get_buffer(name); InputHandler input_handler{{ buffer, Selection{} }}; + // Propagate user hooks disabled status to the temporary context + if (disable_hooks) + input_handler.context().disable_user_hooks(); func(parser, input_handler.context()); } return; @@ -1047,6 +1045,10 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func) if (real_context->is_editing()) input_handler.context().disable_undo_handling(); + // Propagate user hooks disabled status to the temporary context + if (disable_hooks) + input_handler.context().disable_user_hooks(); + if (parser.has_option("itersel")) { SelectionList sels{real_context->selections()}; @@ -1069,6 +1071,14 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func) { if (parser.has_option("itersel")) throw runtime_error("-itersel makes no sense without -draft"); + + if (disable_hooks) + real_context->disable_user_hooks(); + auto restore_hooks = on_scope_end([&](){ + if (disable_hooks) + real_context->enable_user_hooks(); + }); + func(parser, *real_context); } diff --git a/src/context.hh b/src/context.hh index a02f11fd..60b49abb 100644 --- a/src/context.hh +++ b/src/context.hh @@ -75,6 +75,12 @@ public: bool is_editing() const { return m_edition_level!= 0; } void disable_undo_handling() { m_edition_level = -1; } + + bool are_user_hooks_disabled() const { return m_user_hooks_disabled; } + + void disable_user_hooks() { ++m_user_hooks_disabled; } + void enable_user_hooks() { --m_user_hooks_disabled; } + private: void begin_edition(); void end_edition(); @@ -94,6 +100,8 @@ private: using JumpList = std::vector; JumpList m_jump_list; JumpList::iterator m_current_jump = m_jump_list.begin(); + + int m_user_hooks_disabled = 0; }; struct ScopedEdition diff --git a/src/hook_manager.cc b/src/hook_manager.cc index ae0d10ba..7efafbbd 100644 --- a/src/hook_manager.cc +++ b/src/hook_manager.cc @@ -59,11 +59,4 @@ void HookManager::run_hook(const String& hook_name, } } -bool GlobalHooks::are_user_hooks_disabled() const -{ - kak_assert(m_disabled >= 0); - return m_disabled > 0; -} - - } diff --git a/src/hook_manager.hh b/src/hook_manager.hh index 4008e871..e5c94850 100644 --- a/src/hook_manager.hh +++ b/src/hook_manager.hh @@ -36,13 +36,6 @@ private: class GlobalHooks : public HookManager, public Singleton { -public: - bool are_user_hooks_disabled() const; - - void disable_user_hooks() { ++m_disabled; } - void enable_user_hooks() { --m_disabled; } -private: - int m_disabled = 0; }; } diff --git a/src/input_handler.cc b/src/input_handler.cc index 5ee5f8cb..a17ef281 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -86,12 +86,14 @@ public: auto restore_hooks = on_scope_end([&, this]{ if (do_restore_hooks) { - GlobalHooks::instance().enable_user_hooks(); + context().enable_user_hooks(); m_disable_hooks = false; } }); - context().print_status({}); // clear status line + context().print_status({}); + if (context().has_ui()) + context().ui().info_hide(); if (key.modifiers == Key::Modifiers::None and isdigit(key.key)) m_count = m_count * 10 + key.key - '0'; @@ -103,7 +105,7 @@ public: { if (m_disable_hooks) { - GlobalHooks::instance().disable_user_hooks(); + context().disable_user_hooks(); do_restore_hooks = true; } auto it = keymap.find(key); @@ -663,8 +665,13 @@ public: [this](Timer& timer) { context().hooks().run_hook("InsertIdle", "", context()); m_completer.update(); - }} + }}, + m_disable_hooks{context().are_user_hooks_disabled()} { + // Prolongate hook disabling for the whole insert session + if (m_disable_hooks) + context().disable_user_hooks(); + last_insert().first = mode; last_insert().second.clear(); context().hooks().run_hook("InsertBegin", "", context()); @@ -886,6 +893,9 @@ private: sel.cursor() = context().buffer().char_prev(sel.cursor()); } selections.avoid_eol(); + + if (m_disable_hooks) + context().enable_user_hooks(); } enum class Mode { Default, Complete, InsertReg }; @@ -894,6 +904,7 @@ private: ScopedEdition m_edition; InsertCompleter m_completer; Timer m_idle_timer; + bool m_disable_hooks; }; }