From 18481ed91be0cba5460a738347854c394628db72 Mon Sep 17 00:00:00 2001
From: Benno Schulenberg <bensberg@telfort.nl>
Date: Sat, 15 Aug 2020 17:32:31 +0200
Subject: [PATCH 1/2] display: first implementation of a minimal
 state-information bar

This also suppresses status-bar feedback for toggles whose effect
is obvious and things whose state is already shown in the minibar.

This addresses https://savannah.gnu.org/bugs/?57953,
and addresses https://savannah.gnu.org/bugs/?58152,
and addresses https://savannah.gnu.org/bugs/?58789.
---
 src/definitions.h |  2 ++
 src/nano.c        | 16 ++++++++++---
 src/prototypes.h  |  1 +
 src/text.c        |  6 +++--
 src/winio.c       | 59 +++++++++++++++++++++++++++++++++++++++++++++--
 5 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/src/definitions.h b/src/definitions.h
index 6d4809ac..961a3bc9 100644
--- a/src/definitions.h
+++ b/src/definitions.h
@@ -120,6 +120,8 @@
 #define ENABLED_WRAPORJUSTIFY  1
 #endif
 
+#define MINIBAR  TRUE
+
 #define BACKWARD  FALSE
 #define FORWARD  TRUE
 
diff --git a/src/nano.c b/src/nano.c
index b47b2b8f..179c3b02 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -399,9 +399,10 @@ void window_init(void)
 		delwin(bottomwin);
 	}
 
+	topwin = NULL;
+
 	/* If the terminal is very flat, don't set up a title bar. */
 	if (LINES < 3) {
-		topwin = NULL;
 		editwinrows = 1;
 		/* Set up two subwindows.  If the terminal is just one line,
 		 * edit window and status-bar window will cover each other. */
@@ -411,10 +412,14 @@ void window_init(void)
 		int toprows = (!ISSET(EMPTY_LINE) ? 1 : (LINES < 6) ? 1 : 2);
 		int bottomrows = (ISSET(NO_HELP) ? 1 : (LINES < 5) ? 1 : 3);
 
+		if (MINIBAR)
+			toprows = 0;
+
 		editwinrows = LINES - toprows - bottomrows;
 
 		/* Set up the normal three subwindows. */
-		topwin = newwin(toprows, COLS, 0, 0);
+		if (toprows > 0)
+			topwin = newwin(toprows, COLS, 0, 0);
 		edit = newwin(editwinrows, COLS, toprows, 0);
 		bottomwin = newwin(bottomrows, COLS, toprows + editwinrows, 0);
 	}
@@ -1126,7 +1131,9 @@ void do_toggle(int flag)
 	if (flag == NO_HELP || flag == NO_SYNTAX)
 		enabled = !enabled;
 
-	statusline(HUSH, "%s %s", _(flagtostr(flag)),
+	if (!MINIBAR || flag == SMART_HOME || flag == CUT_FROM_CURSOR ||
+				flag == TABS_TO_SPACES || flag == USE_MOUSE || flag == SUSPENDABLE)
+		statusline(HUSH, "%s %s", _(flagtostr(flag)),
 						enabled ? _("enabled") : _("disabled"));
 }
 #endif /* !NANO_TINY */
@@ -2547,6 +2554,9 @@ int main(int argc, char **argv)
 		if (currmenu != MMAIN)
 			bottombars(MMAIN);
 
+		if (MINIBAR && lastmessage == VACUUM)
+			minibar();
+		else
 		/* Update the displayed current cursor position only when there
 		 * is no message and no keys are waiting in the input buffer. */
 		if (ISSET(CONSTANT_SHOW) && lastmessage == VACUUM && get_key_buffer_len() == 0)
diff --git a/src/prototypes.h b/src/prototypes.h
index d1b2ece6..0a1dee67 100644
--- a/src/prototypes.h
+++ b/src/prototypes.h
@@ -593,6 +593,7 @@ void set_blankdelay_to_one(void);
 char *display_string(const char *buf, size_t column, size_t span,
 						bool isdata, bool isprompt);
 void titlebar(const char *path);
+void minibar(void);
 void statusline(message_type importance, const char *msg, ...);
 void statusbar(const char *msg);
 void warn_and_briefly_pause(const char *msg);
