From 7fef7ec0633f91dd84c413472368f6be7b9a5dc9 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 16 Sep 2013 19:38:28 +0100 Subject: [PATCH] Add a InputMode::on_replaced virtual method. Destructors are not a good place to run mode exit hooks, as they wont be called until the next mode trash clearing, so we now call this virtual method on the previous mode just before it gets replaced. --- src/client.cc | 31 ++++++++++++++++--------------- src/client.hh | 2 ++ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/client.cc b/src/client.cc index 22f334a6..ca6f047c 100644 --- a/src/client.cc +++ b/src/client.cc @@ -26,6 +26,7 @@ public: InputMode& operator=(const InputMode&) = delete; virtual void on_key(Key key) = 0; + virtual void on_replaced() {} Context& context() const { return m_client.context(); } using Insertion = Client::Insertion; @@ -54,7 +55,7 @@ public: context().hooks().run_hook("NormalBegin", "", context()); } - ~Normal() + void on_replaced() override { context().hooks().run_hook("NormalEnd", "", context()); } @@ -908,12 +909,10 @@ private: InputMode& InputMode::reset_normal_mode() { - m_client.m_mode_trash.emplace_back(std::move(m_client.m_mode)); - m_client.m_mode.reset(new InputModes::Normal(m_client)); + m_client.change_input_mode(new InputModes::Normal(m_client)); return *m_client.m_mode; } - Client::Client(std::unique_ptr&& ui, Editor& editor, String name) : m_ui(std::move(ui)), m_context(*this, editor), m_mode(new InputModes::Normal(*this)), m_name(name) { @@ -923,10 +922,16 @@ Client::~Client() { } +void Client::change_input_mode(InputMode* new_mode) +{ + m_mode->on_replaced(); + m_mode_trash.emplace_back(std::move(m_mode)); + m_mode.reset(new_mode); +} + void Client::insert(InsertMode mode) { - m_mode_trash.emplace_back(std::move(m_mode)); - m_mode.reset(new InputModes::Insert(*this, mode)); + change_input_mode(new InputModes::Insert(*this, mode)); } void Client::repeat_last_insert() @@ -938,8 +943,7 @@ void Client::repeat_last_insert() swap(keys, m_last_insert.second); // context.last_insert will be refilled by the new Insert // this is very inefficient. - m_mode_trash.emplace_back(std::move(m_mode)); - m_mode.reset(new InputModes::Insert(*this, m_last_insert.first)); + change_input_mode(new InputModes::Insert(*this, m_last_insert.first)); for (auto& key : keys) m_mode->on_key(key); kak_assert(dynamic_cast(m_mode.get()) != nullptr); @@ -948,9 +952,8 @@ void Client::repeat_last_insert() void Client::prompt(const String& prompt, ColorPair prompt_colors, Completer completer, PromptCallback callback) { - m_mode_trash.emplace_back(std::move(m_mode)); - m_mode.reset(new InputModes::Prompt(*this, prompt, prompt_colors, - completer, callback)); + change_input_mode(new InputModes::Prompt(*this, prompt, prompt_colors, + completer, callback)); } void Client::set_prompt_colors(ColorPair prompt_colors) @@ -963,14 +966,12 @@ void Client::set_prompt_colors(ColorPair prompt_colors) void Client::menu(memoryview choices, MenuCallback callback) { - m_mode_trash.emplace_back(std::move(m_mode)); - m_mode.reset(new InputModes::Menu(*this, choices, callback)); + change_input_mode(new InputModes::Menu(*this, choices, callback)); } void Client::on_next_key(KeyCallback callback) { - m_mode_trash.emplace_back(std::move(m_mode)); - m_mode.reset(new InputModes::NextKey(*this, callback)); + change_input_mode(new InputModes::NextKey(*this, callback)); } bool is_valid(Key key) diff --git a/src/client.hh b/src/client.hh index eec3bbd9..8f7d718a 100644 --- a/src/client.hh +++ b/src/client.hh @@ -91,6 +91,8 @@ private: std::unique_ptr m_mode; std::vector> m_mode_trash; + void change_input_mode(InputMode* new_mode); + String m_name; DisplayLine m_status_line;