summaryrefslogtreecommitdiff
path: root/src/hook_manager.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-06-07 12:33:39 +0100
committerMaxime Coste <mawww@kakoune.org>2017-06-07 12:33:39 +0100
commitf0285a8e60de3ca27e02e0709646ef7c1302368f (patch)
treec464d3ccdd62badeb23a681ec4cdd062c7a480d4 /src/hook_manager.cc
parent4606453fedafefc42392c7c78428d8c649319741 (diff)
Move hook executing logic into HookManager
The existing HookManager was able to run arbitrary hook functions, but in practice was only used for user provided textual hooks. That separation was causing some suboptimal performances, by moving that logic directly in the hook manager we can improve hook filtering performance which is a big part of startup time when opening lots of files.
Diffstat (limited to 'src/hook_manager.cc')
-rw-r--r--src/hook_manager.cc21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/hook_manager.cc b/src/hook_manager.cc
index 9a412373..52da2d28 100644
--- a/src/hook_manager.cc
+++ b/src/hook_manager.cc
@@ -6,16 +6,17 @@
#include "buffer_utils.hh"
#include "display_buffer.hh"
#include "face_registry.hh"
+#include "command_manager.hh"
#include "regex.hh"
#include "option.hh"
namespace Kakoune
{
-void HookManager::add_hook(StringView hook_name, String group, HookFunc func)
+void HookManager::add_hook(StringView hook_name, String group, Regex filter, String commands)
{
auto& hooks = m_hooks[hook_name];
- hooks.emplace_back(new Hook{std::move(group), std::move(func)});
+ hooks.emplace_back(new Hook{std::move(group), std::move(filter), {}, std::move(commands)});
}
void HookManager::remove_hooks(StringView group)
@@ -84,8 +85,9 @@ void HookManager::run_hook(StringView hook_name,
Vector<Hook*> hooks_to_run; // The m_hooks_trash vector ensure hooks wont die during this method
for (auto& hook : hook_list->value)
{
- if (hook->group.empty() or disabled_hooks.empty() or
- not regex_match(hook->group.begin(), hook->group.end(), disabled_hooks))
+ if ((hook->group.empty() or disabled_hooks.empty() or
+ not regex_match(hook->group.begin(), hook->group.end(), disabled_hooks))
+ and regex_match(param.begin(), param.end(), hook->captures, hook->filter))
hooks_to_run.push_back(hook.get());
}
@@ -96,7 +98,16 @@ void HookManager::run_hook(StringView hook_name,
{
if (debug_flags & DebugFlags::Hooks)
write_to_debug_buffer(format("hook {}({})/{}", hook_name, param, hook->group));
- hook->func(param, context);
+
+ ScopedSetBool disable_history{context.history_disabled()};
+
+ EnvVarMap env_vars{ {"hook_param", param.str()} };
+ for (size_t i = 0; i < hook->captures.size(); ++i)
+ env_vars.insert({format("hook_param_capture_{}", i),
+ {hook->captures[i].first, hook->captures[i].second}});
+
+ CommandManager::instance().execute(hook->commands, context,
+ { {}, std::move(env_vars) });
}
catch (runtime_error& err)
{