1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 15:47:44 +00:00

LibGUI: Use set_text() for ReplaceAllTextCommand

Previously, this was reimplementing the same thing by removing all the
document text and then inserting the new text - which internally would
insert each code-point individually and fire change notifications for
each one. This made the "Reformat GML" button very slow, since it not
only had to recalculate the visual lines of the document each time, but
also rebuild the preview GUI.

The reason not to use `set_text()` is that it would throw away the undo
stack, since it always behaved as if the text is a new document. So,
let's add a parameter to disable that behaviour.

This takes the time for reformatting a ~200 line GML file from several
seconds, to basically instantaneous. :^)
This commit is contained in:
Sam Atkins 2023-07-26 17:14:57 +01:00 committed by Tim Flynn
parent bf1d680a75
commit 1d7d194062
3 changed files with 17 additions and 26 deletions

View file

@ -42,10 +42,11 @@ TextDocument::TextDocument(Client* client)
};
}
bool TextDocument::set_text(StringView text, AllowCallback allow_callback)
bool TextDocument::set_text(StringView text, AllowCallback allow_callback, IsNewDocument is_new_document)
{
m_client_notifications_enabled = false;
m_undo_stack.clear();
if (is_new_document == IsNewDocument::Yes)
m_undo_stack.clear();
m_spans.clear();
m_folding_regions.clear();
remove_all_lines();
@ -99,7 +100,8 @@ bool TextDocument::set_text(StringView text, AllowCallback allow_callback)
clear_text_guard.disarm();
// FIXME: Should the modified state be cleared on some of the earlier returns as well?
set_unmodified();
if (is_new_document == IsNewDocument::Yes)
set_unmodified();
return true;
}
@ -1057,31 +1059,24 @@ DeprecatedString InsertLineCommand::action_text() const
return action_text_builder.to_deprecated_string();
}
ReplaceAllTextCommand::ReplaceAllTextCommand(GUI::TextDocument& document, DeprecatedString const& text, GUI::TextRange const& range, DeprecatedString const& action_text)
ReplaceAllTextCommand::ReplaceAllTextCommand(GUI::TextDocument& document, DeprecatedString const& text, DeprecatedString const& action_text)
: TextDocumentUndoCommand(document)
, m_original_text(document.text())
, m_new_text(text)
, m_range(range)
, m_action_text(action_text)
{
}
void ReplaceAllTextCommand::redo()
{
m_document.remove(m_range);
m_document.set_all_cursors(m_range.start());
auto new_cursor = m_document.insert_at(m_range.start(), m_new_text, m_client);
m_range.set_end(new_cursor);
m_document.set_all_cursors(new_cursor);
m_document.set_all_cursors({ 0, 0 });
m_document.set_text(m_new_text, AllowCallback::Yes, TextDocument::IsNewDocument::No);
}
void ReplaceAllTextCommand::undo()
{
m_document.remove(m_range);
m_document.set_all_cursors(m_range.start());
auto new_cursor = m_document.insert_at(m_range.start(), m_original_text, m_client);
m_range.set_end(new_cursor);
m_document.set_all_cursors(new_cursor);
m_document.set_all_cursors({ 0, 0 });
m_document.set_text(m_original_text, AllowCallback::Yes, TextDocument::IsNewDocument::No);
}
bool ReplaceAllTextCommand::merge_with(GUI::Command const&)