Hooks can have an (shareable) identifier, and thus be removed
This commit is contained in:
parent
172f46f679
commit
107e95622d
|
@ -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&) {
|
[buffer, watcher](const String&, const Context&) {
|
||||||
// Check if fifo is still alive, else watcher is already dead
|
// Check if fifo is still alive, else watcher is already dead
|
||||||
if (buffer->flags() & Buffer::Flags::Fifo)
|
if (buffer->flags() & Buffer::Flags::Fifo)
|
||||||
|
@ -313,30 +313,36 @@ void rm_filter(const CommandParameters& params, Context& context)
|
||||||
group.remove(parser[0]);
|
group.remove(parser[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HookManager& get_hook_manager(const String& scope, Context& context)
|
||||||
|
{
|
||||||
|
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)
|
void add_hook(const CommandParameters& params, Context& context)
|
||||||
{
|
{
|
||||||
if (params.size() != 4)
|
ParametersParser parser(params, { { "id", true } }, ParametersParser::Flags::None, 4, 4);
|
||||||
throw wrong_argument_count();
|
|
||||||
|
|
||||||
// copy so that the lambda gets a copy as well
|
// copy so that the lambda gets a copy as well
|
||||||
Regex regex(params[2].begin(), params[2].end());
|
Regex regex(parser[2].begin(), parser[2].end());
|
||||||
String command = params[3];
|
String command = parser[3];
|
||||||
auto hook_func = [=](const String& param, Context& context) {
|
auto hook_func = [=](const String& param, Context& context) {
|
||||||
if (boost::regex_match(param.begin(), param.end(), regex))
|
if (boost::regex_match(param.begin(), param.end(), regex))
|
||||||
CommandManager::instance().execute(command, context, {},
|
CommandManager::instance().execute(command, context, {},
|
||||||
{ { "hook_param", param } });
|
{ { "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];
|
void rm_hooks(const CommandParameters& params, Context& context)
|
||||||
const String& name = params[1];
|
{
|
||||||
if (scope == "global")
|
ParametersParser parser(params, {}, ParametersParser::Flags::None, 2, 2);
|
||||||
GlobalHooks::instance().add_hook(name, hook_func);
|
get_hook_manager(parser[0], context).remove_hooks(parser[1]);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EnvVarMap params_to_env_var_map(const CommandParameters& params)
|
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_commands({ "rf", "rmfilter" }, rm_filter, group_rm_completer(get_filters));
|
||||||
|
|
||||||
cm.register_command("hook", add_hook);
|
cm.register_command("hook", add_hook);
|
||||||
|
cm.register_command("rmhooks", rm_hooks);
|
||||||
|
|
||||||
cm.register_command("source", exec_commands_in_file, filename_completer);
|
cm.register_command("source", exec_commands_in_file, filename_completer);
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,18 @@
|
||||||
namespace Kakoune
|
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,
|
void HookManager::run_hook(const String& hook_name,
|
||||||
|
@ -25,11 +34,12 @@ void HookManager::run_hook(const String& hook_name,
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
hook(param, context);
|
hook.second(param, context);
|
||||||
}
|
}
|
||||||
catch (runtime_error& err)
|
catch (runtime_error& err)
|
||||||
{
|
{
|
||||||
write_debug("error running hook " + hook_name + ": " + err.what());
|
write_debug("error running hook " + hook_name + "/" +
|
||||||
|
hook.first + ": " + err.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef hook_manager_hh_INCLUDED
|
#ifndef hook_manager_hh_INCLUDED
|
||||||
#define hook_manager_hh_INCLUDED
|
#define hook_manager_hh_INCLUDED
|
||||||
|
|
||||||
|
#include "idvaluemap.hh"
|
||||||
#include "utils.hh"
|
#include "utils.hh"
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -16,7 +17,8 @@ class HookManager
|
||||||
public:
|
public:
|
||||||
HookManager(HookManager& parent) : m_parent(&parent) {}
|
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,
|
void run_hook(const String& hook_name, const String& param,
|
||||||
Context& context) const;
|
Context& context) const;
|
||||||
|
|
||||||
|
@ -27,7 +29,7 @@ private:
|
||||||
friend class GlobalHooks;
|
friend class GlobalHooks;
|
||||||
|
|
||||||
HookManager* m_parent;
|
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,
|
class GlobalHooks : public HookManager,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user