summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2024-03-23 16:25:32 +1100
committerMaxime Coste <mawww@kakoune.org>2024-03-23 16:29:03 +1100
commit6e4bb5fbc5bc01c9143e40e3f4cb5b48efb020ec (patch)
tree2b8a3776b508d0f43daae0e1aad2de58291372c7 /src
parent71b003b6841f2b5a04f12a5677db729b3d24ce44 (diff)
Refactor last insert recording logic
Only record non-synthetized insertions, removing the need to re-record on replay and fixing the last replay getting dropped by macro execution. Fixes #5122
Diffstat (limited to 'src')
-rw-r--r--src/input_handler.cc48
-rw-r--r--src/insert_completer.cc17
-rw-r--r--src/insert_completer.hh2
3 files changed, 32 insertions, 35 deletions
diff --git a/src/input_handler.cc b/src/input_handler.cc
index 5800a6a0..b4bb32a4 100644
--- a/src/input_handler.cc
+++ b/src/input_handler.cc
@@ -56,7 +56,6 @@ public:
}
using Insertion = InputHandler::Insertion;
- Insertion& last_insert() { return m_input_handler.m_last_insert; }
protected:
virtual void on_key(Key key, bool synthesized) = 0;
@@ -1140,11 +1139,12 @@ private:
class Insert : public InputMode
{
public:
- Insert(InputHandler& input_handler, InsertMode mode, int count)
+ Insert(InputHandler& input_handler, InsertMode mode, int count, Insertion* last_insert)
: InputMode(input_handler),
m_edition(context()),
m_selection_edition(context()),
m_completer(context()),
+ m_last_insert(last_insert),
m_restore_cursor(mode == InsertMode::Append),
m_auto_complete{context().options()["autocomplete"].get<AutoComplete>() & AutoComplete::Insert},
m_idle_timer{TimePoint::max(), context().flags() & Context::Flags::Draft ?
@@ -1157,11 +1157,14 @@ public:
{
context().buffer().throw_if_read_only();
- last_insert().recording.set();
- last_insert().mode = mode;
- last_insert().keys.clear();
- last_insert().disable_hooks = context().hooks_disabled();
- last_insert().count = count;
+ if (m_last_insert)
+ {
+ m_last_insert->recording.set();
+ m_last_insert->mode = mode;
+ m_last_insert->keys.clear();
+ m_last_insert->disable_hooks = context().hooks_disabled();
+ m_last_insert->count = count;
+ }
prepare(mode, count);
}
@@ -1177,7 +1180,8 @@ public:
if (not from_push)
{
- last_insert().recording.unset();
+ if (m_last_insert)
+ m_last_insert->recording.unset();
auto& selections = context().selections();
if (m_restore_cursor)
@@ -1291,11 +1295,11 @@ public:
}
else if (key == ctrl('n') or key == ctrl('p') or key.modifiers == Key::Modifiers::MenuSelect)
{
- if (not synthesized)
- last_insert().keys.pop_back();
+ if (m_last_insert and not synthesized)
+ m_last_insert->keys.pop_back();
bool relative = key.modifiers != Key::Modifiers::MenuSelect;
int index = relative ? (key == ctrl('n') ? 1 : -1) : key.key;
- m_completer.select(index, relative, last_insert().keys);
+ m_completer.select(index, relative, m_last_insert ? &m_last_insert->keys : nullptr);
update_completions = false;
}
else if (key == ctrl('x'))
@@ -1494,6 +1498,7 @@ private:
ScopedEdition m_edition;
ScopedSelectionEdition m_selection_edition;
InsertCompleter m_completer;
+ Insertion* m_last_insert;
const bool m_restore_cursor;
bool m_auto_complete;
Timer m_idle_timer;
@@ -1550,7 +1555,7 @@ void InputHandler::reset_normal_mode()
void InputHandler::insert(InsertMode mode, int count)
{
- push_mode(new InputModes::Insert(*this, mode, count));
+ push_mode(new InputModes::Insert(*this, mode, count, m_handle_key_level <= 1 ? &m_last_insert : nullptr));
}
void InputHandler::repeat_last_insert()
@@ -1562,19 +1567,12 @@ void InputHandler::repeat_last_insert()
m_last_insert.recording)
throw runtime_error{"repeating last insert not available in this context"};
- Vector<Key> keys;
- swap(keys, m_last_insert.keys);
ScopedSetBool disable_hooks(context().hooks_disabled(),
m_last_insert.disable_hooks);
- push_mode(new InputModes::Insert(*this, m_last_insert.mode, m_last_insert.count));
- for (auto& key : keys)
- {
- // refill last_insert, this is very inefficient, but necessary at the moment
- // to properly handle insert completion
- m_last_insert.keys.push_back(key);
+ push_mode(new InputModes::Insert(*this, m_last_insert.mode, m_last_insert.count, nullptr));
+ for (auto& key : m_last_insert.keys)
handle_key(key);
- }
kak_assert(dynamic_cast<InputModes::Normal*>(&current_mode()) != nullptr);
}
@@ -1645,10 +1643,6 @@ void InputHandler::handle_key(Key key)
++m_handle_key_level;
auto dec = on_scope_end([this]{ --m_handle_key_level;} );
- auto process_key = [&](Key key, bool synthesized) {
- current_mode().handle_key(key, synthesized);
- };
-
if (m_last_insert.recording and m_handle_key_level <= 1)
m_last_insert.keys.push_back(key);
@@ -1659,10 +1653,10 @@ void InputHandler::handle_key(Key key)
ScopedSetBool noninteractive{context().noninteractive()};
for (auto& k : keymaps.get_mapping_keys(key, keymap_mode))
- process_key(k, true);
+ current_mode().handle_key(k, true);
}
else
- process_key(key, m_handle_key_level > 1);
+ current_mode().handle_key(key, m_handle_key_level > 1);
// do not record the key that made us enter or leave recording mode,
// and the ones that are triggered recursively by previous keys.
diff --git a/src/insert_completer.cc b/src/insert_completer.cc
index af387506..c50fbe00 100644
--- a/src/insert_completer.cc
+++ b/src/insert_completer.cc
@@ -413,7 +413,7 @@ InsertCompleter::~InsertCompleter()
m_options.unregister_watcher(*this);
}
-void InsertCompleter::select(int index, bool relative, Vector<Key>& keystrokes)
+void InsertCompleter::select(int index, bool relative, Vector<Key>* keystrokes)
{
m_enabled = true;
if (not setup_ifn())
@@ -450,12 +450,15 @@ void InsertCompleter::select(int index, bool relative, Vector<Key>& keystrokes)
m_context.client().menu_select(m_current_candidate);
}
- for (auto i = 0_byte; i < prefix_len; ++i)
- keystrokes.emplace_back(Key::Backspace);
- for (auto i = 0_byte; i < suffix_len; ++i)
- keystrokes.emplace_back(Key::Delete);
- for (auto& c : candidate.completion)
- keystrokes.emplace_back(c);
+ if (keystrokes)
+ {
+ for (auto i = 0_byte; i < prefix_len; ++i)
+ keystrokes->emplace_back(Key::Backspace);
+ for (auto i = 0_byte; i < suffix_len; ++i)
+ keystrokes->emplace_back(Key::Delete);
+ for (auto& c : candidate.completion)
+ keystrokes->emplace_back(c);
+ }
if (not candidate.on_select.empty())
CommandManager::instance().execute(candidate.on_select, m_context);
diff --git a/src/insert_completer.hh b/src/insert_completer.hh
index cce433a2..3d5f2ca6 100644
--- a/src/insert_completer.hh
+++ b/src/insert_completer.hh
@@ -78,7 +78,7 @@ public:
InsertCompleter& operator=(const InsertCompleter&) = delete;
~InsertCompleter();
- void select(int index, bool relative, Vector<Key>& keystrokes);
+ void select(int index, bool relative, Vector<Key>* keystrokes);
void update(bool allow_implicit);
void try_accept();
void reset();