The problem can be reproduced by creating a file with some text that
does not end in a newline:

$ printf test > test
$ vi test
<press 'o'>

The last character will be placed on the next line as well. Problems can
be seen with the 'A' command too.

This patch should fix the problems.
---
 editors/vi.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/editors/vi.c b/editors/vi.c
index 2645afe87..ca8130722 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -556,6 +556,7 @@ static int crashme = 0;
static void show_status_line(void); // put a message on the bottom line
 static void status_line_bold(const char *, ...);
+static char *char_insert(char *p, char c, int undo);
static void show_help(void)
 {
@@ -1830,6 +1831,10 @@ static void dot_end(void)
 {
     undo_queue_commit();
     dot = end_line(dot);    // return pointer to last char cur line
+    if (*dot != '\n') {
+        /* There was no EOL, so create one. */
+        dot = char_insert(dot + 1, '\n', NO_UNDO) - 1;
+    }
 }
static char *move_to_col(char *p, int l)

Ignore that patch, it breaks empty files.

Here is another try. This makes init_text_buffer() add a terminating
newline if the file is empty or the last character is not a newline.
---
 editors/vi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/editors/vi.c b/editors/vi.c
index 2645afe87..d6c6e068e 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -2318,6 +2318,9 @@ static int init_text_buffer(char *fn)
        if (rc < 0) {
                // file doesnt exist. Start empty buf with dummy line
                char_insert(text, '\n', NO_UNDO);
+       } else if (end == text || *(end - 1) != '\n') {
+               // Make the last character of the buffer a newline.
+               char_insert(end, '\n', NO_UNDO);
        }
flush_undo_data();

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to