Disable hooks on a per context basis, and propagate that to Insert mode

using \ before entering insert mode will disable hooks during the whole
insert session rather than only the entering phase. That gives a nice
way of pasting text into kakoune.
This commit is contained in:
Maxime Coste 2014-07-24 19:18:39 +01:00
parent 826bf22eef
commit 731277a425
5 changed files with 42 additions and 27 deletions

View File

@ -546,7 +546,7 @@ const CommandDesc add_hook_cmd = {
Regex regex(parser[2].begin(), parser[2].end()); Regex regex(parser[2].begin(), parser[2].end());
String command = parser[3]; String command = parser[3];
auto hook_func = [=](const String& param, Context& context) { auto hook_func = [=](const String& param, Context& context) {
if (GlobalHooks::instance().are_user_hooks_disabled()) if (context.are_user_hooks_disabled())
return; return;
if (boost::regex_match(param.begin(), param.end(), regex)) if (boost::regex_match(param.begin(), param.end(), regex))
@ -1002,18 +1002,13 @@ struct DisableOption {
template<typename Func> template<typename Func>
void context_wrap(const ParametersParser& parser, Context& context, Func func) void context_wrap(const ParametersParser& parser, Context& context, Func func)
{ {
const bool disable_hooks = parser.has_option("no-hooks"); // Disable these options to avoid costly code paths (and potential screen
if (disable_hooks) // redraws) That are useful only in interactive contexts.
GlobalHooks::instance().disable_user_hooks();
auto restore_hooks = on_scope_end([&](){
if (disable_hooks)
GlobalHooks::instance().enable_user_hooks();
});
DisableOption<int> disable_autoinfo(context, "autoinfo"); DisableOption<int> disable_autoinfo(context, "autoinfo");
DisableOption<bool> disable_autoshowcompl(context, "autoshowcompl"); DisableOption<bool> disable_autoshowcompl(context, "autoshowcompl");
DisableOption<bool> disable_incsearch(context, "incsearch"); DisableOption<bool> disable_incsearch(context, "incsearch");
const bool disable_hooks = parser.has_option("no-hooks") or context.are_user_hooks_disabled();
ClientManager& cm = ClientManager::instance(); ClientManager& cm = ClientManager::instance();
if (parser.has_option("buffer")) 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); Buffer& buffer = BufferManager::instance().get_buffer(name);
InputHandler input_handler{{ buffer, Selection{} }}; 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()); func(parser, input_handler.context());
} }
return; return;
@ -1047,6 +1045,10 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func)
if (real_context->is_editing()) if (real_context->is_editing())
input_handler.context().disable_undo_handling(); 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")) if (parser.has_option("itersel"))
{ {
SelectionList sels{real_context->selections()}; SelectionList sels{real_context->selections()};
@ -1069,6 +1071,14 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func)
{ {
if (parser.has_option("itersel")) if (parser.has_option("itersel"))
throw runtime_error("-itersel makes no sense without -draft"); 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); func(parser, *real_context);
} }

View File

@ -75,6 +75,12 @@ public:
bool is_editing() const { return m_edition_level!= 0; } bool is_editing() const { return m_edition_level!= 0; }
void disable_undo_handling() { m_edition_level = -1; } 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: private:
void begin_edition(); void begin_edition();
void end_edition(); void end_edition();
@ -94,6 +100,8 @@ private:
using JumpList = std::vector<SelectionList>; using JumpList = std::vector<SelectionList>;
JumpList m_jump_list; JumpList m_jump_list;
JumpList::iterator m_current_jump = m_jump_list.begin(); JumpList::iterator m_current_jump = m_jump_list.begin();
int m_user_hooks_disabled = 0;
}; };
struct ScopedEdition struct ScopedEdition

View File

@ -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;
}
} }

View File

@ -36,13 +36,6 @@ private:
class GlobalHooks : public HookManager, class GlobalHooks : public HookManager,
public Singleton<GlobalHooks> public Singleton<GlobalHooks>
{ {
public:
bool are_user_hooks_disabled() const;
void disable_user_hooks() { ++m_disabled; }
void enable_user_hooks() { --m_disabled; }
private:
int m_disabled = 0;
}; };
} }

View File

@ -86,12 +86,14 @@ public:
auto restore_hooks = on_scope_end([&, this]{ auto restore_hooks = on_scope_end([&, this]{
if (do_restore_hooks) if (do_restore_hooks)
{ {
GlobalHooks::instance().enable_user_hooks(); context().enable_user_hooks();
m_disable_hooks = false; 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)) if (key.modifiers == Key::Modifiers::None and isdigit(key.key))
m_count = m_count * 10 + key.key - '0'; m_count = m_count * 10 + key.key - '0';
@ -103,7 +105,7 @@ public:
{ {
if (m_disable_hooks) if (m_disable_hooks)
{ {
GlobalHooks::instance().disable_user_hooks(); context().disable_user_hooks();
do_restore_hooks = true; do_restore_hooks = true;
} }
auto it = keymap.find(key); auto it = keymap.find(key);
@ -663,8 +665,13 @@ public:
[this](Timer& timer) { [this](Timer& timer) {
context().hooks().run_hook("InsertIdle", "", context()); context().hooks().run_hook("InsertIdle", "", context());
m_completer.update(); 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().first = mode;
last_insert().second.clear(); last_insert().second.clear();
context().hooks().run_hook("InsertBegin", "", context()); context().hooks().run_hook("InsertBegin", "", context());
@ -886,6 +893,9 @@ private:
sel.cursor() = context().buffer().char_prev(sel.cursor()); sel.cursor() = context().buffer().char_prev(sel.cursor());
} }
selections.avoid_eol(); selections.avoid_eol();
if (m_disable_hooks)
context().enable_user_hooks();
} }
enum class Mode { Default, Complete, InsertReg }; enum class Mode { Default, Complete, InsertReg };
@ -894,6 +904,7 @@ private:
ScopedEdition m_edition; ScopedEdition m_edition;
InsertCompleter m_completer; InsertCompleter m_completer;
Timer m_idle_timer; Timer m_idle_timer;
bool m_disable_hooks;
}; };
} }