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.
This commit is contained in:
Maxime Coste 2013-09-16 19:38:28 +01:00
parent 168b4b775b
commit 7fef7ec063
2 changed files with 18 additions and 15 deletions

View File

@ -26,6 +26,7 @@ public:
InputMode& operator=(const InputMode&) = delete; InputMode& operator=(const InputMode&) = delete;
virtual void on_key(Key key) = 0; virtual void on_key(Key key) = 0;
virtual void on_replaced() {}
Context& context() const { return m_client.context(); } Context& context() const { return m_client.context(); }
using Insertion = Client::Insertion; using Insertion = Client::Insertion;
@ -54,7 +55,7 @@ public:
context().hooks().run_hook("NormalBegin", "", context()); context().hooks().run_hook("NormalBegin", "", context());
} }
~Normal() void on_replaced() override
{ {
context().hooks().run_hook("NormalEnd", "", context()); context().hooks().run_hook("NormalEnd", "", context());
} }
@ -908,12 +909,10 @@ private:
InputMode& InputMode::reset_normal_mode() InputMode& InputMode::reset_normal_mode()
{ {
m_client.m_mode_trash.emplace_back(std::move(m_client.m_mode)); m_client.change_input_mode(new InputModes::Normal(m_client));
m_client.m_mode.reset(new InputModes::Normal(m_client));
return *m_client.m_mode; return *m_client.m_mode;
} }
Client::Client(std::unique_ptr<UserInterface>&& ui, Editor& editor, String name) Client::Client(std::unique_ptr<UserInterface>&& ui, Editor& editor, String name)
: m_ui(std::move(ui)), m_context(*this, editor), m_mode(new InputModes::Normal(*this)), m_name(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) void Client::insert(InsertMode mode)
{ {
m_mode_trash.emplace_back(std::move(m_mode)); change_input_mode(new InputModes::Insert(*this, mode));
m_mode.reset(new InputModes::Insert(*this, mode));
} }
void Client::repeat_last_insert() void Client::repeat_last_insert()
@ -938,8 +943,7 @@ void Client::repeat_last_insert()
swap(keys, m_last_insert.second); swap(keys, m_last_insert.second);
// context.last_insert will be refilled by the new Insert // context.last_insert will be refilled by the new Insert
// this is very inefficient. // this is very inefficient.
m_mode_trash.emplace_back(std::move(m_mode)); change_input_mode(new InputModes::Insert(*this, m_last_insert.first));
m_mode.reset(new InputModes::Insert(*this, m_last_insert.first));
for (auto& key : keys) for (auto& key : keys)
m_mode->on_key(key); m_mode->on_key(key);
kak_assert(dynamic_cast<InputModes::Normal*>(m_mode.get()) != nullptr); kak_assert(dynamic_cast<InputModes::Normal*>(m_mode.get()) != nullptr);
@ -948,9 +952,8 @@ void Client::repeat_last_insert()
void Client::prompt(const String& prompt, ColorPair prompt_colors, void Client::prompt(const String& prompt, ColorPair prompt_colors,
Completer completer, PromptCallback callback) Completer completer, PromptCallback callback)
{ {
m_mode_trash.emplace_back(std::move(m_mode)); change_input_mode(new InputModes::Prompt(*this, prompt, prompt_colors,
m_mode.reset(new InputModes::Prompt(*this, prompt, prompt_colors, completer, callback));
completer, callback));
} }
void Client::set_prompt_colors(ColorPair prompt_colors) void Client::set_prompt_colors(ColorPair prompt_colors)
@ -963,14 +966,12 @@ void Client::set_prompt_colors(ColorPair prompt_colors)
void Client::menu(memoryview<String> choices, void Client::menu(memoryview<String> choices,
MenuCallback callback) MenuCallback callback)
{ {
m_mode_trash.emplace_back(std::move(m_mode)); change_input_mode(new InputModes::Menu(*this, choices, callback));
m_mode.reset(new InputModes::Menu(*this, choices, callback));
} }
void Client::on_next_key(KeyCallback callback) void Client::on_next_key(KeyCallback callback)
{ {
m_mode_trash.emplace_back(std::move(m_mode)); change_input_mode(new InputModes::NextKey(*this, callback));
m_mode.reset(new InputModes::NextKey(*this, callback));
} }
bool is_valid(Key key) bool is_valid(Key key)

View File

@ -91,6 +91,8 @@ private:
std::unique_ptr<InputMode> m_mode; std::unique_ptr<InputMode> m_mode;
std::vector<std::unique_ptr<InputMode>> m_mode_trash; std::vector<std::unique_ptr<InputMode>> m_mode_trash;
void change_input_mode(InputMode* new_mode);
String m_name; String m_name;
DisplayLine m_status_line; DisplayLine m_status_line;