From eef7d1047adbfb36d8a4d0982b8a2881882688b2 Mon Sep 17 00:00:00 2001
From: Benno Schulenberg <bensberg@justemail.net>
Date: Tue, 20 Dec 2016 19:27:41 +0100
Subject: [PATCH] screen: display byte value 0x0A in the right places as ^@ or
 as ^J

In path names and file names, 0x0A means an embedded newline and
should be shown as ^J, but in anything related to the file's data,
0x0A is an encoded NUL and should be displayed as ^@.

So... switch mode at the two main entry points into the "file system"
(reading in a file, and writing out a file), and also when drawing the
titlebar.  Switch back to the default mode in the main loop.

This fixes https://savannah.gnu.org/bugs/?49893.
---
 src/chars.c  | 4 ++--
 src/files.c  | 6 ++++++
 src/global.c | 3 +++
 src/nano.c   | 1 +
 src/proto.h  | 2 ++
 src/search.c | 1 +
 src/winio.c  | 1 +
 7 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/chars.c b/src/chars.c
index c37aada6..a683177b 100644
--- a/src/chars.c
+++ b/src/chars.c
@@ -234,8 +234,8 @@ char control_rep(const signed char c)
 /* Return the visible representation of multibyte control character c. */
 char control_mbrep(const char *c, bool isdata)
 {
-    /* An embedded newline is an encoded null *if* it is data. */
-    if (*c == '\n' && isdata)
+    /* An embedded newline is an encoded NUL if it is data. */
+    if (*c == '\n' && (isdata || as_an_at))
 	return '@';
 
 #ifdef ENABLE_UTF8
diff --git a/src/files.c b/src/files.c
index b79238e5..80245bbd 100644
--- a/src/files.c
+++ b/src/files.c
@@ -1058,6 +1058,9 @@ void do_insertfile(void)
     bool execute = FALSE, right_side_up = FALSE, single_line = FALSE;
 #endif
 
+    /* Display embedded newlines as ^J. */
+    as_an_at = FALSE;
+
     while (TRUE) {
 #ifndef NANO_TINY
 	if (execute) {
@@ -2178,6 +2181,9 @@ int do_writeout(bool exiting)
     static bool did_credits = FALSE;
 #endif
 
+    /* Display embedded newlines as ^J. */
+    as_an_at = FALSE;
+
     if (exiting && ISSET(TEMP_FILE) && openfile->filename[0] != '\0') {
 	if (write_file(openfile->filename, NULL, FALSE, OVERWRITE, FALSE))
 	    return 1;
diff --git a/src/global.c b/src/global.c
index 645c3668..3eb2c5c0 100644
--- a/src/global.c
+++ b/src/global.c
@@ -45,6 +45,9 @@ bool shift_held;
 bool focusing = TRUE;
 	/* Whether an update of the edit window should center the cursor. */
 
+bool as_an_at = TRUE;
+	/* Whether a 0x0A byte should be shown as a ^@ instead of a ^J. */
+
 int margin = 0;
 	/* The amount of space reserved at the left for line numbers. */
 int editwincols = -1;
diff --git a/src/nano.c b/src/nano.c
index cd181aa4..5f1422b1 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -2674,6 +2674,7 @@ int main(int argc, char **argv)
 	    display_main_list();
 
 	lastmessage = HUSH;
+	as_an_at = TRUE;
 
 	/* Update the displayed current cursor position only when there
 	 * are no keys waiting in the input buffer. */
diff --git a/src/proto.h b/src/proto.h
index 189ef757..5680c6ed 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -38,6 +38,8 @@ extern bool shift_held;
 
 extern bool focusing;
 
+extern bool as_an_at;
+
 extern int margin;
 extern int editwincols;
 
diff --git a/src/search.c b/src/search.c
index 7b50ca7a..59ef7a6d 100644
--- a/src/search.c
+++ b/src/search.c
@@ -743,6 +743,7 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
 	    }
 
 	    set_modified();
+	    as_an_at = TRUE;
 	    numreplaced++;
 	}
     }
diff --git a/src/winio.c b/src/winio.c
index c06b2481..555a05a4 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -1967,6 +1967,7 @@ void titlebar(const char *path)
     wattron(topwin, interface_color_pair[TITLE_BAR]);
 
     blank_titlebar();
+    as_an_at = FALSE;
 
     /* Do as Pico: if there is not enough width available for all items,
      * first sacrifice the version string, then eat up the side spaces,
-- 
GitLab