diff --git a/src/editor.cc b/src/editor.cc index afce02db..4f2f7ba9 100644 --- a/src/editor.cc +++ b/src/editor.cc @@ -23,7 +23,7 @@ private: Editor::Editor(Buffer& buffer) : m_buffer(buffer), - m_current_inserter(nullptr) + m_batch_level(0) { m_selections.push_back(SelectionList()); selections().push_back(Selection(buffer.begin(), buffer.begin())); @@ -31,7 +31,7 @@ Editor::Editor(Buffer& buffer) void Editor::erase() { - if (m_current_inserter == nullptr) + if (not is_in_batch()) { scoped_undo_group undo_group(m_buffer); erase_noundo(); @@ -49,7 +49,7 @@ void Editor::erase_noundo() void Editor::insert(const String& string) { - if (m_current_inserter == nullptr) + if (not is_in_batch()) { scoped_undo_group undo_group(m_buffer); insert_noundo(string); @@ -66,7 +66,7 @@ void Editor::insert_noundo(const String& string) void Editor::append(const String& string) { - if (m_current_inserter == nullptr) + if (not is_in_batch()) { scoped_undo_group undo_group(m_buffer); append_noundo(string); @@ -83,7 +83,7 @@ void Editor::append_noundo(const String& string) void Editor::replace(const std::string& string) { - if (m_current_inserter == nullptr) + if (not is_in_batch()) { scoped_undo_group undo_group(m_buffer); erase_noundo(); @@ -237,28 +237,32 @@ CandidateList Editor::complete_filterid(const std::string& prefix, return m_filters.complete_id(prefix, cursor_pos); } -void Editor::begin_incremental_insert(IncrementalInserter* inserter) +void Editor::begin_batch() { - assert(not m_current_inserter); - m_current_inserter = inserter; - m_buffer.begin_undo_group(); + ++m_batch_level; - on_begin_incremental_insert(); + if (m_batch_level == 1) + { + m_buffer.begin_undo_group(); + on_begin_batch(); + } } -void Editor::end_incremental_insert(IncrementalInserter* inserter) +void Editor::end_batch() { - on_end_incremental_insert(); - - assert(m_current_inserter and m_current_inserter == inserter); - m_current_inserter = nullptr; - m_buffer.end_undo_group(); + assert(m_batch_level > 0); + if (m_batch_level == 1) + { + on_end_batch(); + m_buffer.end_undo_group(); + } + --m_batch_level; } IncrementalInserter::IncrementalInserter(Editor& editor, Mode mode) : m_editor(editor) { - m_editor.begin_incremental_insert(this); + m_editor.begin_batch(); if (mode == Mode::Change) editor.erase_noundo(); @@ -294,7 +298,7 @@ IncrementalInserter::IncrementalInserter(Editor& editor, Mode mode) IncrementalInserter::~IncrementalInserter() { move_cursors(BufferCoord(0, -1)); - m_editor.end_incremental_insert(this); + m_editor.end_batch(); } void IncrementalInserter::apply(Modification&& modification) const diff --git a/src/editor.hh b/src/editor.hh index ebd10214..565ae81f 100644 --- a/src/editor.hh +++ b/src/editor.hh @@ -55,7 +55,9 @@ public: CandidateList complete_filterid(const std::string& prefix, size_t cursor_pos = std::string::npos); - bool is_inserting() const { return m_current_inserter != nullptr; } + void begin_batch(); + void end_batch(); + bool is_in_batch() const { return m_batch_level != 0; } private: void erase_noundo(); @@ -67,12 +69,10 @@ private: void check_invariant() const; friend class IncrementalInserter; - IncrementalInserter* m_current_inserter; + int m_batch_level; - void begin_incremental_insert(IncrementalInserter* inserter); - void end_incremental_insert(IncrementalInserter* inserter); - virtual void on_begin_incremental_insert() {} - virtual void on_end_incremental_insert() {} + virtual void on_begin_batch() {} + virtual void on_end_batch() {} Buffer& m_buffer; diff --git a/src/main.cc b/src/main.cc index 3f90a3c3..bd50a97b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1055,8 +1055,12 @@ void exec_string(const CommandParameters& params, return keys[pos++]; }; - Editor standalone_editor(context.buffer()); - Editor& editor = context.has_window() ? context.window() : standalone_editor; + Editor batch_editor(context.buffer()); + Editor& editor = context.has_window() ? static_cast(context.window()) + : static_cast(batch_editor); + + editor.begin_batch(); + auto end_batch = on_scope_end([&]() { editor.end_batch(); }); int count = 0; while(pos < keys.size()) diff --git a/src/window.cc b/src/window.cc index 72ab0578..e546f655 100644 --- a/src/window.cc +++ b/src/window.cc @@ -154,12 +154,12 @@ std::string Window::status_line() const oss << " [+]"; oss << " -- " << cursor.line+1 << "," << cursor.column+1 << " -- " << selections().size() << " sel -- "; - if (is_inserting()) + if (is_in_batch()) oss << "[Insert]"; return oss.str(); } -void Window::on_end_incremental_insert() +void Window::on_end_batch() { push_selections(); hooks_manager().run_hook("InsertEnd", "", Context(*this)); diff --git a/src/window.hh b/src/window.hh index ad755388..e01ca275 100644 --- a/src/window.hh +++ b/src/window.hh @@ -50,7 +50,7 @@ private: Window(Buffer& buffer); Window(const Window&) = delete; - void on_end_incremental_insert(); + void on_end_batch(); void scroll_to_keep_cursor_visible_ifn();