1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-22 22:37:40 +00:00

LibGUI: Allow TextDocument::set_text to fail

This commit is contained in:
Itamar 2021-03-19 12:57:30 +02:00 committed by Andreas Kling
parent f8c603fe7e
commit 3cc7b00e24
2 changed files with 38 additions and 10 deletions

View file

@ -25,6 +25,7 @@
*/ */
#include <AK/Badge.h> #include <AK/Badge.h>
#include <AK/ScopeGuard.h>
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <AK/Utf8View.h> #include <AK/Utf8View.h>
#include <LibCore/Timer.h> #include <LibCore/Timer.h>
@ -57,28 +58,48 @@ TextDocument::~TextDocument()
{ {
} }
void TextDocument::set_text(const StringView& text) bool TextDocument::set_text(const StringView& text)
{ {
m_client_notifications_enabled = false; m_client_notifications_enabled = false;
m_spans.clear(); m_spans.clear();
remove_all_lines(); remove_all_lines();
ArmedScopeGuard clear_text_guard([this]() {
set_text({});
});
size_t start_of_current_line = 0; size_t start_of_current_line = 0;
auto add_line = [&](size_t current_position) { auto add_line = [&](size_t current_position) -> bool {
size_t line_length = current_position - start_of_current_line; size_t line_length = current_position - start_of_current_line;
auto line = make<TextDocumentLine>(*this); auto line = make<TextDocumentLine>(*this);
bool success = true;
if (line_length) if (line_length)
line->set_text(*this, text.substring_view(start_of_current_line, current_position - start_of_current_line)); success = line->set_text(*this, text.substring_view(start_of_current_line, current_position - start_of_current_line));
if (!success)
return false;
append_line(move(line)); append_line(move(line));
start_of_current_line = current_position + 1; start_of_current_line = current_position + 1;
return true;
}; };
size_t i = 0; size_t i = 0;
for (i = 0; i < text.length(); ++i) { for (i = 0; i < text.length(); ++i) {
if (text[i] == '\n') if (text[i] != '\n')
add_line(i); continue;
auto success = add_line(i);
if (!success)
return false;
} }
add_line(i);
auto success = add_line(i);
if (!success)
return false;
// Don't show the file's trailing newline as an actual new line. // Don't show the file's trailing newline as an actual new line.
if (line_count() > 1 && line(line_count() - 1).is_empty()) if (line_count() > 1 && line(line_count() - 1).is_empty())
@ -88,6 +109,9 @@ void TextDocument::set_text(const StringView& text)
for (auto* client : m_clients) for (auto* client : m_clients)
client->document_did_set_text(); client->document_did_set_text();
clear_text_guard.disarm();
return true;
} }
size_t TextDocumentLine::first_non_whitespace_column() const size_t TextDocumentLine::first_non_whitespace_column() const
@ -157,17 +181,21 @@ void TextDocumentLine::set_text(TextDocument& document, const Vector<u32> text)
document.update_views({}); document.update_views({});
} }
void TextDocumentLine::set_text(TextDocument& document, const StringView& text) bool TextDocumentLine::set_text(TextDocument& document, const StringView& text)
{ {
if (text.is_empty()) { if (text.is_empty()) {
clear(document); clear(document);
return; return true;
} }
m_text.clear(); m_text.clear();
Utf8View utf8_view(text); Utf8View utf8_view(text);
if (!utf8_view.validate()) {
return false;
}
for (auto code_point : utf8_view) for (auto code_point : utf8_view)
m_text.append(code_point); m_text.append(code_point);
document.update_views({}); document.update_views({});
return true;
} }
void TextDocumentLine::append(TextDocument& document, const u32* code_points, size_t length) void TextDocumentLine::append(TextDocument& document, const u32* code_points, size_t length)

View file

@ -81,7 +81,7 @@ public:
void set_spans(Vector<TextDocumentSpan> spans) { m_spans = move(spans); } void set_spans(Vector<TextDocumentSpan> spans) { m_spans = move(spans); }
void set_text(const StringView&); bool set_text(const StringView&);
const NonnullOwnPtrVector<TextDocumentLine>& lines() const { return m_lines; } const NonnullOwnPtrVector<TextDocumentLine>& lines() const { return m_lines; }
NonnullOwnPtrVector<TextDocumentLine>& lines() { return m_lines; } NonnullOwnPtrVector<TextDocumentLine>& lines() { return m_lines; }
@ -176,7 +176,7 @@ public:
Utf32View view() const { return { code_points(), length() }; } Utf32View view() const { return { code_points(), length() }; }
const u32* code_points() const { return m_text.data(); } const u32* code_points() const { return m_text.data(); }
size_t length() const { return m_text.size(); } size_t length() const { return m_text.size(); }
void set_text(TextDocument&, const StringView&); bool set_text(TextDocument&, const StringView&);
void set_text(TextDocument&, Vector<u32>); void set_text(TextDocument&, Vector<u32>);
void append(TextDocument&, u32); void append(TextDocument&, u32);
void prepend(TextDocument&, u32); void prepend(TextDocument&, u32);