From 7e2d673b5f49879a5fa9ef07e73171b485b160df Mon Sep 17 00:00:00 2001
From: David Lawrence Ramsey <pooka109@gmail.com>
Date: Tue, 1 Nov 2005 19:32:45 +0000
Subject: [PATCH] move functions specific to the help browser to their own
 source file, help.c, and adjust related variables accordingly

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@3072 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog       |   6 +-
 po/ChangeLog    |   4 +
 po/POTFILES.in  |   1 +
 src/Makefile.am |   1 +
 src/global.c    |   8 -
 src/help.c      | 517 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/nano.c      | 323 ------------------------------
 src/proto.h     |  17 +-
 src/winio.c     | 160 ---------------
 9 files changed, 535 insertions(+), 502 deletions(-)
 create mode 100644 src/help.c

diff --git a/ChangeLog b/ChangeLog
index 8bc74c52..4eef071d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -31,6 +31,10 @@ CVS code -
 	  statusbar_xplustabs(), get_statusbar_page_start(),
 	  nanoget_repaint(), nanogetstr(), statusq(), and
 	  statusq_abort() (all moved to prompt.c). (DLR)
+	- Move functions specific to the help browser to their own
+	  source file, and adjust related variables accordingly.  New
+	  file help.c; changes to help_init(), help_line_len(), and
+	  do_help() (all moved to help.c). (DLR)
 - nano.h:
 	- Readd MIN_EDITOR_COLS #define. (DLR)
 - winio.c:
