diff --git a/src/buffer.cc b/src/buffer.cc index 7f3f8000..a1f943e8 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -4,7 +4,6 @@ #include "window.hh" #include "assert.hh" #include "utils.hh" -#include "hook_manager.hh" #include "context.hh" #include @@ -27,6 +26,7 @@ Buffer::Buffer(const String& name, Type type, : m_name(name), m_type(type), m_history(1), m_history_cursor(m_history.begin()), m_last_save_undo_index(0), + m_hook_manager(GlobalHookManager::instance()), m_option_manager(GlobalOptionManager::instance()) { BufferManager::instance().register_buffer(this); @@ -34,9 +34,9 @@ Buffer::Buffer(const String& name, Type type, apply_modification(Modification::make_insert(begin(), initial_content)); if (type == Type::NewFile) - GlobalHookManager::instance().run_hook("BufCreate", name, Context(*this)); + m_hook_manager.run_hook("BufCreate", name, Context(*this)); else if (type == Type::File) - GlobalHookManager::instance().run_hook("BufOpen", name, Context(*this)); + m_hook_manager.run_hook("BufOpen", name, Context(*this)); } Buffer::~Buffer() diff --git a/src/buffer.hh b/src/buffer.hh index 950b53b8..cd86737f 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -7,6 +7,7 @@ #include "line_and_column.hh" #include "option_manager.hh" +#include "hook_manager.hh" #include "string.hh" namespace Kakoune @@ -168,6 +169,7 @@ public: const String& line_content(size_t l) const { return m_lines[l].content; } OptionManager& option_manager() { return m_option_manager; } + HookManager& hook_manager() { return m_hook_manager; } private: friend class BufferIterator; @@ -208,6 +210,7 @@ private: std::vector m_iterators_to_update; OptionManager m_option_manager; + HookManager m_hook_manager; }; inline Modification Modification::make_erase(BufferIterator begin, diff --git a/src/hook_manager.cc b/src/hook_manager.cc index 846b922d..dff3506c 100644 --- a/src/hook_manager.cc +++ b/src/hook_manager.cc @@ -12,6 +12,9 @@ void HookManager::run_hook(const String& hook_name, const String& param, const Context& context) const { + if (m_parent) + m_parent->run_hook(hook_name, param, context); + auto hook_list_it = m_hook.find(hook_name); if (hook_list_it == m_hook.end()) return; diff --git a/src/hook_manager.hh b/src/hook_manager.hh index 21d087c7..96df0a8c 100644 --- a/src/hook_manager.hh +++ b/src/hook_manager.hh @@ -14,11 +14,19 @@ typedef std::function HookFunc; class HookManager { public: + HookManager(HookManager& parent) : m_parent(&parent) {} + void add_hook(const String& hook_name, HookFunc hook); void run_hook(const String& hook_name, const String& param, const Context& context) const; private: + HookManager() + : m_parent(nullptr) {} + // the only one allowed to construct a root hook manager + friend class GlobalHookManager; + + HookManager* m_parent; std::unordered_map> m_hook; }; diff --git a/src/window.cc b/src/window.cc index 310d58c8..ee7b0a75 100644 --- a/src/window.cc +++ b/src/window.cc @@ -15,12 +15,12 @@ Window::Window(Buffer& buffer) : Editor(buffer), m_position(0, 0), m_dimensions(0, 0), + m_hook_manager(buffer.hook_manager()), m_option_manager(buffer.option_manager()) { HighlighterRegistry& registry = HighlighterRegistry::instance(); - GlobalHookManager::instance().run_hook("WinCreate", buffer.name(), - Context(*this)); + m_hook_manager.run_hook("WinCreate", buffer.name(), Context(*this)); registry.add_highlighter_to_window(*this, "expand_tabs", HighlighterParameters()); registry.add_highlighter_to_window(*this, "highlight_selections", HighlighterParameters());