Просмотр исходного кода

LibGUI: Make TextEditor write a trailing newline to non-empty files

Fixes #4801.
Andreas Kling 4 лет назад
Родитель
Сommit
7f616449ec
2 измененных файлов с 23 добавлено и 14 удалено
  1. 5 0
      Userland/Libraries/LibGUI/TextDocument.cpp
  2. 18 14
      Userland/Libraries/LibGUI/TextEditor.cpp

+ 5 - 0
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)

+ 18 - 14
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;
         }
     }