From 2adc5efe2b80b48c9cdb7648ad377832d93b36ae Mon Sep 17 00:00:00 2001 From: ForLoveOfCats Date: Sun, 24 Apr 2022 20:35:59 -0400 Subject: [PATCH] LibGUI: Don't merge TextDocumentUndoCommand if too much time has elapsed --- Userland/Libraries/LibGUI/TextDocument.cpp | 12 +++++++++--- Userland/Libraries/LibGUI/TextDocument.h | 6 ++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibGUI/TextDocument.cpp b/Userland/Libraries/LibGUI/TextDocument.cpp index 40a504a162..10a8f76cb3 100644 --- a/Userland/Libraries/LibGUI/TextDocument.cpp +++ b/Userland/Libraries/LibGUI/TextDocument.cpp @@ -762,7 +762,7 @@ String InsertTextCommand::action_text() const bool InsertTextCommand::merge_with(GUI::Command const& other) { - if (!is(other)) + if (!is(other) || commit_time_expired()) return false; auto const& typed_other = static_cast(other); @@ -780,6 +780,7 @@ bool InsertTextCommand::merge_with(GUI::Command const& other) m_text = builder.to_string(); m_range.set_end(typed_other.m_range.end()); + m_timestamp = Time::now_monotonic(); return true; } @@ -862,19 +863,24 @@ String RemoveTextCommand::action_text() const bool RemoveTextCommand::merge_with(GUI::Command const& other) { - if (!is(other)) + if (!is(other) || commit_time_expired()) return false; - auto& typed_other = static_cast(other); + + auto const& typed_other = static_cast(other); + if (m_range.start() != typed_other.m_range.end()) return false; if (m_range.start().line() != m_range.end().line()) return false; + // Merge backspaces StringBuilder builder(m_text.length() + typed_other.m_text.length()); builder.append(typed_other.m_text); builder.append(m_text); m_text = builder.to_string(); m_range.set_start(typed_other.m_range.start()); + + m_timestamp = Time::now_monotonic(); return true; } diff --git a/Userland/Libraries/LibGUI/TextDocument.h b/Userland/Libraries/LibGUI/TextDocument.h index c024c85090..dc24141fab 100644 --- a/Userland/Libraries/LibGUI/TextDocument.h +++ b/Userland/Libraries/LibGUI/TextDocument.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,8 @@ namespace GUI { +constexpr Time COMMAND_COMMIT_TIME = Time::from_milliseconds(400); + struct TextDocumentSpan { TextRange range; Gfx::TextAttributes attributes; @@ -202,6 +205,9 @@ public: } protected: + bool commit_time_expired() const { return Time::now_monotonic() - m_timestamp >= COMMAND_COMMIT_TIME; } + + Time m_timestamp = Time::now_monotonic(); TextDocument& m_document; TextDocument::Client const* m_client { nullptr }; };