InputHandler: InputModes no longer die directly on mode change, they survive until end of on_key

This commit is contained in:
Maxime Coste 2012-11-27 18:52:43 +01:00
parent dc268758dd
commit 4c1b48e314
2 changed files with 15 additions and 17 deletions

View File

@ -48,13 +48,9 @@ public:
if (it != keymap.end()) if (it != keymap.end())
{ {
context.numeric_param() = m_count; context.numeric_param() = m_count;
// it's important to do that before calling the command,
// as we may die during the command execution.
m_count = 0;
it->second(context); it->second(context);
} }
else m_count = 0;
m_count = 0;
} }
} }
@ -154,11 +150,9 @@ public:
{ {
context.ui().menu_hide(); context.ui().menu_hide();
context.ui().print_status(""); context.ui().print_status("");
// save callback as reset_normal_mode will delete this
MenuCallback callback = std::move(m_callback);
int selected = m_selected - m_choices.begin();
reset_normal_mode(); reset_normal_mode();
callback(selected, context); int selected = m_selected - m_choices.begin();
m_callback(selected, context);
return; return;
} }
else if (key == Key::Escape or key == Key{ Key::Modifiers::Control, 'c' }) else if (key == Key::Escape or key == Key{ Key::Modifiers::Control, 'c' })
@ -258,13 +252,10 @@ public:
history.push_back(line); history.push_back(line);
context.ui().print_status(""); context.ui().print_status("");
context.ui().menu_hide(); context.ui().menu_hide();
// save callback as reset_normal_mode will delete this
PromptCallback callback = std::move(m_callback);
String result = line;
reset_normal_mode(); reset_normal_mode();
// call callback after reset_normal_mode so that callback // call callback after reset_normal_mode so that callback
// may change the mode // may change the mode
callback(result, context); m_callback(line, context);
return; return;
} }
else if (key == Key::Escape or key == Key { Key::Modifiers::Control, 'c' }) else if (key == Key::Escape or key == Key { Key::Modifiers::Control, 'c' })
@ -385,10 +376,8 @@ public:
void on_key(const Key& key, Context& context) override void on_key(const Key& key, Context& context) override
{ {
// save callback as reset_normal_mode will delete this
KeyCallback callback = std::move(m_callback);
reset_normal_mode(); reset_normal_mode();
callback(key, context); m_callback(key, context);
} }
private: private:
@ -550,7 +539,8 @@ private:
void InputMode::reset_normal_mode() void InputMode::reset_normal_mode()
{ {
m_input_handler.m_mode.reset(new InputModes::Normal(m_input_handler)); m_input_handler.m_mode_trash.emplace_back(std::move(m_input_handler.m_mode));
m_input_handler.m_mode.reset(new InputModes::Normal(m_input_handler));
} }
@ -566,6 +556,7 @@ InputHandler::~InputHandler()
void InputHandler::insert(Context& context, InsertMode mode) void InputHandler::insert(Context& context, InsertMode mode)
{ {
assert(&context.input_handler() == this); assert(&context.input_handler() == this);
m_mode_trash.emplace_back(std::move(m_mode));
m_mode.reset(new InputModes::Insert(context, mode)); m_mode.reset(new InputModes::Insert(context, mode));
} }
@ -580,6 +571,7 @@ void InputHandler::repeat_last_insert(Context& context)
swap(keys, last_insert.second); swap(keys, 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));
m_mode.reset(new InputModes::Insert(context, last_insert.first)); m_mode.reset(new InputModes::Insert(context, last_insert.first));
for (auto& key : keys) for (auto& key : keys)
m_mode->on_key(key, context); m_mode->on_key(key, context);
@ -590,6 +582,7 @@ void InputHandler::prompt(const String& prompt, Completer completer,
PromptCallback callback, Context& context) PromptCallback callback, Context& context)
{ {
assert(&context.input_handler() == this); assert(&context.input_handler() == this);
m_mode_trash.emplace_back(std::move(m_mode));
m_mode.reset(new InputModes::Prompt(context, prompt, completer, callback)); m_mode.reset(new InputModes::Prompt(context, prompt, completer, callback));
} }
@ -597,11 +590,13 @@ void InputHandler::menu(const memoryview<String>& choices,
MenuCallback callback, Context& context) MenuCallback callback, Context& context)
{ {
assert(&context.input_handler() == this); assert(&context.input_handler() == this);
m_mode_trash.emplace_back(std::move(m_mode));
m_mode.reset(new InputModes::Menu(context, choices, callback)); m_mode.reset(new InputModes::Menu(context, choices, callback));
} }
void InputHandler::on_next_key(KeyCallback callback) void InputHandler::on_next_key(KeyCallback callback)
{ {
m_mode_trash.emplace_back(std::move(m_mode));
m_mode.reset(new InputModes::NextKey(*this, callback)); m_mode.reset(new InputModes::NextKey(*this, callback));
} }
@ -612,11 +607,13 @@ bool is_valid(const Key& key)
void InputHandler::handle_available_inputs(Context& context) void InputHandler::handle_available_inputs(Context& context)
{ {
m_mode_trash.clear();
while (context.ui().is_key_available()) while (context.ui().is_key_available())
{ {
Key key = context.ui().get_key(); Key key = context.ui().get_key();
if (is_valid(key)) if (is_valid(key))
m_mode->on_key(key, context); m_mode->on_key(key, context);
m_mode_trash.clear();
} }
} }

View File

@ -41,6 +41,7 @@ public:
private: private:
friend class InputMode; friend class InputMode;
std::unique_ptr<InputMode> m_mode; std::unique_ptr<InputMode> m_mode;
std::vector<std::unique_ptr<InputMode>> m_mode_trash;
}; };
struct prompt_aborted {}; struct prompt_aborted {};