[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [PATCH] vi: Fix 'o' and 'A' for files without an EOL.
From:       Petja Patjas <pp01415943 () gmail ! com>
Date:       2023-04-07 21:13:04
Message-ID: 8f744744-9f76-9e61-b26e-d33f5335a6f8 () gmail ! com
[Download RAW message or body]

> 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
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic