Disable history writing when running hooks

This commit is contained in:
Maxime Coste 2014-12-05 14:01:07 +00:00
parent 1c5975835e
commit d57be83522
3 changed files with 49 additions and 30 deletions

View File

@ -551,6 +551,9 @@ const CommandDesc add_hook_cmd = {
if (context.user_hooks_support().is_disabled()) if (context.user_hooks_support().is_disabled())
return; return;
// Do not let hooks touch prompt history
ScopedDisable disable_history{context.history_support()};
if (regex_match(param.begin(), param.end(), regex)) if (regex_match(param.begin(), param.end(), regex))
CommandManager::instance().execute(command, context, {}, CommandManager::instance().execute(command, context, {},
{ { "hook_param", param } }); { { "hook_param", param } });
@ -1028,12 +1031,13 @@ 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{} }};
Context& c = input_handler.context();
// Propagate user hooks disabled status to the temporary context // Propagate user hooks disabled status to the temporary context
if (disable_hooks) ScopedDisable hook_disable(c.user_hooks_support(), disable_hooks);
input_handler.context().user_hooks_support().disable(); ScopedDisable keymaps_disable(c.keymaps_support(), disable_keymaps);
if (disable_keymaps)
input_handler.context().keymaps_support().disable(); func(parser, c);
func(parser, input_handler.context());
} }
return; return;
} }
@ -1051,52 +1055,41 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func)
if (parser.has_option("draft")) if (parser.has_option("draft"))
{ {
InputHandler input_handler(real_context->selections(), real_context->name()); InputHandler input_handler(real_context->selections(), real_context->name());
Context& c = input_handler.context();
// We do not want this draft context to commit undo groups if the real one is // We do not want this draft context to commit undo groups if the real one is
// going to commit the whole thing later // going to commit the whole thing later
if (real_context->is_editing()) if (real_context->is_editing())
input_handler.context().disable_undo_handling(); c.disable_undo_handling();
// Propagate user hooks disabled status to the temporary context ScopedDisable hook_disable(c.user_hooks_support(), disable_hooks);
if (disable_hooks) ScopedDisable keymaps_disable(c.keymaps_support(), disable_keymaps);
input_handler.context().user_hooks_support().disable();
if (disable_keymaps)
input_handler.context().keymaps_support().disable();
if (parser.has_option("itersel")) if (parser.has_option("itersel"))
{ {
SelectionList sels{real_context->selections()}; SelectionList sels{real_context->selections()};
ScopedEdition edition{input_handler.context()}; ScopedEdition edition{c};
for (auto& sel : sels) for (auto& sel : sels)
{ {
input_handler.context().selections() = SelectionList{ sels.buffer(), sel, sels.timestamp() }; c.selections() = SelectionList{ sels.buffer(), sel, sels.timestamp() };
input_handler.context().selections().update(); c.selections().update();
func(parser, input_handler.context()); func(parser, c);
if (&sels.buffer() != &input_handler.context().buffer()) if (&sels.buffer() != &c.buffer())
throw runtime_error("the buffer has changed while iterating on selections"); throw runtime_error("the buffer has changed while iterating on selections");
} }
} }
else else
func(parser, input_handler.context()); func(parser, c);
} }
else else
{ {
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) ScopedDisable hook_disable(real_context->user_hooks_support(), disable_hooks);
real_context->user_hooks_support().disable(); ScopedDisable keymaps_disable(real_context->keymaps_support(), disable_keymaps);
if (disable_keymaps)
real_context->keymaps_support().disable();
auto restore = on_scope_end([&](){
if (disable_hooks)
real_context->user_hooks_support().enable();
if (disable_keymaps)
real_context->keymaps_support().enable();
});
func(parser, *real_context); func(parser, *real_context);
} }

View File

@ -27,6 +27,26 @@ private:
int m_disable_count = 0; int m_disable_count = 0;
}; };
struct ScopedDisable
{
ScopedDisable(Disableable& disableable, bool condition = true)
: m_disableable(disableable), m_condition(condition)
{
if (m_condition)
m_disableable.disable();
}
~ScopedDisable()
{
if (m_condition)
m_disableable.enable();
}
private:
Disableable& m_disableable;
bool m_condition;
};
// A Context is used to access non singleton objects for various services // A Context is used to access non singleton objects for various services
// in commands. // in commands.
// //
@ -97,6 +117,9 @@ public:
Disableable& keymaps_support() { return m_keymaps_support; } Disableable& keymaps_support() { return m_keymaps_support; }
const Disableable& keymaps_support() const { return m_keymaps_support; } const Disableable& keymaps_support() const { return m_keymaps_support; }
Disableable& history_support() { return m_history_support; }
const Disableable& history_support() const { return m_history_support; }
private: private:
void begin_edition(); void begin_edition();
void end_edition(); void end_edition();
@ -119,6 +142,7 @@ private:
Disableable m_user_hooks_support; Disableable m_user_hooks_support;
Disableable m_keymaps_support; Disableable m_keymaps_support;
Disableable m_history_support;
}; };
struct ScopedEdition struct ScopedEdition

View File

@ -516,7 +516,8 @@ public:
} }
else if (key == ctrl('m')) // enter else if (key == ctrl('m')) // enter
{ {
history_push(history, line); if (context().history_support().is_enabled())
history_push(history, line);
context().print_status(DisplayLine{}); context().print_status(DisplayLine{});
if (context().has_ui()) if (context().has_ui())
context().ui().menu_hide(); context().ui().menu_hide();
@ -528,7 +529,8 @@ public:
} }
else if (key == Key::Escape or key == ctrl('c')) else if (key == Key::Escape or key == ctrl('c'))
{ {
history_push(history, line); if (context().history_support().is_enabled())
history_push(history, line);
context().print_status(DisplayLine{}); context().print_status(DisplayLine{});
if (context().has_ui()) if (context().has_ui())
context().ui().menu_hide(); context().ui().menu_hide();