Forráskód Böngészése

LibGUI: Don't merge TextDocumentUndoCommand if too much time has elapsed

ForLoveOfCats 3 éve
szülő
commit
2adc5efe2b

+ 9 - 3
Userland/Libraries/LibGUI/TextDocument.cpp

@@ -762,7 +762,7 @@ String InsertTextCommand::action_text() const
 
 bool InsertTextCommand::merge_with(GUI::Command const& other)
 {
-    if (!is<InsertTextCommand>(other))
+    if (!is<InsertTextCommand>(other) || commit_time_expired())
         return false;
 
     auto const& typed_other = static_cast<InsertTextCommand const&>(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<RemoveTextCommand>(other))
+    if (!is<RemoveTextCommand>(other) || commit_time_expired())
         return false;
-    auto& typed_other = static_cast<RemoveTextCommand const&>(other);
+
+    auto const& typed_other = static_cast<RemoveTextCommand const&>(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;
 }
 

+ 6 - 0
Userland/Libraries/LibGUI/TextDocument.h

@@ -12,6 +12,7 @@
 #include <AK/NonnullRefPtr.h>
 #include <AK/Optional.h>
 #include <AK/RefCounted.h>
+#include <AK/Time.h>
 #include <AK/Utf32View.h>
 #include <LibCore/Forward.h>
 #include <LibGUI/Command.h>
@@ -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 };
 };