batches support in Editor, used by IncrementalInserter and exec_string
Editor groups all modification together in one undo group when batching. nested batches are supported.
This commit is contained in:
parent
96101b4392
commit
96b167859a
|
@ -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<str_to_str>(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;
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<Editor&>(context.window())
|
||||
: static_cast<Editor&>(batch_editor);
|
||||
|
||||
editor.begin_batch();
|
||||
auto end_batch = on_scope_end([&]() { editor.end_batch(); });
|
||||
|
||||
int count = 0;
|
||||
while(pos < keys.size())
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user