From 0da5cabbfe3009d9d29b0d2d28381b252aadbe40 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Thu, 28 Sep 2017 11:11:29 +0800 Subject: [PATCH] Distinguish between modes being disabled temporarily and definitely That way, insert mode knows when it can restore selections/avoid eol instead of (wrongly) doing it in the destructor that ends up running unpredictibly (as the mode is kept alive during its on_key call, even though it can happen that it is not the active mode anymore at the end of that call). Fixes #1580 --- src/input_handler.cc | 42 +++++++++---------- test/regression/1580-A-not-moving-to-eol/cmd | 1 + test/regression/1580-A-not-moving-to-eol/in | 2 + test/regression/1580-A-not-moving-to-eol/rc | 1 + .../regression/1580-A-not-moving-to-eol/state | 1 + 5 files changed, 26 insertions(+), 21 deletions(-) create mode 100644 test/regression/1580-A-not-moving-to-eol/cmd create mode 100644 test/regression/1580-A-not-moving-to-eol/in create mode 100644 test/regression/1580-A-not-moving-to-eol/rc create mode 100644 test/regression/1580-A-not-moving-to-eol/state diff --git a/src/input_handler.cc b/src/input_handler.cc index df9186ae..d4214ed1 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -30,7 +30,7 @@ public: void handle_key(Key key) { RefPtr keep_alive{this}; on_key(key); } virtual void on_enabled() {} - virtual void on_disabled() {} + virtual void on_disabled(bool temporary) {} bool enabled() const { return &m_input_handler.current_mode() == this; } Context& context() const { return m_input_handler.context(); } @@ -194,7 +194,7 @@ public: context().hooks().run_hook("NormalBegin", "", context()); } - void on_disabled() override + void on_disabled(bool) override { m_idle_timer.set_next_date(TimePoint::max()); m_fs_check_timer.set_next_date(TimePoint::max()); @@ -966,7 +966,7 @@ private: m_idle_timer.set_next_date(Clock::now() + get_idle_timeout(context())); } - void on_disabled() override + void on_disabled(bool) override { context().print_status({}); m_idle_timer.set_next_date(TimePoint::max()); @@ -1063,29 +1063,29 @@ public: get_face("Error") }); } - ~Insert() override - { - auto& selections = context().selections(); - if (m_restore_cursor) - { - for (auto& sel : selections) - { - if (sel.cursor() > sel.anchor() and sel.cursor().column > 0) - sel.cursor() = context().buffer().char_prev(sel.cursor()); - } - } - selections.avoid_eol(); - } - void on_enabled() override { if (not (context().flags() & Context::Flags::Transient)) m_idle_timer.set_next_date(Clock::now() + get_idle_timeout(context())); } - void on_disabled() override + void on_disabled(bool temporary) override { m_idle_timer.set_next_date(TimePoint::max()); + + if (not temporary) + { + auto& selections = context().selections(); + if (m_restore_cursor) + { + for (auto& sel : selections) + { + if (sel.cursor() > sel.anchor() and sel.cursor().column > 0) + sel.cursor() = context().buffer().char_prev(sel.cursor()); + } + } + selections.avoid_eol(); + } } void on_key(Key key) override @@ -1393,7 +1393,7 @@ InputHandler::~InputHandler() = default; void InputHandler::push_mode(InputMode* new_mode) { - current_mode().on_disabled(); + current_mode().on_disabled(true); m_mode_stack.emplace_back(new_mode); new_mode->on_enabled(); } @@ -1403,7 +1403,7 @@ void InputHandler::pop_mode(InputMode* mode) kak_assert(m_mode_stack.back().get() == mode); kak_assert(m_mode_stack.size() > 1); - current_mode().on_disabled(); + current_mode().on_disabled(false); m_mode_stack.pop_back(); current_mode().on_enabled(); } @@ -1412,7 +1412,7 @@ void InputHandler::reset_normal_mode() { if (m_mode_stack.size() > 1) { - current_mode().on_disabled(); + current_mode().on_disabled(false); m_mode_stack.resize(1); } kak_assert(dynamic_cast(¤t_mode()) != nullptr); diff --git a/test/regression/1580-A-not-moving-to-eol/cmd b/test/regression/1580-A-not-moving-to-eol/cmd new file mode 100644 index 00000000..0be34fa7 --- /dev/null +++ b/test/regression/1580-A-not-moving-to-eol/cmd @@ -0,0 +1 @@ +i diff --git a/test/regression/1580-A-not-moving-to-eol/in b/test/regression/1580-A-not-moving-to-eol/in new file mode 100644 index 00000000..9c4f1f64 --- /dev/null +++ b/test/regression/1580-A-not-moving-to-eol/in @@ -0,0 +1,2 @@ +1234 { +%(}) diff --git a/test/regression/1580-A-not-moving-to-eol/rc b/test/regression/1580-A-not-moving-to-eol/rc new file mode 100644 index 00000000..8be66d93 --- /dev/null +++ b/test/regression/1580-A-not-moving-to-eol/rc @@ -0,0 +1 @@ +hook global InsertChar \n %{ exec -draft k; exec kA; } diff --git a/test/regression/1580-A-not-moving-to-eol/state b/test/regression/1580-A-not-moving-to-eol/state new file mode 100644 index 00000000..354c3f94 --- /dev/null +++ b/test/regression/1580-A-not-moving-to-eol/state @@ -0,0 +1 @@ +2.5,2.5