diff --git a/src/text.c b/src/text.c
index 79bc026d..d98e8dfc 100644
--- a/src/text.c
+++ b/src/text.c
@@ -50,11 +50,13 @@ void do_mark(void)
 	if (!openfile->mark) {
 		openfile->mark = openfile->current;
 		openfile->mark_x = openfile->current_x;
-		statusbar(_("Mark Set"));
+		if (!MINIBAR)
+			statusbar(_("Mark Set"));
 		openfile->kind_of_mark = HARDMARK;
 	} else {
 		openfile->mark = NULL;
-		statusbar(_("Mark Unset"));
+		if (!MINIBAR)
+			statusbar(_("Mark Unset"));
 		refresh_needed = TRUE;
 	}
 }
diff --git a/src/winio.c b/src/winio.c
index 1efbef23..48f2a7d6 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -92,10 +92,12 @@ void record_macro(void)
 
 	if (recording) {
 		macro_length = 0;
-		statusbar(_("Recording a macro..."));
+		if (!MINIBAR)
+			statusbar(_("Recording a macro..."));
 	} else {
 		snip_last_keystroke();
-		statusbar(_("Stopped recording"));
+		if (!MINIBAR)
+			statusbar(_("Stopped recording"));
 	}
 
 	if (ISSET(STATEFLAGS))
@@ -2067,6 +2069,59 @@ void titlebar(const char *path)
 	wrefresh(topwin);
 }
 
+/* Draw a bar at the bottom with some minimal state information. */
+void minibar(void)
+{
+	char *thisline = openfile->current->data;
+	char *hexadecimal = nmalloc(7);
+	char *location = nmalloc(44);
+	char *thename;
+	wchar_t widecode;
+
+	/* Draw a colored bar over the full width of the screen. */
+	wattron(bottomwin, interface_color_pair[TITLE_BAR]);
+	mvwprintw(bottomwin, 0, 0, "%*s", COLS, " ");
+
+	/* Display the name of the current file, plus a star when modified. */
+	if (openfile->filename[0] != '\0') {
+		as_an_at = FALSE;
+		thename = display_string(openfile->filename, 0, COLS - 18, FALSE, FALSE);
+	} else
+		thename = copy_of(_("(nameless)"));
+	mvwaddstr(bottomwin, 0, 2, thename);
+	waddstr(bottomwin, openfile->modified ? " *" : "  ");
+
+	/* Display the line/column position of the cursor. */
+	sprintf(location, "%li,%li   ", openfile->current->lineno, xplustabs() + 1);
+	mvwaddstr(bottomwin, 0, COLS - 19 - strlen(location), location);
+
+	/* Display the state of three flags, and the state of macro and mark. */
+	waddstr(bottomwin, ISSET(AUTOINDENT) ? "I" : " ");
+	waddstr(bottomwin, recording ? "R" : " ");
+	waddstr(bottomwin, ISSET(SOFTWRAP) ? "S" : " ");
+	waddstr(bottomwin, openfile->mark ? "M" : " ");
+	waddstr(bottomwin, ISSET(BREAK_LONG_LINES) ? "L" : " ");
+
+	/* Display the hexadecimal code of the character under the cursor. */
+	if (thisline[openfile->current_x] == '\0')
+		sprintf(hexadecimal, openfile->current->next ? "U+000A" : "------");
+	else if (thisline[openfile->current_x] == '\n')
+		sprintf(hexadecimal, "U+0000");
+	else if ((unsigned char)thisline[openfile->current_x] >= 0x80 &&
+				mbtowc(&widecode, thisline + openfile->current_x, MAXCHARLEN) >= 0)
+		sprintf(hexadecimal, "U+%04X", widecode);
+	else
+		sprintf(hexadecimal, "U+%04X", (unsigned char)thisline[openfile->current_x]);
+	mvwaddstr(bottomwin, 0, COLS - 8, hexadecimal);
+
+	wattroff(bottomwin, interface_color_pair[TITLE_BAR]);
+	wrefresh(bottomwin);
+
+	free(hexadecimal);
+	free(location);
+	free(thename);
+}
+
 /* Display the given message on the status bar, but only if its importance
  * is higher than that of a message that is already there. */
 void statusline(message_type importance, const char *msg, ...)
-- 
2.25.4

