2005-11-01 19:32:45 +00:00
|
|
|
/**************************************************************************
|
2016-08-29 15:10:49 +00:00
|
|
|
* help.c -- This file is part of GNU nano. *
|
2005-11-01 19:32:45 +00:00
|
|
|
* *
|
2021-01-11 13:21:03 +00:00
|
|
|
* Copyright (C) 2000-2011, 2013-2021 Free Software Foundation, Inc. *
|
2017-04-20 18:47:08 +00:00
|
|
|
* Copyright (C) 2017 Rishabh Dave *
|
2020-01-15 11:11:56 +00:00
|
|
|
* Copyright (C) 2014-2019 Benno Schulenberg *
|
2016-08-29 13:14:18 +00:00
|
|
|
* *
|
2016-08-29 15:10:49 +00:00
|
|
|
* GNU nano 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 3 of the License, *
|
|
|
|
* or (at your option) any later version. *
|
2005-11-01 19:32:45 +00:00
|
|
|
* *
|
2016-08-29 15:10:49 +00:00
|
|
|
* GNU nano 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. *
|
2005-11-01 19:32:45 +00:00
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
2016-08-29 15:10:49 +00:00
|
|
|
* along with this program. If not, see http://www.gnu.org/licenses/. *
|
2005-11-01 19:32:45 +00:00
|
|
|
* *
|
|
|
|
**************************************************************************/
|
|
|
|
|
2020-06-20 10:09:31 +00:00
|
|
|
#include "prototypes.h"
|
2005-11-01 19:32:45 +00:00
|
|
|
|
2019-10-13 16:51:15 +00:00
|
|
|
#ifdef ENABLE_HELP
|
|
|
|
|
2017-04-22 16:27:01 +00:00
|
|
|
#include <errno.h>
|
2017-08-06 11:32:44 +00:00
|
|
|
#include <string.h>
|
2005-11-01 19:32:45 +00:00
|
|
|
|
|
|
|
static char *help_text = NULL;
|
2017-12-29 18:27:33 +00:00
|
|
|
/* The text displayed in the help window. */
|
2017-05-01 10:09:41 +00:00
|
|
|
static const char *start_of_body = NULL;
|
2017-12-29 18:27:33 +00:00
|
|
|
/* The point in the help text just after the title. */
|
2015-08-16 08:43:56 +00:00
|
|
|
static char *end_of_intro = NULL;
|
2017-12-29 18:27:33 +00:00
|
|
|
/* The point in the help text where the shortcut descriptions begin. */
|
2016-12-16 12:25:42 +00:00
|
|
|
static size_t location;
|
2017-12-29 18:27:33 +00:00
|
|
|
/* The offset (in bytes) of the topleft of the shown help text. */
|
2016-12-16 12:25:42 +00:00
|
|
|
|
2020-07-05 16:58:30 +00:00
|
|
|
/* Allocate space for the help text for the current menu,
|
|
|
|
* and concatenate the different pieces of text into it. */
|
2005-11-01 19:32:45 +00:00
|
|
|
void help_init(void)
|
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
size_t allocsize = 0;
|
|
|
|
/* Space needed for help_text. */
|
|
|
|
const char *htx[3];
|
|
|
|
/* Untranslated help introduction. We break it up into three chunks
|
|
|
|
* in case the full string is too long for the compiler to handle. */
|
2019-04-03 15:11:24 +00:00
|
|
|
const funcstruct *f;
|
2019-04-03 15:34:05 +00:00
|
|
|
const keystruct *s;
|
2020-07-05 16:58:30 +00:00
|
|
|
char *ptr;
|
2017-12-29 18:27:33 +00:00
|
|
|
|
|
|
|
/* First, set up the initial help text for the current function. */
|
2021-01-05 10:49:03 +00:00
|
|
|
if (currmenu & (MWHEREIS|MREPLACE|MREPLACEWITH)) {
|
2017-12-29 18:27:33 +00:00
|
|
|
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 (currmenu == MGOTOLINE) {
|
|
|
|
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 (currmenu == MINSERTFILE) {
|
|
|
|
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 (currmenu == MWRITEFILE) {
|
|
|
|
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;
|
|
|
|
}
|
2017-05-08 17:08:23 +00:00
|
|
|
#ifdef ENABLE_BROWSER
|
2017-12-29 18:27:33 +00:00
|
|
|
else if (currmenu == MBROWSER) {
|
|
|
|
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 (currmenu == MWHEREISFILE) {
|
|
|
|
htx[0] = N_("Browser 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.\n\n");
|
|
|
|
htx[1] = N_(" The following function keys are available in "
|
|
|
|
"Browser Search mode:\n\n");
|
|
|
|
htx[2] = NULL;
|
|
|
|
} else if (currmenu == MGOTODIR) {
|
|
|
|
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;
|
|
|
|
}
|
2017-05-08 17:08:23 +00:00
|
|
|
#endif /* ENABLE_BROWSER */
|
2017-10-31 18:32:42 +00:00
|
|
|
#ifdef ENABLE_SPELLER
|
2017-12-29 18:27:33 +00:00
|
|
|
else if (currmenu == MSPELL) {
|
|
|
|
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 function keys "
|
|
|
|
"are available in Spell Check mode:\n\n");
|
|
|
|
htx[1] = NULL;
|
|
|
|
htx[2] = NULL;
|
|
|
|
}
|
2017-10-31 18:32:42 +00:00
|
|
|
#endif /* ENABLE_SPELLER */
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2020-05-22 08:04:33 +00:00
|
|
|
else if (currmenu == MEXECUTE) {
|
2017-12-29 18:27:33 +00:00
|
|
|
htx[0] = N_("Execute Command Help Text\n\n "
|
|
|
|
"This mode allows you to insert the output of a "
|
|
|
|
"command run by the shell into the current buffer (or "
|
2018-08-29 18:17:41 +00:00
|
|
|
"into a new buffer). If the command is preceded by '|' "
|
|
|
|
"(the pipe symbol), the current contents of the buffer "
|
|
|
|
"(or marked region) will be piped to the command. ");
|
2018-08-26 08:25:46 +00:00
|
|
|
htx[1] = N_("If you just need another blank buffer, do not enter any "
|
2020-05-30 17:21:44 +00:00
|
|
|
"command.\n\n You can also pick one of four tools, or cut a "
|
|
|
|
"large piece of the buffer, or put the editor to sleep.\n\n");
|
2018-08-29 18:17:41 +00:00
|
|
|
htx[2] = N_(" The following function keys are "
|
2017-12-29 18:27:33 +00:00
|
|
|
"available in Execute Command mode:\n\n");
|
2018-09-24 18:55:18 +00:00
|
|
|
} else if (currmenu == MLINTER) {
|
|
|
|
htx[0] = N_("=== Linter ===\n\n "
|
|
|
|
"In this mode, the status bar shows an error message or "
|
|
|
|
"warning, and the cursor is put at the corresponding "
|
|
|
|
"position in the file. With PageUp and PageDown you "
|
|
|
|
"can switch to earlier and later messages.\n\n");
|
|
|
|
htx[1] = N_(" The following function keys are "
|
|
|
|
"available in Linter mode:\n\n");
|
|
|
|
htx[2] = NULL;
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2006-03-25 15:23:55 +00:00
|
|
|
#endif /* !NANO_TINY */
|
2017-12-29 18:27:33 +00:00
|
|
|
else {
|
|
|
|
/* Default to the main help list. */
|
|
|
|
htx[0] = N_("Main 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. ");
|
|
|
|
htx[1] = N_("The bottom two lines show the most commonly used "
|
|
|
|
"shortcuts in the editor.\n\n Shortcuts are written as "
|
|
|
|
"follows: Control-key sequences are notated with a '^' "
|
|
|
|
"and can be entered either by using the Ctrl key or "
|
|
|
|
"pressing the Esc key twice. Meta-key sequences are "
|
|
|
|
"notated with 'M-' and can be entered using either the "
|
|
|
|
"Alt, Cmd, or Esc 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]);
|
|
|
|
|
2020-07-05 16:58:30 +00:00
|
|
|
/* Calculate the length of the descriptions of the shortcuts.
|
|
|
|
* Each entry has one or two keystrokes, which fill 17 cells,
|
|
|
|
* plus translated text, plus one or two \n's. */
|
2017-12-29 18:27:33 +00:00
|
|
|
for (f = allfuncs; f != NULL; f = f->next)
|
|
|
|
if (f->menus & currmenu)
|
2019-05-13 10:07:32 +00:00
|
|
|
allocsize += strlen(_(f->help)) + 21;
|
2005-11-01 19:32:45 +00:00
|
|
|
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
/* If we're on the main list, we also count the toggle help text.
|
2019-05-13 10:07:32 +00:00
|
|
|
* Each entry has "M-%c\t\t ", six chars which fill 17 cells, plus
|
|
|
|
* two translated texts, plus a space, plus one or two '\n's. */
|
2017-12-29 18:27:33 +00:00
|
|
|
if (currmenu == MMAIN) {
|
2019-05-13 10:07:32 +00:00
|
|
|
size_t onoff_len = strlen(_("enable/disable"));
|
2017-12-29 18:27:33 +00:00
|
|
|
|
|
|
|
for (s = sclist; s != NULL; s = s->next)
|
2021-11-08 15:16:35 +00:00
|
|
|
if (s->func == do_toggle)
|
2021-11-17 10:01:37 +00:00
|
|
|
allocsize += strlen(_(epithet_of_flag(s->toggle))) + onoff_len + 9;
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2005-11-01 19:32:45 +00:00
|
|
|
#endif
|
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Allocate memory for the help text. */
|
2020-08-30 02:57:45 +00:00
|
|
|
help_text = nmalloc(allocsize + 1);
|
2017-12-29 18:27:33 +00:00
|
|
|
|
|
|
|
/* 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]);
|
|
|
|
|
|
|
|
/* Remember this end-of-introduction, start-of-shortcuts. */
|
2019-05-13 10:07:32 +00:00
|
|
|
end_of_intro = help_text + strlen(help_text);
|
|
|
|
ptr = end_of_intro;
|
2017-12-29 18:27:33 +00:00
|
|
|
|
2019-05-13 10:07:32 +00:00
|
|
|
/* Now add the shortcuts and their descriptions. */
|
2017-12-29 18:27:33 +00:00
|
|
|
for (f = allfuncs; f != NULL; f = f->next) {
|
2018-09-17 18:35:13 +00:00
|
|
|
int tally = 0;
|
2017-12-29 18:27:33 +00:00
|
|
|
|
|
|
|
if ((f->menus & currmenu) == 0)
|
|
|
|
continue;
|
|
|
|
|
2019-05-13 10:07:32 +00:00
|
|
|
/* Show the first two shortcuts (if any) for each function. */
|
2017-12-29 18:27:33 +00:00
|
|
|
for (s = sclist; s != NULL; s = s->next) {
|
2020-06-27 08:03:07 +00:00
|
|
|
if ((s->menus & currmenu) && s->func == f->func && s->keystr[0]) {
|
2019-05-13 10:07:32 +00:00
|
|
|
/* Make the first column 7 cells wide and the second 10. */
|
2018-09-17 18:35:13 +00:00
|
|
|
if (++tally == 1) {
|
2019-05-13 09:07:21 +00:00
|
|
|
sprintf(ptr, "%s ", s->keystr);
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Unicode arrows take three bytes instead of one. */
|
2019-05-13 09:07:21 +00:00
|
|
|
ptr += (strstr(s->keystr, "\xE2") != NULL ? 9 : 7);
|
2017-12-29 18:27:33 +00:00
|
|
|
} else {
|
2019-05-13 09:07:21 +00:00
|
|
|
sprintf(ptr, "(%s) ", s->keystr);
|
|
|
|
ptr += (strstr(s->keystr, "\xE2") != NULL ? 12 : 10);
|
2017-12-29 18:27:33 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-04-22 20:10:43 +00:00
|
|
|
}
|
|
|
|
|
2018-09-17 18:35:13 +00:00
|
|
|
if (tally == 0)
|
2019-05-13 09:07:21 +00:00
|
|
|
ptr += sprintf(ptr, "\t\t ");
|
2018-09-17 18:35:13 +00:00
|
|
|
else if (tally == 1)
|
2017-12-29 18:27:33 +00:00
|
|
|
ptr += 10;
|
2005-11-01 19:32:45 +00:00
|
|
|
|
2019-05-13 10:07:32 +00:00
|
|
|
/* The shortcut's description. */
|
2017-12-29 18:27:33 +00:00
|
|
|
ptr += sprintf(ptr, "%s\n", _(f->help));
|
2006-04-22 19:45:26 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
if (f->blank_after)
|
|
|
|
ptr += sprintf(ptr, "\n");
|
|
|
|
}
|
2005-11-01 19:32:45 +00:00
|
|
|
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2017-12-29 18:27:33 +00:00
|
|
|
/* And the toggles... */
|
|
|
|
if (currmenu == MMAIN) {
|
|
|
|
int maximum = 0, counter = 0;
|
|
|
|
|
|
|
|
/* First see how many toggles there are. */
|
|
|
|
for (s = sclist; s != NULL; s = s->next)
|
|
|
|
maximum = (s->toggle && s->ordinal > maximum) ? s->ordinal : maximum;
|
|
|
|
|
|
|
|
/* Now show them in the original order. */
|
|
|
|
while (counter < maximum) {
|
|
|
|
counter++;
|
|
|
|
for (s = sclist; s != NULL; s = s->next)
|
|
|
|
if (s->toggle && s->ordinal == counter) {
|
2020-07-30 08:12:24 +00:00
|
|
|
ptr += sprintf(ptr, "%s\t\t %s %s\n", (s->menus & MMAIN ? s->keystr : ""),
|
2021-11-17 10:01:37 +00:00
|
|
|
_(epithet_of_flag(s->toggle)), _("enable/disable"));
|
2021-10-31 09:50:02 +00:00
|
|
|
/* Add a blank like between two groups. */
|
|
|
|
if (s->toggle == NO_SYNTAX)
|
2017-12-29 18:27:33 +00:00
|
|
|
ptr += sprintf(ptr, "\n");
|
|
|
|
break;
|
|
|
|
}
|
2015-07-06 19:17:27 +00:00
|
|
|
}
|
2014-04-22 20:26:58 +00:00
|
|
|
}
|
2021-06-16 09:19:23 +00:00
|
|
|
#endif
|
2005-11-01 19:32:45 +00:00
|
|
|
}
|
2020-07-05 16:58:30 +00:00
|
|
|
|
|
|
|
/* Hard-wrap the concatenated help text, and write it into a new buffer. */
|
|
|
|
void wrap_help_text_into_buffer(void)
|
|
|
|
{
|
|
|
|
size_t sum = 0;
|
|
|
|
/* Avoid overtight and overwide paragraphs in the introductory text. */
|
|
|
|
size_t wrapping_point = ((COLS < 40) ? 40 : (COLS > 74) ? 74 : COLS) - thebar;
|
|
|
|
const char *ptr = start_of_body;
|
|
|
|
|
|
|
|
make_new_buffer();
|
|
|
|
|
help: ensure there is a blank line between title bar and start of text
In olden times, each help text started with a title line in the text
window followed by a blank line. But since version 2.8.2, since the
help texts have become almost regular buffers (and thus searchable),
the title of the help text is in the title bar, and since version 4.0,
since --morespace became the default, the text will start immediately
below it. But a title line immediately followed by text, without a
blank line between them, does not look nice. So, add such a blank
line back when not using --emptyline (and also when using --minibar,
because the top of the terminal window is like a title bar).
2021-10-15 09:12:26 +00:00
|
|
|
/* Ensure there is a blank line at the top of the text, for esthetics. */
|
2021-11-17 11:21:41 +00:00
|
|
|
if ((ISSET(MINIBAR) || !ISSET(EMPTY_LINE)) && LINES > 6) {
|
help: ensure there is a blank line between title bar and start of text
In olden times, each help text started with a title line in the text
window followed by a blank line. But since version 2.8.2, since the
help texts have become almost regular buffers (and thus searchable),
the title of the help text is in the title bar, and since version 4.0,
since --morespace became the default, the text will start immediately
below it. But a title line immediately followed by text, without a
blank line between them, does not look nice. So, add such a blank
line back when not using --emptyline (and also when using --minibar,
because the top of the terminal window is like a title bar).
2021-10-15 09:12:26 +00:00
|
|
|
openfile->current->data = mallocstrcpy(openfile->current->data, " ");
|
|
|
|
openfile->current->next = make_new_node(openfile->current);
|
|
|
|
openfile->current = openfile->current->next;
|
|
|
|
}
|
|
|
|
|
2020-07-05 16:58:30 +00:00
|
|
|
/* Copy the help text into the just-created new buffer. */
|
|
|
|
while (*ptr != '\0') {
|
|
|
|
int length, shim;
|
|
|
|
char *oneline;
|
|
|
|
|
|
|
|
if (ptr == end_of_intro)
|
|
|
|
wrapping_point = ((COLS < 40) ? 40 : COLS) - thebar;
|
|
|
|
|
|
|
|
if (ptr < end_of_intro || *(ptr - 1) == '\n') {
|
|
|
|
length = break_line(ptr, wrapping_point, TRUE);
|
|
|
|
oneline = nmalloc(length + 1);
|
|
|
|
shim = (*(ptr + length - 1) == ' ') ? 0 : 1;
|
|
|
|
snprintf(oneline, length + shim, "%s", ptr);
|
|
|
|
} else {
|
|
|
|
length = break_line(ptr, ((COLS < 40) ? 22 : COLS - 18) - thebar, TRUE);
|
|
|
|
oneline = nmalloc(length + 5);
|
|
|
|
snprintf(oneline, length + 5, "\t\t %s", ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(openfile->current->data);
|
|
|
|
openfile->current->data = oneline;
|
|
|
|
|
|
|
|
ptr += length;
|
|
|
|
if (*ptr != '\n')
|
|
|
|
ptr--;
|
|
|
|
|
|
|
|
/* Create a new line, and then one more for each extra \n. */
|
|
|
|
do {
|
|
|
|
openfile->current->next = make_new_node(openfile->current);
|
|
|
|
openfile->current = openfile->current->next;
|
|
|
|
openfile->current->data = copy_of("");
|
|
|
|
} while (*(++ptr) == '\n');
|
|
|
|
}
|
|
|
|
|
|
|
|
openfile->filebot = openfile->current;
|
|
|
|
openfile->current = openfile->filetop;
|
|
|
|
|
|
|
|
remove_magicline();
|
|
|
|
#ifdef ENABLE_COLOR
|
|
|
|
find_and_prime_applicable_syntax();
|
|
|
|
#endif
|
|
|
|
prepare_for_display();
|
|
|
|
|
|
|
|
/* Move to the position in the file where we were before. */
|
|
|
|
while (TRUE) {
|
|
|
|
sum += strlen(openfile->current->data);
|
|
|
|
if (sum > location)
|
|
|
|
break;
|
|
|
|
openfile->current = openfile->current->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
openfile->edittop = openfile->current;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Assemble a help text, display it, and allow scrolling through it. */
|
|
|
|
void show_help(void)
|
|
|
|
{
|
|
|
|
int kbinput = ERR;
|
|
|
|
functionptrtype func;
|
|
|
|
/* The function of the key the user typed in. */
|
|
|
|
int oldmenu = currmenu;
|
|
|
|
/* The menu we were called from. */
|
|
|
|
#ifdef ENABLE_LINENUMBERS
|
|
|
|
int was_margin = margin;
|
|
|
|
#endif
|
|
|
|
ssize_t was_tabsize = tabsize;
|
|
|
|
#ifdef ENABLE_COLOR
|
|
|
|
char *was_syntax = syntaxstr;
|
|
|
|
#endif
|
|
|
|
char *saved_answer = (answer != NULL) ? copy_of(answer) : NULL;
|
|
|
|
/* The current answer when the user invokes help at the prompt. */
|
|
|
|
unsigned stash[sizeof(flags) / sizeof(flags[0])];
|
|
|
|
/* A storage place for the current flag settings. */
|
|
|
|
linestruct *line;
|
|
|
|
int length;
|
|
|
|
|
|
|
|
/* Save the settings of all flags. */
|
|
|
|
memcpy(stash, flags, sizeof(flags));
|
|
|
|
|
|
|
|
/* Ensure that the help screen's shortcut list can be displayed. */
|
2021-11-17 15:57:50 +00:00
|
|
|
if (ISSET(NO_HELP) || ISSET(ZERO)) {
|
2020-07-05 16:58:30 +00:00
|
|
|
UNSET(NO_HELP);
|
2021-11-17 10:36:03 +00:00
|
|
|
UNSET(ZERO);
|
2020-07-05 16:58:30 +00:00
|
|
|
window_init();
|
|
|
|
} else
|
|
|
|
blank_statusbar();
|
|
|
|
|
|
|
|
/* When searching, do it forward, case insensitive, and without regexes. */
|
|
|
|
UNSET(BACKWARDS_SEARCH);
|
|
|
|
UNSET(CASE_SENSITIVE);
|
|
|
|
UNSET(USE_REGEXP);
|
|
|
|
|
|
|
|
UNSET(WHITESPACE_DISPLAY);
|
|
|
|
|
|
|
|
#ifdef ENABLE_LINENUMBERS
|
|
|
|
editwincols = COLS - thebar;
|
|
|
|
margin = 0;
|
|
|
|
#endif
|
|
|
|
tabsize = 8;
|
|
|
|
#ifdef ENABLE_COLOR
|
|
|
|
syntaxstr = "nanohelp";
|
|
|
|
#endif
|
|
|
|
curs_set(0);
|
|
|
|
|
|
|
|
/* Compose the help text from all the relevant pieces. */
|
|
|
|
help_init();
|
|
|
|
|
|
|
|
inhelp = TRUE;
|
|
|
|
location = 0;
|
|
|
|
didfind = 0;
|
|
|
|
|
2020-09-13 08:24:22 +00:00
|
|
|
bottombars(MHELP);
|
|
|
|
|
2020-07-05 16:58:30 +00:00
|
|
|
/* Extract the title from the head of the help text. */
|
|
|
|
length = break_line(help_text, HIGHEST_POSITIVE, TRUE);
|
|
|
|
title = measured_copy(help_text, length);
|
|
|
|
|
|
|
|
titlebar(title);
|
|
|
|
|
|
|
|
/* Skip over the title to point at the start of the body text. */
|
|
|
|
start_of_body = help_text + length;
|
|
|
|
while (*start_of_body == '\n')
|
|
|
|
start_of_body++;
|
|
|
|
|
|
|
|
wrap_help_text_into_buffer();
|
|
|
|
edit_refresh();
|
|
|
|
|
|
|
|
while (TRUE) {
|
|
|
|
lastmessage = VACUUM;
|
|
|
|
focusing = TRUE;
|
|
|
|
|
|
|
|
/* Show the cursor when we searched and found something. */
|
|
|
|
kbinput = get_kbinput(edit, didfind == 1 || ISSET(SHOW_CURSOR));
|
2020-12-12 13:50:20 +00:00
|
|
|
|
2020-07-05 16:58:30 +00:00
|
|
|
didfind = 0;
|
|
|
|
|
|
|
|
#ifndef NANO_TINY
|
2021-01-25 15:35:07 +00:00
|
|
|
spotlighted = FALSE;
|
2021-01-11 12:22:15 +00:00
|
|
|
|
2020-07-05 16:58:30 +00:00
|
|
|
if (bracketed_paste || kbinput == BRACKETED_PASTE_MARKER) {
|
|
|
|
beep();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
func = interpret(&kbinput);
|
|
|
|
|
|
|
|
if (func == full_refresh) {
|
|
|
|
full_refresh();
|
|
|
|
} else if (ISSET(SHOW_CURSOR) && (func == do_left || func == do_right ||
|
|
|
|
func == do_up || func == do_down)) {
|
|
|
|
func();
|
|
|
|
} else if (func == do_up || func == do_scroll_up) {
|
|
|
|
do_scroll_up();
|
|
|
|
} else if (func == do_down || func == do_scroll_down) {
|
2020-09-14 16:53:19 +00:00
|
|
|
if (openfile->edittop->lineno + editwinrows - 1 < openfile->filebot->lineno)
|
2020-07-05 16:58:30 +00:00
|
|
|
do_scroll_down();
|
|
|
|
} else if (func == do_page_up || func == do_page_down ||
|
2020-09-13 08:24:22 +00:00
|
|
|
func == to_first_line || func == to_last_line) {
|
|
|
|
func();
|
2020-09-14 16:53:19 +00:00
|
|
|
} else if (func == do_search_backward || func == do_search_forward ||
|
2020-07-05 16:58:30 +00:00
|
|
|
func == do_findprevious || func == do_findnext) {
|
|
|
|
func();
|
2020-09-13 08:24:22 +00:00
|
|
|
bottombars(MHELP);
|
2020-07-05 16:58:30 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
|
|
|
} else if (func == (functionptrtype)implant) {
|
|
|
|
implant(first_sc_for(MHELP, func)->expansion);
|
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_MOUSE
|
|
|
|
} else if (kbinput == KEY_MOUSE) {
|
|
|
|
int dummy_row, dummy_col;
|
|
|
|
get_mouseinput(&dummy_row, &dummy_col, TRUE);
|
|
|
|
#endif
|
|
|
|
#ifndef NANO_TINY
|
|
|
|
} else if (kbinput == KEY_WINCH) {
|
|
|
|
; /* Nothing to do. */
|
|
|
|
#endif
|
|
|
|
} else if (func == do_exit) {
|
|
|
|
break;
|
|
|
|
} else
|
|
|
|
unbound_key(kbinput);
|
|
|
|
|
|
|
|
edit_refresh();
|
|
|
|
|
|
|
|
location = 0;
|
|
|
|
line = openfile->filetop;
|
|
|
|
|
|
|
|
/* Count how far (in bytes) edittop is into the file. */
|
|
|
|
while (line != openfile->edittop) {
|
|
|
|
location += strlen(line->data);
|
|
|
|
line = line->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Discard the help-text buffer. */
|
|
|
|
close_buffer();
|
|
|
|
|
|
|
|
/* Restore the settings of all flags. */
|
|
|
|
memcpy(flags, stash, sizeof(flags));
|
|
|
|
|
|
|
|
#ifdef ENABLE_LINENUMBERS
|
|
|
|
margin = was_margin;
|
|
|
|
editwincols = COLS - margin - thebar;
|
|
|
|
#endif
|
|
|
|
tabsize = was_tabsize;
|
|
|
|
#ifdef ENABLE_COLOR
|
|
|
|
syntaxstr = was_syntax;
|
|
|
|
have_palette = FALSE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
free(title);
|
|
|
|
title = NULL;
|
|
|
|
free(answer);
|
|
|
|
answer = saved_answer;
|
|
|
|
free(help_text);
|
|
|
|
inhelp = FALSE;
|
|
|
|
|
|
|
|
curs_set(0);
|
|
|
|
|
2021-11-17 15:38:30 +00:00
|
|
|
if (ISSET(NO_HELP) || ISSET(ZERO))
|
2020-07-05 16:58:30 +00:00
|
|
|
window_init();
|
2021-11-17 15:38:30 +00:00
|
|
|
else
|
2020-07-05 16:58:30 +00:00
|
|
|
blank_statusbar();
|
2021-11-17 15:38:30 +00:00
|
|
|
|
|
|
|
bottombars(oldmenu);
|
2020-07-05 16:58:30 +00:00
|
|
|
|
|
|
|
#ifdef ENABLE_BROWSER
|
2021-01-05 10:49:03 +00:00
|
|
|
if (oldmenu & (MBROWSER|MWHEREISFILE|MGOTODIR))
|
2020-07-05 16:58:30 +00:00
|
|
|
browser_refresh();
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
titlebar(NULL);
|
|
|
|
edit_refresh();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-25 15:51:45 +00:00
|
|
|
#endif /* ENABLE_HELP */
|
2008-08-30 21:00:00 +00:00
|
|
|
|
2019-12-15 18:40:22 +00:00
|
|
|
/* Start the help viewer, or indicate that there is no help. */
|
2019-12-15 18:47:05 +00:00
|
|
|
void do_help(void)
|
2008-08-30 21:00:00 +00:00
|
|
|
{
|
2017-04-25 15:51:45 +00:00
|
|
|
#ifdef ENABLE_HELP
|
2019-12-15 18:40:22 +00:00
|
|
|
show_help();
|
2008-08-30 21:00:00 +00:00
|
|
|
#else
|
2021-01-05 10:49:03 +00:00
|
|
|
if (currmenu & (MMAIN|MBROWSER))
|
2020-09-18 13:32:09 +00:00
|
|
|
statusbar(_("^W = Ctrl+W M-W = Alt+W"));
|
2017-12-29 18:27:33 +00:00
|
|
|
else
|
|
|
|
beep();
|
2017-04-25 15:51:45 +00:00
|
|
|
#endif
|
2008-08-30 21:00:00 +00:00
|
|
|
}
|