From 10cb4da2ee66d981623482f66f25ba826f55c08c Mon Sep 17 00:00:00 2001
From: Benno Schulenberg <bensberg@telfort.nl>
Date: Sat, 15 Aug 2020 17:32:31 +0200
Subject: [PATCH 2/7] display: add code for showing minimal state-information
 bar at the bottom

When activated, it suppresses the title bar, and suppresses feedback
on the status bar for toggles whose effect is obvious or whose state
is already shown in the minibar.

This addresses https://savannah.gnu.org/bugs/?58152,
and addresses https://savannah.gnu.org/bugs/?58789.
---
 src/definitions.h |  3 ++-
 src/nano.c        | 19 ++++++++++++++---
 src/prototypes.h  |  1 +
 src/winio.c       | 52 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/src/definitions.h b/src/definitions.h
index 19e1a68f..bb02b017 100644
--- a/src/definitions.h
+++ b/src/definitions.h
@@ -346,7 +346,8 @@ enum {
 	INDICATOR,
 	BOOKSTYLE,
 	STATEFLAGS,
-	USE_MAGIC
+	USE_MAGIC,
+	MINIBAR
 };
 
 /* Structure types. */
diff --git a/src/nano.c b/src/nano.c
index 4c97375a..5fc731f1 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -395,9 +395,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. */
@@ -407,10 +408,15 @@ void window_init(void)
 		int toprows = ((ISSET(EMPTY_LINE) && LINES > 5) ? 2 : 1);
 		int bottomrows = ((ISSET(NO_HELP) || LINES < 5) ? 1 : 3);
 
+#ifndef NANO_TINY
+		if (ISSET(MINIBAR) && COLS > 48)
+			toprows = 0;
+#endif
 		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);
 	}
@@ -1104,7 +1110,9 @@ void do_toggle(int flag)
 	if (flag == NO_HELP || flag == NO_SYNTAX)
 		enabled = !enabled;
 
-	statusline(HUSH, "%s %s", _(flagtostr(flag)),
+	if (!ISSET(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 */
@@ -2492,6 +2500,11 @@ int main(int argc, char **argv)
 		if (currmenu != MMAIN)
 			bottombars(MMAIN);
 
+#ifndef NANO_TINY
+		if (ISSET(MINIBAR) && COLS > 48 && lastmessage == VACUUM)
+			minibar();
+		else
+#endif
 		/* 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 f9ac3a9c..adfb81d1 100644
--- a/src/prototypes.h
+++ b/src/prototypes.h
@@ -594,6 +594,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/winio.c b/src/winio.c
index 05a6f858..fd6e532b 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -2039,6 +2039,58 @@ void titlebar(const char *path)
 	wrefresh(topwin);
 }
 
+#ifndef NANO_TINY
+/* Draw a bar at the bottom with some minimal state information. */
+void minibar(void)
+{
+	char *thisline = openfile->current->data;
+	char *hexadecimal = nmalloc(9);
+	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, "%zi,%lu", openfile->current->lineno, xplustabs() + 1);
+	mvwaddstr(bottomwin, 0, COLS - 21 - strlen(location), location);
+
+	/* 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 - 17, hexadecimal);
+
+	/* Display the state of three flags, and the state of macro and mark. */
+	wmove(bottomwin, 0, COLS - 7);
+	show_states_at(bottomwin);
+
+	wattroff(bottomwin, interface_color_pair[TITLE_BAR]);
+	wrefresh(bottomwin);
+
+	free(hexadecimal);
+	free(location);
+	free(thename);
+}
+#endif /* NANO_TINY */
+
 /* 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.29.2

