From c8f530af936d1c0a6a12d829a6734e508c832e92 Mon Sep 17 00:00:00 2001
From: Benno Schulenberg <bensberg@justemail.net>
Date: Thu, 19 May 2016 20:43:08 +0200
Subject: [PATCH] statusbar: add a non-beeping message type that does not get
 overwritten

Error messages about lock files should not get overwritten by purely
informational messages, only by alerting ones.

This fixes https://savannah.gnu.org/bugs/?47963.
---
 src/browser.c |  2 +-
 src/files.c   | 18 +++++++++---------
 src/global.c  |  5 +++--
 src/help.c    |  2 +-
 src/nano.c    |  2 +-
 src/nano.h    |  8 ++++----
 src/proto.h   |  5 +++--
 src/winio.c   | 23 ++++++++++++-----------
 8 files changed, 34 insertions(+), 31 deletions(-)

diff --git a/src/browser.c b/src/browser.c
index ae890f1b..d5a8a37f 100644
--- a/src/browser.c
+++ b/src/browser.c
@@ -105,7 +105,7 @@ char *do_browser(char *path, DIR *dir)
 
 	/* Make sure that the cursor is off. */
 	curs_set(0);
-	alerted = FALSE;
+	lastmessage = HUSH;
 
 #ifndef NANO_TINY
 	if (kbinput == KEY_WINCH) {
diff --git a/src/files.c b/src/files.c
index 4b07ed07..fddc78dc 100644
--- a/src/files.c
+++ b/src/files.c
@@ -184,7 +184,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
      * old state. */
     myuid = geteuid();
     if ((mypwuid = getpwuid(myuid)) == NULL) {
-	statusline(ALERT, _("Couldn't determine my identity for lock file "
+	statusline(MILD, _("Couldn't determine my identity for lock file "
 				"(getpwuid() failed)"));
 	goto free_and_fail;
     }
@@ -194,7 +194,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
 	if (errno == ENAMETOOLONG)
 	    myhostname[31] = '\0';
 	else {
-	    statusline(ALERT, _("Couldn't determine hostname for lock file: %s"),
+	    statusline(MILD, _("Couldn't determine hostname for lock file: %s"),
 			strerror(errno));
 	    goto free_and_fail;
 	}
@@ -216,7 +216,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
     /* Maybe we just don't have write access.  Print an error message
      * and continue. */
     if (fd < 0) {
-	statusline(ALERT, _("Error writing lock file %s: %s"),
+	statusline(MILD, _("Error writing lock file %s: %s"),
 			lockfilename, strerror(errno));
 	free(lockdata);
 	return 0;
@@ -227,7 +227,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
     filestream = fdopen(fd, "wb");
 
     if (fd < 0 || filestream == NULL) {
-	statusline(ALERT, _("Error writing lock file %s: %s"), lockfilename,
+	statusline(MILD, _("Error writing lock file %s: %s"), lockfilename,
 			strerror(errno));
 	goto free_and_fail;
     }
@@ -264,7 +264,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
 
     wroteamt = fwrite(lockdata, sizeof(char), lockdatalen, filestream);
     if (wroteamt < lockdatalen) {
-	statusline(ALERT, _("Error writing lock file %s: %s"),
+	statusline(MILD, _("Error writing lock file %s: %s"),
 		lockfilename, ferror(filestream));
 	goto free_and_fail;
     }
@@ -274,7 +274,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
 #endif
 
     if (fclose(filestream) == EOF) {
-	statusline(ALERT, _("Error writing lock file %s: %s"),
+	statusline(MILD, _("Error writing lock file %s: %s"),
 		lockfilename, strerror(errno));
 	goto free_and_fail;
     }
@@ -294,7 +294,7 @@ int write_lockfile(const char *lockfilename, const char *origfilename, bool modi
 int delete_lockfile(const char *lockfilename)
 {
     if (unlink(lockfilename) < 0 && errno != ENOENT) {
-	statusline(ALERT, _("Error deleting lock file %s: %s"), lockfilename,
+	statusline(MILD, _("Error deleting lock file %s: %s"), lockfilename,
 		  strerror(errno));
 	return -1;
     }
@@ -329,7 +329,7 @@ int do_lockfile(const char *filename)
 	int room, ans;
 
 	if ((lockfd = open(lockfilename, O_RDONLY)) < 0) {
-	    statusline(ALERT, _("Error opening lock file %s: %s"),
+	    statusline(MILD, _("Error opening lock file %s: %s"),
 			lockfilename, strerror(errno));
 	    goto free_the_name;
 	}
@@ -341,7 +341,7 @@ int do_lockfile(const char *filename)
 	} while (readamt > 0 && readtot < LOCKBUFSIZE);
 
 	if (readtot < 48) {
-	    statusline(ALERT, _("Error reading lock file %s: "
+	    statusline(MILD, _("Error reading lock file %s: "
 			"Not enough data read"), lockfilename);
 	    free(lockbuf);
 	    goto free_the_name;
diff --git a/src/global.c b/src/global.c
index f5583c64..5805c187 100644
--- a/src/global.c
+++ b/src/global.c
@@ -39,8 +39,9 @@ bool func_key;
 	/* Whether the current keystroke is an extended keypad value. */
 bool focusing = TRUE;
 	/* Whether an update of the edit window should center the cursor. */
-bool alerted = FALSE;
-	/* Whether the next important message should wait a bit. */
+
+message_type lastmessage = HUSH;
+	/* Messages of type HUSH should not overwrite type MILD nor ALERT. */
 
 #ifndef NANO_TINY
 int controlleft = CONTROL_LEFT;
diff --git a/src/help.c b/src/help.c
index f7df4c4b..66716634 100644
--- a/src/help.c
+++ b/src/help.c
@@ -118,7 +118,7 @@ void do_help(void)
 
 	old_line = line;
 
-	alerted = FALSE;
+	lastmessage = HUSH;
 
 	kbinput = get_kbinput(edit);
 
diff --git a/src/nano.c b/src/nano.c
index 7f623d02..f3f3ee6e 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -2657,7 +2657,7 @@ int main(int argc, char **argv)
     while (TRUE) {
 	currmenu = MMAIN;
 	focusing = TRUE;
-	alerted = FALSE;
+	lastmessage = HUSH;
 
 	/* If constant cursor position display is on, and there are no
 	 * keys waiting in the input buffer, display the current cursor
diff --git a/src/nano.h b/src/nano.h
index 71407289..9ffbbc16 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -56,10 +56,6 @@
 /* Suppress warnings for __attribute__((warn_unused_result)). */
 #define IGNORE_CALL_RESULT(call) do { if (call) {} } while(0)
 
-/* Whether to beep when showing a statusbar message. */
-#define ALERT  TRUE
-#define HUSH  FALSE
-
 /* Macros for flags, indexing each bit in a small array. */
 #define FLAGS(flag) flags[((flag) / (sizeof(unsigned) * 8))]
 #define FLAGMASK(flag) (1 << ((flag) % (sizeof(unsigned) * 8)))
@@ -171,6 +167,10 @@ typedef enum {
     NIX_FILE, DOS_FILE, MAC_FILE
 } file_format;
 
+typedef enum {
+    HUSH, MILD, ALERT
+} message_type;
+
 typedef enum {
     OVERWRITE, APPEND, PREPEND
 } append_type;
diff --git a/src/proto.h b/src/proto.h
index c48f0671..0024988a 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -33,7 +33,8 @@ extern volatile sig_atomic_t sigwinch_counter;
 extern bool meta_key;
 extern bool func_key;
 extern bool focusing;
-extern bool alerted;
+
+extern message_type lastmessage;
 
 #ifndef NANO_TINY
 extern int controlleft;
@@ -787,7 +788,7 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
 void titlebar(const char *path);
 extern void set_modified(void);
 void statusbar(const char *msg);
-void statusline(bool sound, const char *msg, ...);
+void statusline(message_type importance, const char *msg, ...);
 void bottombars(int menu);
 void onekey(const char *keystroke, const char *desc, int length);
 void reset_cursor(void);
diff --git a/src/winio.c b/src/winio.c
index ba6eb63d..002f87f7 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -1121,7 +1121,7 @@ int parse_escape_sequence(WINDOW *win, int kbinput)
 	     * (from the keyboard) that nano does not know about. */
 	    statusline(ALERT, _("Unknown sequence"));
 	    suppress_cursorpos = FALSE;
-	    alerted = FALSE;
+	    lastmessage = HUSH;
 	    if (currmenu == MMAIN) {
 		reset_cursor();
 		curs_set(1);
@@ -2055,7 +2055,7 @@ void statusbar(const char *msg)
 /* Display a message on the statusbar, and set suppress_cursorpos to
  * TRUE, so that the message won't be immediately overwritten if
  * constant cursor position display is on. */
-void statusline(bool sound, const char *msg, ...)
+void statusline(message_type importance, const char *msg, ...)
 {
     va_list ap;
     char *bar, *foo;
@@ -2076,18 +2076,19 @@ void statusline(bool sound, const char *msg, ...)
 	return;
     }
 
-    /* If there already was an important message, ignore a normal one and
-     * delay another important one, to allow the earlier one to be noticed. */
-    if (alerted) {
-	if (sound == HUSH)
-	    return;
+    /* If there already was an alert message, ignore lesser ones. */
+    if ((lastmessage == ALERT && importance != ALERT) ||
+		(lastmessage == MILD && importance == HUSH))
+	return;
+
+    /* Delay another alert message, to allow an earlier one to be noticed. */
+    if (lastmessage == ALERT)
 	napms(1200);
-    }
 
-    if (sound == ALERT) {
+    if (importance == ALERT)
 	beep();
-	alerted = TRUE;
-    }
+
+    lastmessage = importance;
 
     /* Turn the cursor off while fiddling in the statusbar. */
     curs_set(0);
-- 
GitLab