summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2013-04-11 14:29:10 +0200
committerMaxime Coste <frrrwww@gmail.com>2013-04-11 14:29:10 +0200
commit107e95622d910309ab2c324583f216cee9fd926b (patch)
tree80a49e1097a0d14943b4f57a31f3bd9db7cb4274 /src
parent172f46f6795497215bfac72c1d17c3db64179d82 (diff)
Hooks can have an (shareable) identifier, and thus be removed
Diffstat (limited to 'src')
-rw-r--r--src/commands.cc39
-rw-r--r--src/hook_manager.cc18
-rw-r--r--src/hook_manager.hh6
3 files changed, 41 insertions, 22 deletions
diff --git a/src/commands.cc b/src/commands.cc
index 02f816f4..68f7bdfd 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -73,7 +73,7 @@ Buffer* open_fifo(const String& name , const String& filename, Context& context)
}
});
- buffer->hooks().add_hook("BufClose",
+ buffer->hooks().add_hook("BufClose", "",
[buffer, watcher](const String&, const Context&) {
// Check if fifo is still alive, else watcher is already dead
if (buffer->flags() & Buffer::Flags::Fifo)
@@ -313,30 +313,36 @@ void rm_filter(const CommandParameters& params, Context& context)
group.remove(parser[0]);
}
-void add_hook(const CommandParameters& params, Context& context)
+static HookManager& get_hook_manager(const String& scope, Context& context)
{
- if (params.size() != 4)
- throw wrong_argument_count();
+ if (scope == "global")
+ return GlobalHooks::instance();
+ else if (scope == "buffer")
+ return context.buffer().hooks();
+ else if (scope == "window")
+ return context.window().hooks();
+ throw runtime_error("error: no such hook container " + scope);
+}
+void add_hook(const CommandParameters& params, Context& context)
+{
+ ParametersParser parser(params, { { "id", true } }, ParametersParser::Flags::None, 4, 4);
// copy so that the lambda gets a copy as well
- Regex regex(params[2].begin(), params[2].end());
- String command = params[3];
+ Regex regex(parser[2].begin(), parser[2].end());
+ String command = parser[3];
auto hook_func = [=](const String& param, Context& context) {
if (boost::regex_match(param.begin(), param.end(), regex))
CommandManager::instance().execute(command, context, {},
{ { "hook_param", param } });
};
+ String id = parser.has_option("id") ? parser.option_value("id") : "";
+ get_hook_manager(parser[0], context).add_hook(parser[1], id, hook_func);
+}
- const String& scope = params[0];
- const String& name = params[1];
- if (scope == "global")
- GlobalHooks::instance().add_hook(name, hook_func);
- else if (scope == "buffer")
- context.buffer().hooks().add_hook(name, hook_func);
- else if (scope == "window")
- context.window().hooks().add_hook(name , hook_func);
- else
- throw runtime_error("error: no such hook container " + scope);
+void rm_hooks(const CommandParameters& params, Context& context)
+{
+ ParametersParser parser(params, {}, ParametersParser::Flags::None, 2, 2);
+ get_hook_manager(parser[0], context).remove_hooks(parser[1]);
}
EnvVarMap params_to_env_var_map(const CommandParameters& params)
@@ -895,6 +901,7 @@ void register_commands()
cm.register_commands({ "rf", "rmfilter" }, rm_filter, group_rm_completer(get_filters));
cm.register_command("hook", add_hook);
+ cm.register_command("rmhooks", rm_hooks);
cm.register_command("source", exec_commands_in_file, filename_completer);
diff --git a/src/hook_manager.cc b/src/hook_manager.cc
index 5eae3fc9..344b6ce0 100644
--- a/src/hook_manager.cc
+++ b/src/hook_manager.cc
@@ -5,9 +5,18 @@
namespace Kakoune
{
-void HookManager::add_hook(const String& hook_name, HookFunc hook)
+void HookManager::add_hook(const String& hook_name, String id, HookFunc hook)
{
- m_hook[hook_name].push_back(hook);
+ auto& hooks = m_hook[hook_name];
+ hooks.append({std::move(id), std::move(hook)});
+}
+
+void HookManager::remove_hooks(const String& id)
+{
+ if (id.empty())
+ throw runtime_error("invalid id");
+ for (auto& hooks : m_hook)
+ hooks.second.remove_all(id);
}
void HookManager::run_hook(const String& hook_name,
@@ -25,11 +34,12 @@ void HookManager::run_hook(const String& hook_name,
{
try
{
- hook(param, context);
+ hook.second(param, context);
}
catch (runtime_error& err)
{
- write_debug("error running hook " + hook_name + ": " + err.what());
+ write_debug("error running hook " + hook_name + "/" +
+ hook.first + ": " + err.what());
}
}
}
diff --git a/src/hook_manager.hh b/src/hook_manager.hh
index 3fcc0b74..c5b0e152 100644
--- a/src/hook_manager.hh
+++ b/src/hook_manager.hh
@@ -1,6 +1,7 @@
#ifndef hook_manager_hh_INCLUDED
#define hook_manager_hh_INCLUDED
+#include "idvaluemap.hh"
#include "utils.hh"
#include <unordered_map>
@@ -16,7 +17,8 @@ class HookManager
public:
HookManager(HookManager& parent) : m_parent(&parent) {}
- void add_hook(const String& hook_name, HookFunc hook);
+ void add_hook(const String& hook_name, String id, HookFunc hook);
+ void remove_hooks(const String& id);
void run_hook(const String& hook_name, const String& param,
Context& context) const;
@@ -27,7 +29,7 @@ private:
friend class GlobalHooks;
HookManager* m_parent;
- std::unordered_map<String, std::vector<HookFunc>> m_hook;
+ std::unordered_map<String, idvaluemap<String, HookFunc>> m_hook;
};
class GlobalHooks : public HookManager,