@@ -43,7 +47,7 @@ CVS code -
 	- Tweak the "c-file" regex for characters to properly accept
 	  '\"' and reject '"' and '''. (DLR)
 - src/Makefile.am:
-	- Add prompt.c to nano_SOURCES. (DLR)
+	- Add help.c and prompt.c to nano_SOURCES. (DLR)
 
 GNU nano 1.3.9 - 2005.10.23
 - General:
diff --git a/po/ChangeLog b/po/ChangeLog
index 1753789d..0e5bc418 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,7 @@
+2005-11-01  David Lawrence Ramsey  <pooka109@cox.net>
+
+	* POTFILES.in: Add help.c.
+
 2006-10-23  Jordi Mallach  <jordi@gnu.org>
 
 	* ca.po: Updated Catalan translation.
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5659c7f5..ed05a329 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -3,6 +3,7 @@
 
 src/files.c
 src/global.c
+src/help.c
 src/nano.c
 src/rcfile.c
 src/search.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 635771aa..08322aec 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,6 +9,7 @@ nano_SOURCES =	chars.c \
 		cut.c \
 		files.c \
 		global.c \
+		help.c \
 		move.c \
 		nano.c \
 		nano.h \
diff --git a/src/global.c b/src/global.c
index 00dc0192..a76c3e4a 100644
--- a/src/global.c
+++ b/src/global.c
@@ -91,10 +91,6 @@ char *answer = NULL;		/* The answer string for statusbar
 ssize_t tabsize = -1;		/* Our internal tabsize variable.  The
 				   default value is set in main(). */
 
-#ifndef DISABLE_HELP
-char *help_text;		/* The text in the help window */
-#endif
-
 #ifndef DISABLE_OPERATINGDIR
 char *operating_dir = NULL;	/* Operating directory, which we can't */
 char *full_operating_dir = NULL;/* go higher than */
@@ -1176,10 +1172,6 @@ void thanks_for_all_the_fish(void)
 #ifndef DISABLE_SPELLER
     if (alt_speller != NULL)
 	free(alt_speller);
-#endif
-#ifndef DISABLE_HELP
-    if (help_text != NULL)
-	free(help_text);
 #endif
     if (answer != NULL)
 	free(answer);
diff --git a/src/help.c b/src/help.c
new file mode 100644
index 00000000..556270f7
--- /dev/null
+++ b/src/help.c
@@ -0,0 +1,517 @@
+/* $Id$ */
+/**************************************************************************
+ *   help.c                                                               *
+ *                                                                        *
+ *   Copyright (C) 2005 Chris Allegretta                                  *
+ *   This program is free software; you can redistribute it and/or modify *
+ *   it under the terms of the GNU General Public License as published by *
+ *   the Free Software Foundation; either version 2, or (at your option)  *
+ *   any later version.                                                   *
+ *                                                                        *
+ *   This program is distributed in the hope that it will be useful, but  *
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of           *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    *
+ *   General Public License for more details.                             *
+ *                                                                        *
+ *   You should have received a copy of the GNU General Public License    *
+ *   along with this program; if not, write to the Free Software          *
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA            *
+ *   02110-1301, USA.                                                     *
+ *                                                                        *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "proto.h"
+
+#ifndef DISABLE_HELP
+
+static char *help_text = NULL;
+	/* The text displayed in the help window. */
+
+/* This function allocates help_text, and stores the help string in it. 
+ * help_text should be NULL initially. */
+void help_init(void)
+{
+    size_t allocsize = 0;	/* Space needed for help_text. */
+    const char *htx[3];		/* Untranslated help message.  We break
+				 * it up into three chunks in case the
+				 * full string is too long for the
+				 * compiler to handle. */
+    char *ptr;
+    const shortcut *s;
+#ifndef NANO_SMALL
+    const toggle *t;
+#ifdef ENABLE_NANORC
+    bool old_whitespace = ISSET(WHITESPACE_DISPLAY);
+
+    UNSET(WHITESPACE_DISPLAY);
+#endif
+#endif
+
+    /* First, set up the initial help text for the current function. */
+    if (currshortcut == whereis_list || currshortcut == replace_list ||
+	currshortcut == replace_list_2) {
+	htx[0] = N_("Search Command Help Text\n\n "
+		"Enter the words or characters you would like to "
+		"search for, and then press Enter.  If there is a "
+		"match for the text you entered, the screen will be "
+		"updated to the location of the nearest match for the "
+		"search string.\n\n The previous search string will be "
+		"shown in brackets after the search prompt.  Hitting "
+		"Enter without entering any text will perform the "
+		"previous search.  ");
+	htx[1] = N_("If you have selected text with the mark and then "
+		"search to replace, only matches in the selected text "
+		"will be replaced.\n\n The following function keys are "
+		"available in Search mode:\n\n");
+	htx[2] = NULL;
+    } else if (currshortcut == gotoline_list) {
+	htx[0] = N_("Go To Line Help Text\n\n "
+		"Enter the line number that you wish to go to and hit "
+		"Enter.  If there are fewer lines of text than the "
+		"number you entered, you will be brought to the last "
+		"line of the file.\n\n The following function keys are "
+		"available in Go To Line mode:\n\n");
+	htx[1] = NULL;
+	htx[2] = NULL;
+    } else if (currshortcut == insertfile_list) {
+	htx[0] = N_("Insert File Help Text\n\n "
+		"Type in the name of a file to be inserted into the "
+		"current file buffer at the current cursor "
+		"location.\n\n If you have compiled nano with multiple "
+		"file buffer support, and enable multiple file buffers "
+		"with the -F or --multibuffer command line flags, the "
+		"Meta-F toggle, or a nanorc file, inserting a file "
+		"will cause it to be loaded into a separate buffer "
+		"(use Meta-< and > to switch between file buffers).  ");
+	htx[1] = N_("If you need another blank buffer, do not enter "
+		"any filename, or type in a nonexistent filename at "
+		"the prompt and press Enter.\n\n The following "
+		"function keys are available in Insert File mode:\n\n");
+	htx[2] = NULL;
+    } else if (currshortcut == writefile_list) {
+	htx[0] = N_("Write File Help Text\n\n "
+		"Type the name that you wish to save the current file "
+		"as and press Enter to save the file.\n\n If you have "
+		"selected text with the mark, you will be prompted to "
+		"save only the selected portion to a separate file.  To "
+		"reduce the chance of overwriting the current file with "
+		"just a portion of it, the current filename is not the "
+		"default in this mode.\n\n The following function keys "
+		"are available in Write File mode:\n\n");
+	htx[1] = NULL;
+	htx[2] = NULL;
+    }
+#ifndef DISABLE_BROWSER
+    else if (currshortcut == browser_list) {
+	htx[0] = N_("File Browser Help Text\n\n "
+		"The file browser is used to visually browse the "
+		"directory structure to select a file for reading "
+		"or writing.  You may use the arrow keys or Page Up/"
+		"Down to browse through the files, and S or Enter to "
+		"choose the selected file or enter the selected "
+		"directory.  To move up one level, select the "
+		"directory called \"..\" at the top of the file "
+		"list.\n\n The following function keys are available "
+		"in the file browser:\n\n");
+	htx[1] = NULL;
+	htx[2] = NULL;
+    } else if (currshortcut == gotodir_list) {
+	htx[0] = N_("Browser Go To Directory Help Text\n\n "
+		"Enter the name of the directory you would like to "
+		"browse to.\n\n If tab completion has not been "
+		"disabled, you can use the Tab key to (attempt to) "
+		"automatically complete the directory name.\n\n The "
+		"following function keys are available in Browser Go "
+		"To Directory mode:\n\n");
+	htx[1] = NULL;
+	htx[2] = NULL;
+    }
+#endif
+#ifndef DISABLE_SPELLER
+    else if (currshortcut == spell_list) {
+	htx[0] = N_("Spell Check Help Text\n\n "
+		"The spell checker checks the spelling of all text in "
+		"the current file.  When an unknown word is "
+		"encountered, it is highlighted and a replacement can "
+		"be edited.  It will then prompt to replace every "
+		"instance of the given misspelled word in the current "
+		"file, or, if you have selected text with the mark, in "
+		"the selected text.\n\n The following other functions "
+		"are available in Spell Check mode:\n\n");
+	htx[1] = NULL;
+	htx[2] = NULL;
+    }
+#endif
+#ifndef NANO_SMALL
+    else if (currshortcut == extcmd_list) {
+	htx[0] = N_("Execute Command Help Text\n\n "
+		"This menu allows you to insert the output of a "
+		"command run by the shell into the current buffer (or "
+		"a new buffer in multiple file buffer mode). If you "
+		"need another blank buffer, do not enter any "
+		"command.\n\n The following keys are available in "
+		"Execute Command mode:\n\n");
+	htx[1] = NULL;
+	htx[2] = NULL;
+    }
+#endif
+    else {
+	/* Default to the main help list. */
+	htx[0] = N_(" nano help text\n\n "
+		"The nano editor is designed to emulate the "
+		"functionality and ease-of-use of the UW Pico text "
+		"editor.  There are four main sections of the editor.  "
+		"The top line shows the program version, the current "
+		"filename being edited, and whether or not the file "
+		"has been modified.  Next is the main editor window "
+		"showing the file being edited.  The status line is "
+		"the third line from the bottom and shows important "
+		"messages.  The bottom two lines show the most "
+		"commonly used shortcuts in the editor.\n\n ");
+	htx[1] = N_("The notation for shortcuts is as follows: "
+		"Control-key sequences are notated with a caret (^) "
+		"symbol and can be entered either by using the Control "
+		"(Ctrl) key or pressing the Escape (Esc) key twice.  "
+		"Escape-key sequences are notated with the Meta (M) "
+		"symbol and can be entered using either the Esc, Alt, "
+		"or Meta key depending on your keyboard setup.  ");
+	htx[2] = N_("Also, pressing Esc twice and then typing a "
+		"three-digit decimal number from 000 to 255 will enter "
+		"the character with the corresponding value.  The "
+		"following keystrokes are available in the main editor "
+		"window.  Alternative keys are shown in "
+		"parentheses:\n\n");
+    }
+
+    htx[0] = _(htx[0]);
+    if (htx[1] != NULL)
+	htx[1] = _(htx[1]);
+    if (htx[2] != NULL)
+	htx[2] = _(htx[2]);
+
+    allocsize += strlen(htx[0]);
+    if (htx[1] != NULL)
+	allocsize += strlen(htx[1]);
+    if (htx[2] != NULL)
+	allocsize += strlen(htx[2]);
+
+    /* The space needed for the shortcut lists, at most COLS characters,
+     * plus '\n'. */
+    allocsize += (COLS < 24 ? (24 * mb_cur_max()) :
+	((COLS + 1) * mb_cur_max())) * length_of_list(currshortcut);
+
+#ifndef NANO_SMALL
+    /* If we're on the main list, we also count the toggle help text.
+     * Each line has "M-%c\t\t\t", which fills 24 columns, plus a space,
+     * plus translated text, plus '\n'. */
+    if (currshortcut == main_list) {
+	size_t endis_len = strlen(_("enable/disable"));
+
+	for (t = toggles; t != NULL; t = t->next)
+	    allocsize += 8 + strlen(t->desc) + endis_len;
+    }
+#endif
+
+    /* help_text has been freed and set to NULL unless the user resized
+     * while in the help screen. */
+    if (help_text != NULL)
+	free(help_text);
+
+    /* Allocate space for the help text. */
+    help_text = charalloc(allocsize + 1);
+
+    /* Now add the text we want. */
+    strcpy(help_text, htx[0]);
+    if (htx[1] != NULL)
+	strcat(help_text, htx[1]);
+    if (htx[2] != NULL)
+	strcat(help_text, htx[2]);
+
+    ptr = help_text + strlen(help_text);
+
+    /* Now add our shortcut info.  Assume that each shortcut has, at the
+     * very least, an equivalent control key, an equivalent primary meta
+     * key sequence, or both.  Also assume that the meta key values are
+     * not control characters.  We can display a maximum of 3 shortcut
+     * entries. */
+    for (s = currshortcut; s != NULL; s = s->next) {
+	int entries = 0;
+
+	/* Control key. */
+	if (s->ctrlval != NANO_NO_KEY) {
+	    entries++;
+	    /* Yucky sentinel values that we can't handle a better
+	     * way. */
+	    if (s->ctrlval == NANO_CONTROL_SPACE) {
+		char *space_ptr = display_string(_("Space"), 0, 6,
+			FALSE);
+
+		ptr += sprintf(ptr, "^%s", space_ptr);
+
+		free(space_ptr);
+	    } else if (s->ctrlval == NANO_CONTROL_8)
+		ptr += sprintf(ptr, "^?");
+	    /* Normal values. */
+	    else
+		ptr += sprintf(ptr, "^%c", s->ctrlval + 64);
+	    *(ptr++) = '\t';
+	}
+
+	/* Function key. */
+	if (s->funcval != NANO_NO_KEY) {
+	    entries++;
+	    /* If this is the first entry, put it in the middle. */
+	    if (entries == 1) {
+		entries++;
+		*(ptr++) = '\t';
+	    }
+	    ptr += sprintf(ptr, "(F%d)", s->funcval - KEY_F0);
+	    *(ptr++) = '\t';
+	}
+
+	/* Primary meta key sequence.  If it's the first entry, don't
+	 * put parentheses around it. */
+	if (s->metaval != NANO_NO_KEY) {
+	    entries++;
+	    /* If this is the last entry, put it at the end. */
+	    if (entries == 2 && s->miscval == NANO_NO_KEY) {
+		entries++;
+		*(ptr++) = '\t';
+	    }
+	    /* Yucky sentinel values that we can't handle a better
+	     * way. */
+	    if (s->metaval == NANO_ALT_SPACE && entries == 1) {
+		char *space_ptr = display_string(_("Space"), 0, 5,
+			FALSE);
+
+		ptr += sprintf(ptr, "M-%s", space_ptr);
+
+		free(space_ptr);
+	    } else
+		/* Normal values. */
+		ptr += sprintf(ptr, (entries == 1) ? "M-%c" : "(M-%c)",
+			toupper(s->metaval));
+	    *(ptr++) = '\t';
+	}
+
+	/* Miscellaneous meta key sequence. */
+	if (entries < 3 && s->miscval != NANO_NO_KEY) {
+	    entries++;
+	    /* If this is the last entry, put it at the end. */
+	    if (entries == 2) {
+		entries++;
+		*(ptr++) = '\t';
+	    }
+	    ptr += sprintf(ptr, "(M-%c)", toupper(s->miscval));
+	    *(ptr++) = '\t';
+	}
+
+	/* Make sure all the help text starts at the same place. */
+	while (entries < 3) {
+	    entries++;
+	    *(ptr++) = '\t';
+	}
+
+	assert(s->help != NULL);
+
+	if (COLS > 24) {
+	    char *help_ptr = display_string(s->help, 0, COLS - 24,
+		FALSE);
+
+	    ptr += sprintf(ptr, help_ptr);
+
+	    free(help_ptr);
+	}
+
+	ptr += sprintf(ptr, "\n");
+    }
+
+#ifndef NANO_SMALL
+    /* And the toggles... */
+    if (currshortcut == main_list) {
+	for (t = toggles; t != NULL; t = t->next) {
+
+	    assert(t->desc != NULL);
+
+	    ptr += sprintf(ptr, "M-%c\t\t\t%s %s\n", toupper(t->val),
+		t->desc, _("enable/disable"));
+	}
+    }
+
+#ifdef ENABLE_NANORC
+    if (old_whitespace)
+	SET(WHITESPACE_DISPLAY);
+#endif
+#endif
+
+    /* If all went well, we didn't overwrite the allocated space for
+     * help_text. */
+    assert(strlen(help_text) <= allocsize + 1);
+}
+
+/* Calculate the next line of help_text, starting at ptr. */
+size_t help_line_len(const char *ptr)
+{
+    int help_cols = (COLS > 24) ? COLS - 8 : 24;
+
+    /* Try to break the line at (COLS - 8) columns if we have more than
+     * 24 columns, and at 24 columns otherwise. */
+    size_t retval = break_line(ptr, help_cols, TRUE);
+    size_t retval_save = retval;
+
+    /* Get the length of the entire line up to a null or a newline. */
+    while (*(ptr + retval) != '\0' && *(ptr + retval) != '\n')
+	retval += move_mbright(ptr + retval, 0);
+
+    /* If the entire line doesn't go more than 8 columns beyond where we
+     * tried to break it, we should display it as-is.  Otherwise, we
+     * should display it only up to the break. */
+    if (strnlenpt(ptr, retval) > help_cols + 8)
+	retval = retval_save;
+
+    return retval;
+}
+
+/* Our dynamic, shortcut-list-compliant help function. */
+void do_help(void)
+{
+    int line = 0;
+	/* The line number in help_text of the first displayed help
+	 * line.  This variable is zero-based. */
+    bool no_more = FALSE;
+	/* no_more means the end of the help text is shown, so don't go
+	 * down any more. */
+    int kbinput = ERR;
+    bool meta_key, func_key;
+
+    bool old_no_help = ISSET(NO_HELP);
+#ifndef DISABLE_MOUSE
+    const shortcut *oldshortcut = currshortcut;
+	/* We will set currshortcut to allow clicking on the help
+	 * screen's shortcut list. */
+#endif
+
+    curs_set(0);
+    blank_edit();
+    wattroff(bottomwin, A_REVERSE);
+    blank_statusbar();
+
+    /* Set help_text as the string to display. */
+    help_init();
+
+    assert(help_text != NULL);
+
+#ifndef DISABLE_MOUSE
+    /* Set currshortcut to allow clicking on the help screen's shortcut
+     * list, after help_init() is called. */
+    currshortcut = help_list;
+#endif
+
+    if (ISSET(NO_HELP)) {
+	/* Make sure that the help screen's shortcut list will actually
+	 * be displayed. */
+	UNSET(NO_HELP);
+	window_init();
+    }
+
+    bottombars(help_list);
+
+    do {
+	int i;
+	int old_line = line;
+	    /* We redisplay the help only if it moved. */
+	const char *ptr = help_text;
+
+	switch (kbinput) {
+#ifndef DISABLE_MOUSE
+	    case KEY_MOUSE:
+		{
+		    int mouse_x, mouse_y;
+		    get_mouseinput(&mouse_x, &mouse_y, TRUE);
+		}
+		break;
+#endif
+	    case NANO_PREVPAGE_KEY:
+	    case NANO_PREVPAGE_FKEY:
+		if (line > 0) {
+		    line -= editwinrows - 2;
+		    if (line < 0)
+			line = 0;
+		}
+		break;
+	    case NANO_NEXTPAGE_KEY:
+	    case NANO_NEXTPAGE_FKEY:
+		if (!no_more)
+		    line += editwinrows - 2;
+		break;
+	    case NANO_PREVLINE_KEY:
+		if (line > 0)
+		    line--;
+		break;
+	    case NANO_NEXTLINE_KEY:
+		if (!no_more)
+		    line++;
+		break;
+	}
+
+	if (kbinput == NANO_REFRESH_KEY)
+	    total_redraw();
+	else {
+	    if (line == old_line && kbinput != ERR)
+		goto skip_redisplay;
+
+	    blank_edit();
+	}
+
+	/* Calculate where in the text we should be, based on the
+	 * page. */
+	for (i = 0; i < line; i++) {
+	    ptr += help_line_len(ptr);
+	    if (*ptr == '\n')
+		ptr++;
+	}
+
+	for (i = 0; i < editwinrows && *ptr != '\0'; i++) {
+	    size_t j = help_line_len(ptr);
+
+	    mvwaddnstr(edit, i, 0, ptr, j);
+	    ptr += j;
+	    if (*ptr == '\n')
+		ptr++;
+	}
+	no_more = (*ptr == '\0');
+
+  skip_redisplay:
+	kbinput = get_kbinput(edit, &meta_key, &func_key);
+    } while (kbinput != NANO_EXIT_KEY && kbinput != NANO_EXIT_FKEY);
+
+#ifndef DISABLE_MOUSE
+    currshortcut = oldshortcut;
+#endif
+
+    if (old_no_help) {
+	blank_bottombars();
+	wnoutrefresh(bottomwin);
+	SET(NO_HELP);
+	window_init();
+    } else
+	bottombars(currshortcut);
+
+    curs_set(1);
+    edit_refresh();
+
+    /* The help_init() at the beginning allocated help_text.  Since 
+     * help_text has now been written to the screen, we don't need it
+     * anymore. */
+    free(help_text);
+    help_text = NULL;
+}
+
+#endif /* !DISABLE_HELP */
diff --git a/src/nano.c b/src/nano.c
index 803d3ed3..aaf17a12 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -678,329 +678,6 @@ void mouse_init(void)
 }
 #endif
 
-#ifndef DISABLE_HELP
-/* This function allocates help_text, and stores the help string in it. 
- * help_text should be NULL initially. */
-void help_init(void)
-{
-    size_t allocsize = 0;	/* Space needed for help_text. */
-    const char *htx[3];		/* Untranslated help message.  We break
-				 * it up into three chunks in case the
-				 * full string is too long for the
-				 * compiler to handle. */
-    char *ptr;
-    const shortcut *s;
-#ifndef NANO_SMALL
-    const toggle *t;
-#ifdef ENABLE_NANORC
-    bool old_whitespace = ISSET(WHITESPACE_DISPLAY);
-
-    UNSET(WHITESPACE_DISPLAY);
-#endif
-#endif
-
-    /* First, set up the initial help text for the current function. */
-    if (currshortcut == whereis_list || currshortcut == replace_list ||
-	currshortcut == replace_list_2) {
-	htx[0] = N_("Search Command Help Text\n\n "
-		"Enter the words or characters you would like to "
-		"search for, and then press Enter.  If there is a "
-		"match for the text you entered, the screen will be "
-		"updated to the location of the nearest match for the "
-		"search string.\n\n The previous search string will be "
-		"shown in brackets after the search prompt.  Hitting "
-		"Enter without entering any text will perform the "
-		"previous search.  ");
-	htx[1] = N_("If you have selected text with the mark and then "
-		"search to replace, only matches in the selected text "
-		"will be replaced.\n\n The following function keys are "
-		"available in Search mode:\n\n");
-	htx[2] = NULL;
-    } else if (currshortcut == gotoline_list) {
-	htx[0] = N_("Go To Line Help Text\n\n "
-		"Enter the line number that you wish to go to and hit "
-		"Enter.  If there are fewer lines of text than the "
-		"number you entered, you will be brought to the last "
-		"line of the file.\n\n The following function keys are "
-		"available in Go To Line mode:\n\n");
-	htx[1] = NULL;
-	htx[2] = NULL;
-    } else if (currshortcut == insertfile_list) {
-	htx[0] = N_("Insert File Help Text\n\n "
-		"Type in the name of a file to be inserted into the "
-		"current file buffer at the current cursor "
-		"location.\n\n If you have compiled nano with multiple "
-		"file buffer support, and enable multiple file buffers "
-		"with the -F or --multibuffer command line flags, the "
-		"Meta-F toggle, or a nanorc file, inserting a file "
-		"will cause it to be loaded into a separate buffer "
-		"(use Meta-< and > to switch between file buffers).  ");
-	htx[1] = N_("If you need another blank buffer, do not enter "
-		"any filename, or type in a nonexistent filename at "
-		"the prompt and press Enter.\n\n The following "
-		"function keys are available in Insert File mode:\n\n");
-	htx[2] = NULL;
-    } else if (currshortcut == writefile_list) {
-	htx[0] = N_("Write File Help Text\n\n "
-		"Type the name that you wish to save the current file "
-		"as and press Enter to save the file.\n\n If you have "
-		"selected text with the mark, you will be prompted to "
-		"save only the selected portion to a separate file.  To "
-		"reduce the chance of overwriting the current file with "
-		"just a portion of it, the current filename is not the "
-		"default in this mode.\n\n The following function keys "
-		"are available in Write File mode:\n\n");
-	htx[1] = NULL;
-	htx[2] = NULL;
-    }
-#ifndef DISABLE_BROWSER
-    else if (currshortcut == browser_list) {
-	htx[0] = N_("File Browser Help Text\n\n "
-		"The file browser is used to visually browse the "
-		"directory structure to select a file for reading "
-		"or writing.  You may use the arrow keys or Page Up/"
-		"Down to browse through the files, and S or Enter to "
-		"choose the selected file or enter the selected "
-		"directory.  To move up one level, select the "
-		"directory called \"..\" at the top of the file "
-		"list.\n\n The following function keys are available "
-		"in the file browser:\n\n");
-	htx[1] = NULL;
-	htx[2] = NULL;
-    } else if (currshortcut == gotodir_list) {
-	htx[0] = N_("Browser Go To Directory Help Text\n\n "
-		"Enter the name of the directory you would like to "
-		"browse to.\n\n If tab completion has not been "
-		"disabled, you can use the Tab key to (attempt to) "
-		"automatically complete the directory name.\n\n The "
-		"following function keys are available in Browser Go "
-		"To Directory mode:\n\n");
-	htx[1] = NULL;
-	htx[2] = NULL;
-    }
-#endif
-#ifndef DISABLE_SPELLER
-    else if (currshortcut == spell_list) {
-	htx[0] = N_("Spell Check Help Text\n\n "
-		"The spell checker checks the spelling of all text in "
-		"the current file.  When an unknown word is "
-		"encountered, it is highlighted and a replacement can "
-		"be edited.  It will then prompt to replace every "
-		"instance of the given misspelled word in the current "
-		"file, or, if you have selected text with the mark, in "
-		"the selected text.\n\n The following other functions "
-		"are available in Spell Check mode:\n\n");
-	htx[1] = NULL;
-	htx[2] = NULL;
-    }
-#endif
-#ifndef NANO_SMALL
-    else if (currshortcut == extcmd_list) {
-	htx[0] = N_("Execute Command Help Text\n\n "
-		"This menu allows you to insert the output of a "
-		"command run by the shell into the current buffer (or "
-		"a new buffer in multiple file buffer mode). If you "
-		"need another blank buffer, do not enter any "
-		"command.\n\n The following keys are available in "
-		"Execute Command mode:\n\n");
-	htx[1] = NULL;
-	htx[2] = NULL;
-    }
-#endif
-    else {
-	/* Default to the main help list. */
-	htx[0] = N_(" nano help text\n\n "
-		"The nano editor is designed to emulate the "
-		"functionality and ease-of-use of the UW Pico text "
-		"editor.  There are four main sections of the editor.  "
-		"The top line shows the program version, the current "
-		"filename being edited, and whether or not the file "
-		"has been modified.  Next is the main editor window "
-		"showing the file being edited.  The status line is "
-		"the third line from the bottom and shows important "
-		"messages.  The bottom two lines show the most "
-		"commonly used shortcuts in the editor.\n\n ");
-	htx[1] = N_("The notation for shortcuts is as follows: "
-		"Control-key sequences are notated with a caret (^) "
-		"symbol and can be entered either by using the Control "
-		"(Ctrl) key or pressing the Escape (Esc) key twice.  "
-		"Escape-key sequences are notated with the Meta (M) "
-		"symbol and can be entered using either the Esc, Alt, "
-		"or Meta key depending on your keyboard setup.  ");
-	htx[2] = N_("Also, pressing Esc twice and then typing a "
-		"three-digit decimal number from 000 to 255 will enter "
-		"the character with the corresponding value.  The "
-		"following keystrokes are available in the main editor "
-		"window.  Alternative keys are shown in "
-		"parentheses:\n\n");
-    }
-
-    htx[0] = _(htx[0]);
-    if (htx[1] != NULL)
-	htx[1] = _(htx[1]);
-    if (htx[2] != NULL)
-	htx[2] = _(htx[2]);
-
-    allocsize += strlen(htx[0]);
-    if (htx[1] != NULL)
-	allocsize += strlen(htx[1]);
-    if (htx[2] != NULL)
-	allocsize += strlen(htx[2]);
-
-    /* The space needed for the shortcut lists, at most COLS characters,
-     * plus '\n'. */
-    allocsize += (COLS < 24 ? (24 * mb_cur_max()) :
-	((COLS + 1) * mb_cur_max())) * length_of_list(currshortcut);
-
-#ifndef NANO_SMALL
-    /* If we're on the main list, we also count the toggle help text.
-     * Each line has "M-%c\t\t\t", which fills 24 columns, plus a space,
-     * plus translated text, plus '\n'. */
-    if (currshortcut == main_list) {
-	size_t endis_len = strlen(_("enable/disable"));
-
-	for (t = toggles; t != NULL; t = t->next)
-	    allocsize += 8 + strlen(t->desc) + endis_len;
-    }
-#endif
-
-    /* help_text has been freed and set to NULL unless the user resized
-     * while in the help screen. */
-    free(help_text);
-
-    /* Allocate space for the help text. */
-    help_text = charalloc(allocsize + 1);
-
-    /* Now add the text we want. */
-    strcpy(help_text, htx[0]);
-    if (htx[1] != NULL)
-	strcat(help_text, htx[1]);
-    if (htx[2] != NULL)
-	strcat(help_text, htx[2]);
-
-    ptr = help_text + strlen(help_text);
-
-    /* Now add our shortcut info.  Assume that each shortcut has, at the
-     * very least, an equivalent control key, an equivalent primary meta
-     * key sequence, or both.  Also assume that the meta key values are
-     * not control characters.  We can display a maximum of 3 shortcut
-     * entries. */
-    for (s = currshortcut; s != NULL; s = s->next) {
-	int entries = 0;
-
-	/* Control key. */
-	if (s->ctrlval != NANO_NO_KEY) {
-	    entries++;
-	    /* Yucky sentinel values that we can't handle a better
-	     * way. */
-	    if (s->ctrlval == NANO_CONTROL_SPACE) {
-		char *space_ptr = display_string(_("Space"), 0, 6,
-			FALSE);
-
-		ptr += sprintf(ptr, "^%s", space_ptr);
-
-		free(space_ptr);
-	    } else if (s->ctrlval == NANO_CONTROL_8)
-		ptr += sprintf(ptr, "^?");
-	    /* Normal values. */
-	    else
-		ptr += sprintf(ptr, "^%c", s->ctrlval + 64);
-	    *(ptr++) = '\t';
-	}
-
-	/* Function key. */
-	if (s->funcval != NANO_NO_KEY) {
-	    entries++;
-	    /* If this is the first entry, put it in the middle. */
-	    if (entries == 1) {
-		entries++;
-		*(ptr++) = '\t';
-	    }
-	    ptr += sprintf(ptr, "(F%d)", s->funcval - KEY_F0);
-	    *(ptr++) = '\t';
-	}
-
-	/* Primary meta key sequence.  If it's the first entry, don't
-	 * put parentheses around it. */
-	if (s->metaval != NANO_NO_KEY) {
-	    entries++;
-	    /* If this is the last entry, put it at the end. */
-	    if (entries == 2 && s->miscval == NANO_NO_KEY) {
-		entries++;
-		*(ptr++) = '\t';
-	    }
-	    /* Yucky sentinel values that we can't handle a better
-	     * way. */
-	    if (s->metaval == NANO_ALT_SPACE && entries == 1) {
-		char *space_ptr = display_string(_("Space"), 0, 5,
-			FALSE);
-
-		ptr += sprintf(ptr, "M-%s", space_ptr);
-
-		free(space_ptr);
-	    } else
-		/* Normal values. */
-		ptr += sprintf(ptr, (entries == 1) ? "M-%c" : "(M-%c)",
-			toupper(s->metaval));
-	    *(ptr++) = '\t';
-	}
-
-	/* Miscellaneous meta key sequence. */
-	if (entries < 3 && s->miscval != NANO_NO_KEY) {
-	    entries++;
-	    /* If this is the last entry, put it at the end. */
-	    if (entries == 2) {
-		entries++;
-		*(ptr++) = '\t';
-	    }
-	    ptr += sprintf(ptr, "(M-%c)", toupper(s->miscval));
-	    *(ptr++) = '\t';
-	}
-
-	/* Make sure all the help text starts at the same place. */
-	while (entries < 3) {
-	    entries++;
-	    *(ptr++) = '\t';
-	}
-
-	assert(s->help != NULL);
-
-	if (COLS > 24) {
-	    char *help_ptr = display_string(s->help, 0, COLS - 24,
-		FALSE);
-
-	    ptr += sprintf(ptr, help_ptr);
-
-	    free(help_ptr);
-	}
-
-	ptr += sprintf(ptr, "\n");
-    }
-
-#ifndef NANO_SMALL
-    /* And the toggles... */
-    if (currshortcut == main_list) {
-	for (t = toggles; t != NULL; t = t->next) {
-
-	    assert(t->desc != NULL);
-
-	    ptr += sprintf(ptr, "M-%c\t\t\t%s %s\n", toupper(t->val),
-		t->desc, _("enable/disable"));
-	}
-    }
-
-#ifdef ENABLE_NANORC
-    if (old_whitespace)
-	SET(WHITESPACE_DISPLAY);
-#endif
-#endif
-
-    /* If all went well, we didn't overwrite the allocated space for
-     * help_text. */
-    assert(strlen(help_text) <= allocsize + 1);
-}
-#endif
-
 #ifdef HAVE_GETOPT_LONG
 #define print1opt(shortflag, longflag, desc) print1opt_full(shortflag, longflag, desc)
 #else
diff --git a/src/proto.h b/src/proto.h
index 5322f3a7..6f6fbc48 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -59,9 +59,6 @@ extern char *backup_dir;
 
 extern WINDOW *topwin, *edit, *bottomwin;
 extern char *answer;
-#ifndef DISABLE_HELP
-extern char *help_text;
-#endif
 extern char *last_search;
 extern char *last_replace;
 #ifndef DISABLE_OPERATINGDIR
@@ -313,6 +310,13 @@ void free_shortcutage(shortcut **shortcutage);
 void thanks_for_all_the_fish(void);
 #endif
 
+/* Public functions in help.c. */
+#ifndef DISABLE_HELP
+void help_init(void);
+size_t help_line_len(const char *ptr);
+void do_help(void);
+#endif
+
 /* Public functions in move.c. */
 void do_first_line(void);
 void do_last_line(void);
@@ -375,9 +379,6 @@ void window_init(void);
 #ifndef DISABLE_MOUSE
 void mouse_init(void);
 #endif
-#ifndef DISABLE_HELP
-void help_init(void);
-#endif
 void print1opt_full(const char *shortflag
 #ifdef HAVE_GETOPT_LONG
 	, const char *longflag
@@ -687,10 +688,6 @@ void total_refresh(void);
 void display_main_list(void);
 void do_cursorpos(bool constant);
 void do_cursorpos_void(void);
-#ifndef DISABLE_HELP
-size_t help_line_len(const char *ptr);
-void do_help(void);
-#endif
 void do_replace_highlight(bool highlight, const char *word);
 #ifndef NDEBUG
 int check_linenumbers(const filestruct *fileptr);
diff --git a/src/winio.c b/src/winio.c
index 8151be52..84fb8d3f 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -3048,166 +3048,6 @@ void do_cursorpos_void(void)
     do_cursorpos(FALSE);
 }
 
-#ifndef DISABLE_HELP
-/* Calculate the next line of help_text, starting at ptr. */
-size_t help_line_len(const char *ptr)
-{
-    int help_cols = (COLS > 24) ? COLS - 8 : 24;
-
-    /* Try to break the line at (COLS - 8) columns if we have more than
-     * 24 columns, and at 24 columns otherwise. */
-    size_t retval = break_line(ptr, help_cols, TRUE);
-    size_t retval_save = retval;
-
-    /* Get the length of the entire line up to a null or a newline. */
-    while (*(ptr + retval) != '\0' && *(ptr + retval) != '\n')
-	retval += move_mbright(ptr + retval, 0);
-
-    /* If the entire line doesn't go more than 8 columns beyond where we
-     * tried to break it, we should display it as-is.  Otherwise, we
-     * should display it only up to the break. */
-    if (strnlenpt(ptr, retval) > help_cols + 8)
-	retval = retval_save;
-
-    return retval;
-}
-
-/* Our dynamic, shortcut-list-compliant help function. */
-void do_help(void)
-{
-    int line = 0;
-	/* The line number in help_text of the first displayed help
-	 * line.  This variable is zero-based. */
-    bool no_more = FALSE;
-	/* no_more means the end of the help text is shown, so don't go
-	 * down any more. */
-    int kbinput = ERR;
-    bool meta_key, func_key;
-
-    bool old_no_help = ISSET(NO_HELP);
-#ifndef DISABLE_MOUSE
-    const shortcut *oldshortcut = currshortcut;
-	/* We will set currshortcut to allow clicking on the help
-	 * screen's shortcut list. */
-#endif
-
-    curs_set(0);
-    blank_edit();
-    wattroff(bottomwin, A_REVERSE);
-    blank_statusbar();
-
-    /* Set help_text as the string to display. */
-    help_init();
-
-    assert(help_text != NULL);
-
-#ifndef DISABLE_MOUSE
-    /* Set currshortcut to allow clicking on the help screen's shortcut
-     * list, AFTER help_init(). */
-    currshortcut = help_list;
-#endif
-
-    if (ISSET(NO_HELP)) {
-	/* Make sure that the help screen's shortcut list will actually
-	 * be displayed. */
-	UNSET(NO_HELP);
-	window_init();
-    }
-
-    bottombars(help_list);
-
-    do {
-	int i;
-	int old_line = line;
-	    /* We redisplay the help only if it moved. */
-	const char *ptr = help_text;
-
-	switch (kbinput) {
-#ifndef DISABLE_MOUSE
-	    case KEY_MOUSE:
-		{
-		    int mouse_x, mouse_y;
-		    get_mouseinput(&mouse_x, &mouse_y, TRUE);
-		}
-		break;
-#endif
-	    case NANO_PREVPAGE_KEY:
-	    case NANO_PREVPAGE_FKEY:
-		if (line > 0) {
-		    line -= editwinrows - 2;
-		    if (line < 0)
-			line = 0;
-		}
-		break;
-	    case NANO_NEXTPAGE_KEY:
-	    case NANO_NEXTPAGE_FKEY:
-		if (!no_more)
-		    line += editwinrows - 2;
-		break;
-	    case NANO_PREVLINE_KEY:
-		if (line > 0)
-		    line--;
-		break;
-	    case NANO_NEXTLINE_KEY:
-		if (!no_more)
-		    line++;
-		break;
-	}
-
-	if (kbinput == NANO_REFRESH_KEY)
-	    total_redraw();
-	else {
-	    if (line == old_line && kbinput != ERR)
-		goto skip_redisplay;
-
-	    blank_edit();
-	}
-
-	/* Calculate where in the text we should be, based on the
-	 * page. */
-	for (i = 0; i < line; i++) {
-	    ptr += help_line_len(ptr);
-	    if (*ptr == '\n')
-		ptr++;
-	}
-
-	for (i = 0; i < editwinrows && *ptr != '\0'; i++) {
-	    size_t j = help_line_len(ptr);
-
-	    mvwaddnstr(edit, i, 0, ptr, j);
-	    ptr += j;
-	    if (*ptr == '\n')
-		ptr++;
-	}
-	no_more = (*ptr == '\0');
-
-  skip_redisplay:
-	kbinput = get_kbinput(edit, &meta_key, &func_key);
-    } while (kbinput != NANO_EXIT_KEY && kbinput != NANO_EXIT_FKEY);
-
-#ifndef DISABLE_MOUSE
-    currshortcut = oldshortcut;
-#endif
-
-    if (old_no_help) {
-	blank_bottombars();
-	wnoutrefresh(bottomwin);
-	SET(NO_HELP);
-	window_init();
-    } else
-	bottombars(currshortcut);
-
-    curs_set(1);
-    edit_refresh();
-
-    /* The help_init() at the beginning allocated help_text.  Since 
-     * help_text has now been written to the screen, we don't need it
-     * anymore. */
-    free(help_text);
-    help_text = NULL;
-}
-#endif /* !DISABLE_HELP */
-
 /* Highlight the current word being replaced or spell checked.  We
  * expect word to have tabs and control characters expanded. */
 void do_replace_highlight(bool highlight, const char *word)
-- 
GitLab