diff options
author | Andreas Kling <kling@serenityos.org> | 2021-02-15 18:02:33 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-02-15 18:02:33 +0100 |
commit | 7f616449ec1c192bd43c9eb70b7a655b35a3e161 (patch) | |
tree | fd03a0f8577cdaf97d1e119db689d1e0c275b6c2 | |
parent | a048f46be599a4db8ba457cbd4e5ce57cc54161c (diff) | |
download | serenity-7f616449ec1c192bd43c9eb70b7a655b35a3e161.zip |
LibGUI: Make TextEditor write a trailing newline to non-empty files
Fixes #4801.
-rw-r--r-- | Userland/Libraries/LibGUI/TextDocument.cpp | 5 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/TextEditor.cpp | 32 |
2 files changed, 23 insertions, 14 deletions
diff --git a/Userland/Libraries/LibGUI/TextDocument.cpp b/Userland/Libraries/LibGUI/TextDocument.cpp index 986c4cd308..3c1836184e 100644 --- a/Userland/Libraries/LibGUI/TextDocument.cpp +++ b/Userland/Libraries/LibGUI/TextDocument.cpp @@ -79,6 +79,11 @@ void TextDocument::set_text(const StringView& text) add_line(i); } add_line(i); + + // Don't show the file's trailing newline as an actual new line. + if (line_count() > 1 && line(line_count() - 1).is_empty()) + m_lines.take_last(); + m_client_notifications_enabled = true; for (auto* client : m_clients) diff --git a/Userland/Libraries/LibGUI/TextEditor.cpp b/Userland/Libraries/LibGUI/TextEditor.cpp index 93dc5d13f2..1005098f2b 100644 --- a/Userland/Libraries/LibGUI/TextEditor.cpp +++ b/Userland/Libraries/LibGUI/TextEditor.cpp @@ -1060,19 +1060,25 @@ bool TextEditor::write_to_file(const String& path) ScopeGuard fd_guard = [fd] { close(fd); }; - // Compute the final file size and ftruncate() to make writing fast. - // FIXME: Remove this once the kernel is smart enough to do this instead. off_t file_size = 0; - for (size_t i = 0; i < line_count(); ++i) - file_size += line(i).length(); - file_size += line_count() - 1; + if (line_count() == 1 && line(0).is_empty()) { + // Truncate to zero. + } else { + // Compute the final file size and ftruncate() to make writing fast. + // FIXME: Remove this once the kernel is smart enough to do this instead. + for (size_t i = 0; i < line_count(); ++i) + file_size += line(i).length(); + file_size += line_count(); + } - int rc = ftruncate(fd, file_size); - if (rc < 0) { + if (ftruncate(fd, file_size) < 0) { perror("ftruncate"); return false; } + if (file_size == 0) + return true; + for (size_t i = 0; i < line_count(); ++i) { auto& line = this->line(i); if (line.length()) { @@ -1083,13 +1089,11 @@ bool TextEditor::write_to_file(const String& path) return false; } } - if (i != line_count() - 1) { - char ch = '\n'; - ssize_t nwritten = write(fd, &ch, 1); - if (nwritten != 1) { - perror("write"); - return false; - } + char ch = '\n'; + ssize_t nwritten = write(fd, &ch, 1); + if (nwritten != 1) { + perror("write"); + return false; } } |