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
|
|
|
* *
|
2019-02-24 18:32:17 +00:00
|
|
|
* Copyright (C) 2000-2011, 2013-2019 Free Software Foundation, Inc. *
|
2017-04-20 18:47:08 +00:00
|
|
|
* Copyright (C) 2017 Rishabh Dave *
|
2019-03-10 15:29:57 +00:00
|
|
|
* Copyright (C) 2014-2018 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
|
|
|
* *
|
|
|
|
**************************************************************************/
|
|
|
|
|
2005-12-08 02:47:10 +00:00
|
|
|
#include "proto.h"
|
2005-11-01 19:32:45 +00:00
|
|
|
|
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
|
|
|
|
2017-04-25 15:51:45 +00:00
|
|
|
#ifdef ENABLE_HELP
|
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. */
|
2005-11-01 19:32:45 +00:00
|
|
|
|
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. */
|
2016-12-19 10:16:42 +00:00
|
|
|
|
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. */
|
2015-08-16 08:43:56 +00:00
|
|
|
|
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
|
|
|
|
2019-05-28 17:51:56 +00:00
|
|
|
/* Hard-wrap the concatenated help text, and write it into a new buffer. */
|
2019-09-30 17:01:04 +00:00
|
|
|
void wrap_help_text_into_buffer(void)
|
2017-04-22 16:27:01 +00:00
|
|
|
{
|
2018-03-22 18:32:17 +00:00
|
|
|
size_t sum = 0;
|
2017-12-29 18:27:33 +00:00
|
|
|
const char *ptr = start_of_body;
|
|
|
|
|
2019-05-28 17:51:56 +00:00
|
|
|
make_new_buffer();
|
|
|
|
|
|
|
|
/* Copy the help text into the just-created new buffer. */
|
2017-12-29 18:27:33 +00:00
|
|
|
while (*ptr != '\0') {
|
|
|
|
int length = help_line_len(ptr);
|
2019-05-28 17:51:56 +00:00
|
|
|
char *oneline = nmalloc(length + 1);
|
2017-04-22 16:27:01 +00:00
|
|
|
|
2019-05-28 17:51:56 +00:00
|
|
|
snprintf(oneline, length + 1, "%s", ptr);
|
|
|
|
free(openfile->current->data);
|
|
|
|
openfile->current->data = oneline;
|
2017-05-01 11:22:37 +00:00
|
|
|
|
2019-05-28 17:51:56 +00:00
|
|
|
ptr += length;
|
2017-12-29 18:27:33 +00:00
|
|
|
if (*ptr != '\n')
|
2019-05-28 17:51:56 +00:00
|
|
|
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;
|
2019-10-13 10:24:27 +00:00
|
|
|
openfile->current->data = copy_of("");
|
2019-05-28 17:51:56 +00:00
|
|
|
} while (*(++ptr) == '\n');
|
2017-12-29 18:27:33 +00:00
|
|
|
}
|
2016-12-19 10:16:42 +00:00
|
|
|
|
2019-05-28 17:51:56 +00:00
|
|
|
openfile->filebot = openfile->current;
|
|
|
|
openfile->current = openfile->filetop;
|
2017-04-22 16:27:01 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
remove_magicline();
|
2019-05-28 17:51:56 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
|
|
|
color_update();
|
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
prepare_for_display();
|
2016-12-16 12:25:42 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Move to the position in the file where we were before. */
|
|
|
|
while (TRUE) {
|
|
|
|
sum += strlen(openfile->current->data);
|
|
|
|
if (sum > location)
|
2017-12-29 20:35:14 +00:00
|
|
|
break;
|
2017-12-29 18:27:33 +00:00
|
|
|
openfile->current = openfile->current->next;
|
|
|
|
}
|
2016-12-16 12:25:42 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
openfile->edittop = openfile->current;
|
2017-04-22 16:27:01 +00:00
|
|
|
}
|
|
|
|
|
2015-08-16 09:28:33 +00:00
|
|
|
/* Our main help-viewer function. */
|
|
|
|
void do_help(void)
|
2005-11-01 23:00:56 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
int kbinput = ERR;
|
|
|
|
functionptrtype func;
|
|
|
|
/* The function of the key the user typed in. */
|
|
|
|
int oldmenu = currmenu;
|
|
|
|
/* The menu we were called from. */
|
2017-05-01 10:09:41 +00:00
|
|
|
#ifdef ENABLE_LINENUMBERS
|
2017-12-29 18:27:33 +00:00
|
|
|
int was_margin = margin;
|
2017-05-01 10:09:41 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
ssize_t was_tabsize = tabsize;
|
2017-11-01 18:45:33 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2017-12-29 18:27:33 +00:00
|
|
|
char *was_syntax = syntaxstr;
|
2017-04-25 11:41:35 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
char *saved_answer = (answer != NULL) ? strdup(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. */
|
2019-03-21 16:08:52 +00:00
|
|
|
linestruct *line;
|
2017-12-29 18:27:33 +00:00
|
|
|
int length;
|
|
|
|
|
|
|
|
blank_statusbar();
|
|
|
|
|
|
|
|
/* Save the settings of all flags. */
|
|
|
|
memcpy(stash, flags, sizeof(flags));
|
|
|
|
|
|
|
|
/* Ensure that the help screen's shortcut list can be displayed. */
|
|
|
|
if (ISSET(NO_HELP) && LINES > 4) {
|
|
|
|
UNSET(NO_HELP);
|
|
|
|
window_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* When searching, do it forward, case insensitive, and without regexes. */
|
|
|
|
UNSET(BACKWARDS_SEARCH);
|
|
|
|
UNSET(CASE_SENSITIVE);
|
|
|
|
UNSET(USE_REGEXP);
|
|
|
|
|
|
|
|
UNSET(WHITESPACE_DISPLAY);
|
|
|
|
UNSET(NOREAD_MODE);
|
2005-11-01 23:00:56 +00:00
|
|
|
|
2017-04-22 16:27:01 +00:00
|
|
|
#ifdef ENABLE_LINENUMBERS
|
2017-12-29 18:27:33 +00:00
|
|
|
UNSET(LINE_NUMBERS);
|
2018-03-09 11:03:48 +00:00
|
|
|
editwincols = COLS;
|
2017-12-29 18:27:33 +00:00
|
|
|
margin = 0;
|
2017-04-22 16:27:01 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
tabsize = 8;
|
2017-11-01 18:45:33 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2017-12-29 18:27:33 +00:00
|
|
|
syntaxstr = "nanohelp";
|
2017-05-01 15:52:45 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
curs_set(0);
|
2017-05-01 10:09:41 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Compose the help text from all the pieces. */
|
|
|
|
help_init();
|
|
|
|
inhelp = TRUE;
|
|
|
|
location = 0;
|
|
|
|
didfind = 0;
|
2016-12-19 10:16:42 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
bottombars(MHELP);
|
2017-04-22 16:27:01 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Extract the title from the head of the help text. */
|
|
|
|
length = break_line(help_text, MAX_BUF_SIZE, TRUE);
|
|
|
|
title = charalloc(length * sizeof(char) + 1);
|
|
|
|
strncpy(title, help_text, length);
|
|
|
|
title[length] = '\0';
|
2017-04-22 16:27:01 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
titlebar(title);
|
2006-07-05 01:10:18 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* 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++;
|
2016-04-30 15:31:43 +00:00
|
|
|
|
2019-05-29 10:44:23 +00:00
|
|
|
wrap_help_text_into_buffer();
|
2017-12-29 18:27:33 +00:00
|
|
|
edit_refresh();
|
2005-11-01 23:00:56 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
while (TRUE) {
|
|
|
|
lastmessage = HUSH;
|
|
|
|
focusing = TRUE;
|
|
|
|
|
|
|
|
/* Show the cursor when we searched and found something. */
|
2018-10-02 17:59:59 +00:00
|
|
|
kbinput = get_kbinput(edit, didfind == 1 || ISSET(SHOW_CURSOR));
|
2017-12-29 18:27:33 +00:00
|
|
|
didfind = 0;
|
|
|
|
|
|
|
|
func = parse_help_input(&kbinput);
|
|
|
|
|
|
|
|
if (func == total_refresh) {
|
|
|
|
total_redraw();
|
2018-10-02 17:59:59 +00:00
|
|
|
} else if (ISSET(SHOW_CURSOR) && (func == do_left || func == do_right ||
|
|
|
|
func == do_up || func == do_down)) {
|
|
|
|
func();
|
2018-12-17 16:05:56 +00:00
|
|
|
} else if (func == do_up || func == do_scroll_up) {
|
2018-03-12 17:28:44 +00:00
|
|
|
do_scroll_up();
|
2018-12-17 16:05:56 +00:00
|
|
|
} else if (func == do_down || func == do_scroll_down) {
|
2017-12-29 18:27:33 +00:00
|
|
|
if (openfile->edittop->lineno + editwinrows - 1 <
|
|
|
|
openfile->filebot->lineno)
|
2018-03-12 17:28:44 +00:00
|
|
|
do_scroll_down();
|
2018-10-24 15:20:30 +00:00
|
|
|
} else if (func == do_page_up || func == do_page_down ||
|
|
|
|
func == to_first_line || func == to_last_line ||
|
|
|
|
func == do_findprevious || func == do_findnext) {
|
|
|
|
func();
|
|
|
|
} else if (func == do_search_forward || func == do_search_backward) {
|
|
|
|
func();
|
2017-12-29 18:27:33 +00:00
|
|
|
bottombars(MHELP);
|
2018-03-01 09:55:04 +00:00
|
|
|
#ifdef ENABLE_NANORC
|
2018-03-18 18:17:56 +00:00
|
|
|
} else if (func == (functionptrtype)implant) {
|
2018-03-01 09:55:04 +00:00
|
|
|
implant(first_sc_for(MHELP, func)->expansion);
|
|
|
|
#endif
|
2017-05-01 18:45:07 +00:00
|
|
|
#ifdef ENABLE_MOUSE
|
2017-12-29 18:27:33 +00:00
|
|
|
} else if (kbinput == KEY_MOUSE) {
|
2018-01-27 19:00:14 +00:00
|
|
|
int dummy_row, dummy_col;
|
|
|
|
get_mouseinput(&dummy_row, &dummy_col, TRUE);
|
2019-05-30 13:00:17 +00:00
|
|
|
#endif
|
|
|
|
#ifndef NANO_TINY
|
|
|
|
} else if (kbinput == KEY_WINCH) {
|
|
|
|
; /* Nothing to do. */
|
2016-12-16 12:29:34 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
} else if (func == do_exit) {
|
|
|
|
break;
|
|
|
|
} else
|
|
|
|
unbound_key(kbinput);
|
|
|
|
|
|
|
|
currmenu = MHELP;
|
|
|
|
edit_refresh();
|
|
|
|
|
|
|
|
location = 0;
|
2019-03-21 16:23:49 +00:00
|
|
|
line = openfile->filetop;
|
2017-12-29 18:27:33 +00:00
|
|
|
|
|
|
|
/* Count how far (in bytes) edittop is into the file. */
|
|
|
|
while (line != openfile->edittop) {
|
|
|
|
location += strlen(line->data);
|
|
|
|
line = line->next;
|
|
|
|
}
|
2016-12-16 12:25:42 +00:00
|
|
|
}
|
2017-04-22 16:27:01 +00:00
|
|
|
|
2019-05-31 07:15:12 +00:00
|
|
|
/* Discard the help-text buffer. */
|
|
|
|
close_buffer();
|
2019-05-30 13:00:17 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
/* Restore the settings of all flags. */
|
|
|
|
memcpy(flags, stash, sizeof(flags));
|
2017-04-22 16:27:01 +00:00
|
|
|
|
|
|
|
#ifdef ENABLE_LINENUMBERS
|
2017-12-29 18:27:33 +00:00
|
|
|
margin = was_margin;
|
2018-03-09 11:03:48 +00:00
|
|
|
editwincols = COLS - margin;
|
2017-04-22 16:27:01 +00:00
|
|
|
#endif
|
2017-12-29 18:27:33 +00:00
|
|
|
tabsize = was_tabsize;
|
2017-11-01 18:45:33 +00:00
|
|
|
#ifdef ENABLE_COLOR
|
2017-12-29 18:27:33 +00:00
|
|
|
syntaxstr = was_syntax;
|
2019-05-31 08:18:22 +00:00
|
|
|
have_palette = FALSE;
|
2017-05-01 11:22:37 +00:00
|
|
|
#endif
|
|
|
|
|
2019-05-30 13:00:17 +00:00
|
|
|
free(title);
|
|
|
|
title = NULL;
|
|
|
|
free(answer);
|
|
|
|
answer = saved_answer;
|
|
|
|
free(help_text);
|
|
|
|
inhelp = FALSE;
|
|
|
|
|
|
|
|
curs_set(0);
|
2019-05-31 08:18:22 +00:00
|
|
|
refresh_needed = TRUE;
|
2017-04-22 16:27:01 +00:00
|
|
|
|
2017-12-29 18:27:33 +00:00
|
|
|
if (ISSET(NO_HELP)) {
|
|
|
|
currmenu = oldmenu;
|
|
|
|
window_init();
|
2019-05-31 08:18:22 +00:00
|
|
|
} else {
|
|
|
|
wipe_statusbar();
|
2017-12-29 18:27:33 +00:00
|
|
|
bottombars(oldmenu);
|
2019-05-31 08:18:22 +00:00
|
|
|
}
|
2019-05-30 14:37:16 +00:00
|
|
|
|
2017-05-08 17:08:23 +00:00
|
|
|
#ifdef ENABLE_BROWSER
|
2017-12-29 18:27:33 +00:00
|
|
|
if (oldmenu == MBROWSER || oldmenu == MWHEREISFILE || oldmenu == MGOTODIR)
|
|
|
|
browser_refresh();
|
|
|
|
else
|
2015-08-16 09:28:33 +00:00
|
|
|
#endif
|
2019-05-31 08:18:22 +00:00
|
|
|
titlebar(NULL);
|
2005-11-01 23:00:56 +00:00
|
|
|
}
|
|
|
|
|
2015-08-16 17:53:28 +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. */
|
|
|
|
char *ptr;
|
2019-04-03 15:11:24 +00:00
|
|
|
const funcstruct *f;
|
2019-04-03 15:34:05 +00:00
|
|
|
const keystruct *s;
|
2017-12-29 18:27:33 +00:00
|
|
|
|
|
|
|
/* First, set up the initial help text for the current function. */
|
|
|
|
if (currmenu == MWHEREIS || currmenu == MREPLACE || currmenu == MREPLACEWITH) {
|
|
|
|
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
|
2017-12-29 18:27:33 +00:00
|
|
|
else if (currmenu == MEXTCMD) {
|
|
|
|
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 "
|
2018-08-29 18:17:41 +00:00
|
|
|
"command.\n\n");
|
|
|
|
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]);
|
|
|
|
|
|
|
|
/* Calculate the length of the shortcut help text. Each entry has
|
2019-05-13 10:07:32 +00:00
|
|
|
* one or two keys, which fill 17 cells, plus translated text,
|
2017-12-29 18:27:33 +00:00
|
|
|
* plus one or two \n's. */
|
|
|
|
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)
|
2018-02-24 18:31:11 +00:00
|
|
|
if (s->func == do_toggle_void)
|
2019-05-13 10:07:32 +00:00
|
|
|
allocsize += strlen(_(flagtostr(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. */
|
|
|
|
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]);
|
|
|
|
|
|
|
|
/* 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) {
|
2018-09-17 18:32:48 +00:00
|
|
|
if ((s->menus & currmenu) && s->func == f->func) {
|
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) {
|
2019-05-13 09:07:21 +00:00
|
|
|
ptr += sprintf(ptr, "%s\t\t %s %s\n", (s->menus == MMAIN ? s->keystr : ""),
|
2017-12-29 18:27:33 +00:00
|
|
|
_(flagtostr(s->toggle)), _("enable/disable"));
|
|
|
|
if (s->toggle == NO_COLOR_SYNTAX || s->toggle == TABS_TO_SPACES)
|
|
|
|
ptr += sprintf(ptr, "\n");
|
|
|
|
break;
|
|
|
|
}
|
2015-07-06 19:17:27 +00:00
|
|
|
}
|
2014-04-22 20:26:58 +00:00
|
|
|
}
|
2014-05-13 20:14:01 +00:00
|
|
|
#endif /* !NANO_TINY */
|
2005-11-01 19:32:45 +00:00
|
|
|
}
|
|
|
|
|
2014-07-02 09:29:05 +00:00
|
|
|
/* Return the function that is bound to the given key, accepting certain
|
|
|
|
* plain characters too, for consistency with the file browser. */
|
|
|
|
functionptrtype parse_help_input(int *kbinput)
|
2006-04-24 23:03:21 +00:00
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
if (!meta_key) {
|
|
|
|
switch (*kbinput) {
|
2018-11-07 19:48:04 +00:00
|
|
|
case '-':
|
2017-12-29 18:27:33 +00:00
|
|
|
return do_page_up;
|
2018-11-07 19:48:04 +00:00
|
|
|
case ' ':
|
|
|
|
return do_page_down;
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'W':
|
|
|
|
case 'w':
|
|
|
|
case '/':
|
|
|
|
return do_search_forward;
|
|
|
|
case 'N':
|
|
|
|
return do_findprevious;
|
|
|
|
case 'n':
|
2018-07-29 15:43:24 +00:00
|
|
|
return do_findnext;
|
2017-12-29 18:27:33 +00:00
|
|
|
case 'E':
|
|
|
|
case 'e':
|
|
|
|
case 'Q':
|
|
|
|
case 'q':
|
|
|
|
case 'X':
|
|
|
|
case 'x':
|
|
|
|
return do_exit;
|
|
|
|
}
|
2006-04-24 23:03:21 +00:00
|
|
|
}
|
2017-12-29 18:27:33 +00:00
|
|
|
return func_from_key(kbinput);
|
2006-04-24 23:03:21 +00:00
|
|
|
}
|
|
|
|
|
2015-08-16 09:14:42 +00:00
|
|
|
/* Calculate the displayable length of the help-text line starting at ptr. */
|
2005-11-01 20:11:55 +00:00
|
|
|
size_t help_line_len(const char *ptr)
|
|
|
|
{
|
2017-12-29 18:27:33 +00:00
|
|
|
size_t wrapping_point = (COLS > 24) ? COLS - 1 : 24;
|
|
|
|
/* The target width for wrapping long lines. */
|
|
|
|
ssize_t wrap_location;
|
|
|
|
/* Actual position where the line can be wrapped. */
|
|
|
|
size_t length = 0;
|
|
|
|
/* Full length of the line, until the first newline. */
|
|
|
|
|
|
|
|
/* Avoid overwide paragraphs in the introductory text. */
|
|
|
|
if (ptr < end_of_intro && COLS > 74)
|
|
|
|
wrapping_point = 74;
|
|
|
|
|
|
|
|
wrap_location = break_line(ptr, wrapping_point, TRUE);
|
|
|
|
|
|
|
|
/* Get the length of the entire line up to a null or a newline. */
|
|
|
|
while (*(ptr + length) != '\0' && *(ptr + length) != '\n')
|
2019-06-09 17:37:56 +00:00
|
|
|
length = step_right(ptr, length);
|
2017-12-29 18:27:33 +00:00
|
|
|
|
|
|
|
/* If the entire line will just fit the screen, don't wrap it. */
|
2019-04-24 07:08:23 +00:00
|
|
|
if (wideness(ptr, length) <= wrapping_point + 1)
|
2017-12-29 18:27:33 +00:00
|
|
|
return length;
|
|
|
|
else if (wrap_location > 0)
|
|
|
|
return wrap_location;
|
|
|
|
else
|
2018-01-27 19:59:40 +00:00
|
|
|
return 1;
|
2005-11-01 20:11:55 +00:00
|
|
|
}
|
|
|
|
|
2017-04-25 15:51:45 +00:00
|
|
|
#endif /* ENABLE_HELP */
|
2008-08-30 21:00:00 +00:00
|
|
|
|
2015-08-16 09:28:33 +00:00
|
|
|
/* Start the help viewer. */
|
2008-08-30 21:00:00 +00:00
|
|
|
void do_help_void(void)
|
|
|
|
{
|
2017-04-25 15:51:45 +00:00
|
|
|
#ifdef ENABLE_HELP
|
2017-12-29 18:27:33 +00:00
|
|
|
do_help();
|
2008-08-30 21:00:00 +00:00
|
|
|
#else
|
2017-12-29 18:27:33 +00:00
|
|
|
if (currmenu == MMAIN)
|
|
|
|
say_there_is_no_help();
|
|
|
|
else
|
|
|
|
beep();
|
2017-04-25 15:51:45 +00:00
|
|
|
#endif
|
2008-08-30 21:00:00 +00:00
|
|
|
}
|