From 04a37d8895a5e2e1a59e71d447c07e9aefcee64d Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 7 Feb 2012 23:41:10 +0000 Subject: [PATCH] Editor refactoring, merge undo and batch management --- src/editor.cc | 97 ++++++++++----------------------------------------- src/editor.hh | 32 +++++++++++------ src/main.cc | 4 +-- src/window.cc | 4 +-- src/window.hh | 2 +- 5 files changed, 45 insertions(+), 94 deletions(-) diff --git a/src/editor.cc b/src/editor.cc index fe8187d7..172e096c 100644 --- a/src/editor.cc +++ b/src/editor.cc @@ -6,24 +6,9 @@ namespace Kakoune { -namespace -{ - -struct scoped_undo_group -{ - scoped_undo_group(Buffer& buffer) - : m_buffer(buffer) { m_buffer.begin_undo_group(); } - - ~scoped_undo_group() { m_buffer.end_undo_group(); } -private: - Buffer& m_buffer; -}; - -} - Editor::Editor(Buffer& buffer) : m_buffer(buffer), - m_batch_level(0) + m_edition_level(0) { m_selections.push_back(SelectionList()); selections().push_back(Selection(buffer.begin(), buffer.begin())); @@ -31,69 +16,30 @@ Editor::Editor(Buffer& buffer) void Editor::erase() { - if (not is_in_batch()) - { - scoped_undo_group undo_group(m_buffer); - erase_noundo(); - } - else - erase_noundo(); -} - -void Editor::erase_noundo() -{ - check_invariant(); + scoped_edition edition(*this); for (auto& sel : selections()) m_buffer.modify(Modification::make_erase(sel.begin(), sel.end())); } void Editor::insert(const String& string) { - if (not is_in_batch()) - { - scoped_undo_group undo_group(m_buffer); - insert_noundo(string); - } - else - insert_noundo(string); -} - -void Editor::insert_noundo(const String& string) -{ + scoped_edition edition(*this); for (auto& sel : selections()) m_buffer.modify(Modification::make_insert(sel.begin(), string)); } void Editor::append(const String& string) { - if (not is_in_batch()) - { - scoped_undo_group undo_group(m_buffer); - append_noundo(string); - } - else - append_noundo(string); -} - -void Editor::append_noundo(const String& string) -{ + scoped_edition edition(*this); for (auto& sel : selections()) m_buffer.modify(Modification::make_insert(sel.end(), string)); } void Editor::replace(const std::string& string) { - if (not is_in_batch()) - { - scoped_undo_group undo_group(m_buffer); - erase_noundo(); - insert_noundo(string); - } - else - { - erase_noundo(); - insert_noundo(string); - } + scoped_edition edition(*this); + erase(); + insert(string); } void Editor::push_selections() @@ -236,35 +182,30 @@ CandidateList Editor::complete_filterid(const std::string& prefix, return m_filters.complete_id(prefix, cursor_pos); } -void Editor::begin_batch() +void Editor::begin_edition() { - ++m_batch_level; + ++m_edition_level; - if (m_batch_level == 1) - { + if (m_edition_level == 1) m_buffer.begin_undo_group(); - on_begin_batch(); - } } -void Editor::end_batch() +void Editor::end_edition() { - assert(m_batch_level > 0); - if (m_batch_level == 1) - { - on_end_batch(); + assert(m_edition_level > 0); + if (m_edition_level == 1) m_buffer.end_undo_group(); - } - --m_batch_level; + + --m_edition_level; } IncrementalInserter::IncrementalInserter(Editor& editor, Mode mode) - : m_editor(editor) + : m_editor(editor), m_edition(editor) { - m_editor.begin_batch(); + m_editor.on_incremental_insertion_begin(); if (mode == Mode::Change) - editor.erase_noundo(); + editor.erase(); for (auto& sel : m_editor.selections()) { @@ -297,7 +238,7 @@ IncrementalInserter::IncrementalInserter(Editor& editor, Mode mode) IncrementalInserter::~IncrementalInserter() { move_cursors(BufferCoord(0, -1)); - m_editor.end_batch(); + m_editor.on_incremental_insertion_end(); } void IncrementalInserter::apply(Modification&& modification) const diff --git a/src/editor.hh b/src/editor.hh index 3ad15b50..bd08801a 100644 --- a/src/editor.hh +++ b/src/editor.hh @@ -55,31 +55,40 @@ public: CandidateList complete_filterid(const std::string& prefix, size_t cursor_pos = std::string::npos); - void begin_batch(); - void end_batch(); - bool is_in_batch() const { return m_batch_level != 0; } + bool is_editing() const { return m_edition_level!= 0; } private: - void erase_noundo(); - void insert_noundo(const String& string); - void append_noundo(const String& string); + friend class scoped_edition; + void begin_edition(); + void end_edition(); + + int m_edition_level; SelectionList& selections() { return m_selections.back(); } void check_invariant() const; friend class IncrementalInserter; - int m_batch_level; - - virtual void on_begin_batch() {} - virtual void on_end_batch() {} - + virtual void on_incremental_insertion_begin() {} + virtual void on_incremental_insertion_end() {} Buffer& m_buffer; std::vector m_selections; idvaluemap m_filters; }; +struct scoped_edition +{ + scoped_edition(Editor& editor) + : m_editor(editor) + { m_editor.begin_edition(); } + + ~scoped_edition() + { m_editor.end_edition(); } +private: + Editor& m_editor; +}; + // An IncrementalInserter manage insert mode class IncrementalInserter { @@ -109,6 +118,7 @@ private: void apply(Modification&& modification) const; Editor& m_editor; + scoped_edition m_edition; }; } diff --git a/src/main.cc b/src/main.cc index c9066243..a2d13d4d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1054,8 +1054,8 @@ void exec_keys(const KeyList& keys, 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(); }); + + scoped_edition edition(editor); int count = 0; while(pos < keys.size()) diff --git a/src/window.cc b/src/window.cc index e546f655..49eb6c0b 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_in_batch()) + if (is_editing()) oss << "[Insert]"; return oss.str(); } -void Window::on_end_batch() +void Window::on_incremental_insertion_end() { push_selections(); hooks_manager().run_hook("InsertEnd", "", Context(*this)); diff --git a/src/window.hh b/src/window.hh index e01ca275..d79ace21 100644 --- a/src/window.hh +++ b/src/window.hh @@ -50,7 +50,7 @@ private: Window(Buffer& buffer); Window(const Window&) = delete; - void on_end_batch(); + void on_incremental_insertion_end(); void scroll_to_keep_cursor_visible_ifn();