nano

nano with my custom patches
git clone git://bsandro.tech/nano
Log | Files | Refs | README | LICENSE

global.c (60939B)


      1 /**************************************************************************
      2  *   global.c  --  This file is part of GNU nano.                         *
      3  *                                                                        *
      4  *   Copyright (C) 1999-2011, 2013-2025 Free Software Foundation, Inc.    *
      5  *   Copyright (C) 2014-2022 Benno Schulenberg                            *
      6  *                                                                        *
      7  *   GNU nano is free software: you can redistribute it and/or modify     *
      8  *   it under the terms of the GNU General Public License as published    *
      9  *   by the Free Software Foundation, either version 3 of the License,    *
     10  *   or (at your option) any later version.                               *
     11  *                                                                        *
     12  *   GNU nano is distributed in the hope that it will be useful,          *
     13  *   but WITHOUT ANY WARRANTY; without even the implied warranty          *
     14  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.              *
     15  *   See the GNU General Public License for more details.                 *
     16  *                                                                        *
     17  *   You should have received a copy of the GNU General Public License    *
     18  *   along with this program.  If not, see https://gnu.org/licenses/.     *
     19  *                                                                        *
     20  **************************************************************************/
     21 
     22 #include "prototypes.h"
     23 
     24 #include <ctype.h>
     25 #include <string.h>
     26 #include <strings.h>
     27 #include <term.h>
     28 
     29 /* Global variables. */
     30 #ifndef NANO_TINY
     31 volatile sig_atomic_t the_window_resized = FALSE;
     32 		/* Set to TRUE by the handler whenever a SIGWINCH occurs. */
     33 #endif
     34 
     35 bool on_a_vt = FALSE;
     36 		/* Whether we're running on a Linux console (a VT). */
     37 bool using_utf8 = FALSE;
     38 		/* Whether we're in a UTF-8 locale. */
     39 bool shifted_metas = FALSE;
     40 		/* Whether any Sh-M-<letter> combo has been bound. */
     41 
     42 bool meta_key;
     43 		/* Whether the current keystroke is a Meta key. */
     44 bool shift_held;
     45 		/* Whether Shift was being held together with a movement key. */
     46 bool mute_modifiers = FALSE;
     47 		/* Whether to ignore modifier keys while running a macro or string bind. */
     48 
     49 bool we_are_running = FALSE;
     50 		/* Becomes TRUE as soon as all options and files have been read. */
     51 bool more_than_one = FALSE;
     52 		/* Whether more than one buffer is or has been open. */
     53 bool report_size = TRUE;
     54 		/* Whether to show the number of lines when the minibar is used. */
     55 
     56 bool ran_a_tool = FALSE;
     57 		/* Whether a tool has been run at the Execute-Command prompt. */
     58 #ifndef NANO_TINY
     59 char *foretext = NULL;
     60 		/* What was typed at the Execute prompt before invoking a tool. */
     61 #endif
     62 
     63 int final_status = 0;
     64 		/* The status value that nano returns upon exit. */
     65 
     66 bool inhelp = FALSE;
     67 		/* Whether we are in the help viewer. */
     68 char *title = NULL;
     69 		/* When not NULL: the title of the current help text. */
     70 
     71 bool refresh_needed = FALSE;
     72 		/* Did a command mangle enough of the buffer that we should
     73 		 * repaint the screen? */
     74 bool focusing = TRUE;
     75 		/* Whether an update of the edit window should center the cursor. */
     76 
     77 bool as_an_at = TRUE;
     78 		/* Whether a 0x0A byte should be shown as a ^@ instead of a ^J. */
     79 
     80 bool control_C_was_pressed = FALSE;
     81 		/* Whether Ctrl+C was pressed (when a keyboard interrupt is enabled). */
     82 
     83 message_type lastmessage = VACUUM;
     84 		/* Messages of type HUSH should not overwrite type MILD nor ALERT. */
     85 
     86 linestruct *pletion_line = NULL;
     87 		/* The line where the last completion was found, if any. */
     88 
     89 bool also_the_last = FALSE;
     90 		/* Whether indenting/commenting should include the last line of
     91 		 * the marked region. */
     92 
     93 char *answer = NULL;
     94 		/* The answer string used by the status-bar prompt. */
     95 
     96 char *last_search = NULL;
     97 		/* The last string we searched for. */
     98 int didfind = 0;
     99 		/* Whether the last search found something. */
    100 
    101 char *present_path = NULL;
    102 		/* The current browser directory when trying to do tab completion. */
    103 
    104 unsigned flags[4] = {0, 0, 0, 0};
    105 		/* Our flags array, containing the states of all global options. */
    106 
    107 int controlleft, controlright, controlup, controldown;
    108 int controlhome, controlend;
    109 #ifndef NANO_TINY
    110 int controldelete, controlshiftdelete;
    111 int shiftup, shiftdown;
    112 int shiftcontrolleft, shiftcontrolright, shiftcontrolup, shiftcontroldown;
    113 int shiftcontrolhome, shiftcontrolend;
    114 int altleft, altright, altup, altdown;
    115 int althome, altend, altpageup, altpagedown;
    116 int altinsert, altdelete;
    117 int shiftaltleft, shiftaltright, shiftaltup, shiftaltdown;
    118 #endif
    119 int mousefocusin, mousefocusout;
    120 
    121 #ifdef ENABLED_WRAPORJUSTIFY
    122 ssize_t fill = -COLUMNS_FROM_EOL;
    123 		/* The relative column where we will wrap lines. */
    124 size_t wrap_at = 0;
    125 		/* The actual column where we will wrap lines, based on fill. */
    126 #endif
    127 
    128 WINDOW *topwin = NULL;
    129 		/* The top portion of the screen, showing the version number of nano,
    130 		 * the name of the file, and whether the buffer was modified. */
    131 WINDOW *midwin = NULL;
    132 		/* The middle portion of the screen: the edit window, showing the
    133 		 * contents of the current buffer, the file we are editing. */
    134 WINDOW *footwin = NULL;
    135 		/* The bottom portion of the screen, where status-bar messages,
    136 		 * the status-bar prompt, and a list of shortcuts are shown. */
    137 int editwinrows = 0;
    138 		/* How many rows does the edit window take up? */
    139 int editwincols = -1;
    140 		/* The number of usable columns in the edit window: COLS - margin. */
    141 int margin = 0;
    142 		/* The amount of space reserved at the left for line numbers. */
    143 int sidebar = 0;
    144 		/* Becomes 1 when the indicator "scroll bar" must be shown. */
    145 #ifndef NANO_TINY
    146 int *bardata = NULL;
    147 		/* An array of characters that together depict the scrollbar. */
    148 ssize_t stripe_column = 0;
    149 		/* The column at which a vertical bar will be drawn. */
    150 int cycling_aim = 0;
    151 		/* Whether to center the line with the cursor (0), push it
    152 		 * to the top of the viewport (1), or to the bottom (2). */
    153 #endif
    154 
    155 linestruct *cutbuffer = NULL;
    156 		/* The buffer where we store cut text. */
    157 linestruct *cutbottom = NULL;
    158 		/* The last line in the cutbuffer. */
    159 bool keep_cutbuffer = FALSE;
    160 		/* Whether to add to the cutbuffer instead of clearing it first. */
    161 
    162 openfilestruct *openfile = NULL;
    163 		/* The list of all open file buffers. */
    164 #ifdef ENABLE_MULTIBUFFER
    165 openfilestruct *startfile = NULL;
    166 		/* The first open buffer. */
    167 #endif
    168 
    169 #ifndef NANO_TINY
    170 char *matchbrackets = NULL;
    171 		/* The opening and closing brackets that bracket searches can find. */
    172 char *whitespace = NULL;
    173 		/* The characters used when visibly showing tabs and spaces. */
    174 int whitelen[2];
    175 		/* The length in bytes of these characters. */
    176 #endif
    177 
    178 #ifdef ENABLE_JUSTIFY
    179 char *punct = NULL;
    180 		/* The closing punctuation that can end sentences. */
    181 char *brackets = NULL;
    182 		/* The closing brackets that can follow closing punctuation and
    183 		 * can end sentences. */
    184 char *quotestr = NULL;
    185 		/* The quoting string.  The default value is set in main(). */
    186 regex_t quotereg;
    187 		/* The compiled regular expression from the quoting string. */
    188 #endif
    189 
    190 char *word_chars = NULL;
    191 		/* Nonalphanumeric characters that also form words. */
    192 
    193 ssize_t tabsize = -1;
    194 		/* The width of a tab in spaces.  The default is set in main(). */
    195 
    196 #ifndef NANO_TINY
    197 char *backup_dir = NULL;
    198 		/* The directory where we store backup files. */
    199 #endif
    200 #ifdef ENABLE_OPERATINGDIR
    201 char *operating_dir = NULL;
    202 		/* The path to our confining "operating" directory, when given. */
    203 #endif
    204 
    205 #ifdef ENABLE_SPELLER
    206 char *alt_speller = NULL;
    207 		/* The command to use for the alternate spell checker. */
    208 #endif
    209 
    210 #ifdef ENABLE_COLOR
    211 syntaxtype *syntaxes = NULL;
    212 		/* The global list of color syntaxes. */
    213 char *syntaxstr = NULL;
    214 		/* The color syntax name specified on the command line. */
    215 bool have_palette = FALSE;
    216 		/* Whether the colors for the current syntax have been initialized. */
    217 bool rescind_colors = FALSE;
    218 		/* Becomes TRUE when NO_COLOR is set in the environment. */
    219 bool perturbed = FALSE;
    220 		/* Whether the multiline-coloring situation has changed. */
    221 bool recook = FALSE;
    222 		/* Whether the multidata should be recalculated. */
    223 #endif
    224 
    225 int currmenu = MMOST;
    226 		/* The currently active menu, initialized to a dummy value. */
    227 keystruct *sclist = NULL;
    228 		/* The start of the shortcuts list. */
    229 funcstruct *allfuncs = NULL;
    230 		/* The start of the functions list. */
    231 funcstruct *tailfunc;
    232 		/* The last function in the list. */
    233 funcstruct *exitfunc;
    234 		/* A pointer to the special Exit/Close item. */
    235 
    236 linestruct *search_history = NULL;
    237 		/* The current item in the list of strings that were searched for. */
    238 linestruct *replace_history = NULL;
    239 		/* The current item in the list of replace strings. */
    240 linestruct *execute_history = NULL;
    241 		/* The current item in the list of commands that were run with ^T. */
    242 
    243 #ifdef ENABLE_HISTORIES
    244 linestruct *searchtop = NULL;
    245 		/* The oldest item in the list of search strings. */
    246 linestruct *searchbot = NULL;
    247 		/* The empty item at the end of the list of search strings. */
    248 
    249 linestruct *replacetop = NULL;
    250 linestruct *replacebot = NULL;
    251 
    252 linestruct *executetop = NULL;
    253 linestruct *executebot = NULL;
    254 #endif
    255 
    256 regex_t search_regexp;
    257 		/* The compiled regular expression to use in searches. */
    258 regmatch_t regmatches[10];
    259 		/* The match positions for parenthetical subexpressions, 10
    260 		 * maximum, used in regular expression searches. */
    261 
    262 int hilite_attribute = A_REVERSE;
    263 		/* The curses attribute we use to highlight something. */
    264 #ifdef ENABLE_COLOR
    265 colortype* color_combo[NUMBER_OF_ELEMENTS] = {NULL};
    266 		/* The color combinations for interface elements given in the rcfile. */
    267 #endif
    268 int interface_color_pair[NUMBER_OF_ELEMENTS] = {0};
    269 		/* The processed color pairs for the interface elements. */
    270 
    271 char *homedir = NULL;
    272 		/* The user's home directory, from $HOME or /etc/passwd. */
    273 char *statedir = NULL;
    274 		/* The directory for nano's history files. */
    275 
    276 #if defined(ENABLE_NANORC) || defined(ENABLE_HISTORIES)
    277 char *startup_problem = NULL;
    278 		/* An error message (if any) about nanorc files or history files. */
    279 #endif
    280 #ifdef ENABLE_NANORC
    281 char *custom_nanorc = NULL;
    282 		/* The argument of the --rcfile option, when given. */
    283 
    284 char *commandname = NULL;
    285 		/* The name (of a function) between braces in a string bind. */
    286 keystruct *planted_shortcut = NULL;
    287 		/* The function that the above name resolves to, if any. */
    288 #endif
    289 
    290 bool spotlighted = FALSE;
    291 	/* Whether any text is spotlighted. */
    292 size_t light_from_col = 0;
    293 	/* Where the spotlighted text starts. */
    294 size_t light_to_col = 0;
    295 	/* Where the spotlighted text ends. */
    296 
    297 /* To make the functions and shortcuts lists clearer. */
    298 #define VIEW  TRUE    /* Is allowed in view mode. */
    299 #define NOVIEW  FALSE
    300 #define BLANKAFTER  TRUE    /* A blank line after this one. */
    301 #define TOGETHER  FALSE
    302 
    303 /* Empty functions, for the most part corresponding to toggles. */
    304 void case_sens_void(void)  {;}
    305 void regexp_void(void)  {;}
    306 void backwards_void(void)  {;}
    307 #ifdef ENABLE_HISTORIES
    308 void get_older_item(void)  {;}
    309 void get_newer_item(void)  {;}
    310 #endif
    311 void flip_replace(void)  {;}
    312 void flip_goto(void)  {;}
    313 #ifdef ENABLE_BROWSER
    314 void to_files(void)  {;}
    315 void goto_dir(void)  {;}
    316 #endif
    317 #ifndef NANO_TINY
    318 void do_nothing(void)  {;}
    319 void do_toggle(void)  {;}
    320 void dos_format(void)  {;}
    321 void mac_format(void)  {;}
    322 void append_it(void)  {;}
    323 void prepend_it(void)  {;}
    324 void back_it_up(void)  {;}
    325 void flip_execute(void)  {;}
    326 void flip_pipe(void)  {;}
    327 void flip_convert(void)  {;}
    328 #endif
    329 #ifdef ENABLE_MULTIBUFFER
    330 void flip_newbuffer(void)  {;}
    331 #endif
    332 void discard_buffer(void)  {;}
    333 void do_cancel(void)  {;}
    334 
    335 /* Add a function to the linked list of functions. */
    336 void add_to_funcs(void (*function)(void), int menus, const char *tag,
    337 					const char *phrase, bool blank_after)
    338 {
    339 	funcstruct *f = nmalloc(sizeof(funcstruct));
    340 
    341 	if (allfuncs == NULL)
    342 		allfuncs = f;
    343 	else
    344 		tailfunc->next = f;
    345 	tailfunc = f;
    346 
    347 	f->next = NULL;
    348 	f->func = function;
    349 	f->menus = menus;
    350 	f->tag = tag;
    351 #ifdef ENABLE_HELP
    352 	f->phrase = phrase;
    353 	f->blank_after = blank_after;
    354 #endif
    355 }
    356 
    357 /* Parse the given keystring and return the corresponding keycode,
    358  * or return -1 when the string is invalid. */
    359 int keycode_from_string(const char *keystring)
    360 {
    361 	if (keystring[0] == '^') {
    362 		if (keystring[2] == '\0') {
    363 			if (keystring[1] == '/' || keystring[1] == '-')
    364 				return 31;
    365 			if (keystring[1] <= '_')
    366 				return keystring[1] - 64;
    367 			if (keystring[1] == '`')
    368 				return 0;
    369 			else
    370 				return -1;
    371 		} else if (strcasecmp(keystring, "^Space") == 0)
    372 			return 0;
    373 		else
    374 			return -1;
    375 	} else if (keystring[0] == 'M') {
    376 		if (keystring[1] == '-' && keystring[3] == '\0') {
    377 			if ('A' <= keystring[2] && keystring[2] <= 'Z')
    378 				return (keystring[2] | 0x20);
    379 			else
    380 				return keystring[2];
    381 		}
    382 		if (strcasecmp(keystring, "M-Space") == 0)
    383 			return (int)' ';
    384 		else
    385 			return -1;
    386 #ifdef ENABLE_NANORC
    387 	} else if (strncasecmp(keystring, "Sh-M-", 5) == 0 &&
    388 				'a' <= (keystring[5] | 0x20) && (keystring[5] | 0x20) <= 'z' &&
    389 				keystring[6] == '\0') {
    390 		shifted_metas = TRUE;
    391 		return (keystring[5] & 0x5F);
    392 #endif
    393 	} else if (keystring[0] == 'F') {
    394 		int fn = atoi(&keystring[1]);
    395 		if (fn < 1 || fn > 24)
    396 			return -1;
    397 		return KEY_F0 + fn;
    398 	} else if (strcasecmp(keystring, "Ins") == 0)
    399 		return KEY_IC;
    400 	else if (strcasecmp(keystring, "Del") == 0)
    401 		return KEY_DC;
    402 	else
    403 		return -1;
    404 }
    405 
    406 #if defined(ENABLE_EXTRA) && defined(NCURSES_VERSION_PATCH)
    407 /* Report the version of ncurses that nano is linked against. */
    408 void show_curses_version(void)
    409 {
    410 	statusline(NOTICE, "ncurses-%i.%i, patch %li", NCURSES_VERSION_MAJOR,
    411 							NCURSES_VERSION_MINOR, NCURSES_VERSION_PATCH);
    412 }
    413 #endif
    414 
    415 /* Add a key combo to the linked list of shortcuts. */
    416 void add_to_sclist(int menus, const char *scstring, const int keycode,
    417 						void (*function)(void), int toggle)
    418 {
    419 	static keystruct *tailsc;
    420 #ifndef NANO_TINY
    421 	static int counter = 0;
    422 #endif
    423 	keystruct *sc = nmalloc(sizeof(keystruct));
    424 
    425 	/* Start the list, or tack on the next item. */
    426 	if (sclist == NULL)
    427 		sclist = sc;
    428 	else
    429 		tailsc->next = sc;
    430 	sc->next = NULL;
    431 
    432 	/* Fill in the data. */
    433 	sc->menus = menus;
    434 	sc->func = function;
    435 #ifndef NANO_TINY
    436 	sc->toggle = toggle;
    437 	/* When not the same toggle as the previous one, increment the ID. */
    438 	if (toggle)
    439 		sc->ordinal = (tailsc->toggle == toggle) ? counter : ++counter;
    440 #endif
    441 	sc->keystr = scstring;
    442 	sc->keycode = (keycode ? keycode : keycode_from_string(scstring));
    443 
    444 	tailsc = sc;
    445 }
    446 
    447 /* Return the first shortcut in the list of shortcuts that
    448  * matches the given function in the given menu. */
    449 const keystruct *first_sc_for(int menu, void (*function)(void))
    450 {
    451 	for (keystruct *sc = sclist; sc != NULL; sc = sc->next)
    452 		if ((sc->menus & menu) && sc->func == function && sc->keystr[0])
    453 			return sc;
    454 
    455 	return NULL;
    456 }
    457 
    458 /* Return the number of entries that can be shown in the given menu. */
    459 size_t shown_entries_for(int menu)
    460 {
    461 	funcstruct *item = allfuncs;
    462 	size_t maximum = ((COLS + 40) / 20) * 2;
    463 	size_t count = 0;
    464 
    465 	while (count < maximum && item != NULL) {
    466 		if (item->menus & menu)
    467 			count++;
    468 		item = item->next;
    469 	}
    470 
    471 	/* When --saveonexit is not used, widen the grid of the WriteOut menu. */
    472 	if (menu == MWRITEFILE && item == NULL &&
    473 						first_sc_for(menu, discard_buffer) == NULL)
    474 		count--;
    475 
    476 	return count;
    477 }
    478 
    479 /* Return the first shortcut in the current menu that matches the given input. */
    480 const keystruct *get_shortcut(const int keycode)
    481 {
    482 	/* Plain characters and upper control codes cannot be shortcuts. */
    483 	if (!meta_key && 0x20 <= keycode && keycode <= 0xFF)
    484 		return NULL;
    485 
    486 	/* Lower control codes with Meta cannot be shortcuts either. */
    487 	if (meta_key && keycode < 0x20)
    488 		return NULL;
    489 
    490 #ifdef ENABLE_NANORC
    491 	if (keycode == PLANTED_A_COMMAND)
    492 		return planted_shortcut;
    493 #endif
    494 
    495 	for (keystruct *sc = sclist; sc != NULL; sc = sc->next) {
    496 		if ((sc->menus & currmenu) && keycode == sc->keycode)
    497 			return sc;
    498 	}
    499 
    500 	return NULL;
    501 }
    502 
    503 /* Return a pointer to the function that is bound to the given key. */
    504 functionptrtype func_from_key(const int keycode)
    505 {
    506 	const keystruct *sc = get_shortcut(keycode);
    507 
    508 	return (sc) ? sc->func : NULL;
    509 }
    510 
    511 #if defined(ENABLE_BROWSER) || defined(ENABLE_HELP)
    512 /* Return the function that is bound to the given key in the file browser or
    513  * the help viewer.  Accept also certain plain characters, for compatibility
    514  * with Pico or to mimic 'less' and similar text viewers. */
    515 functionptrtype interpret(const int keycode)
    516 {
    517 	if (!meta_key && keycode < 0x7F) {
    518 		if (keycode == 'N')
    519 			return do_findprevious;
    520 		if (keycode == 'n')
    521 			return do_findnext;
    522 
    523 		switch (tolower(keycode)) {
    524 			case 'b':
    525 			case '-':
    526 				return do_page_up;
    527 			case ' ':
    528 				return do_page_down;
    529 			case 'w':
    530 			case '/':
    531 				return do_search_forward;
    532 #ifdef ENABLE_BROWSER
    533 			case 'g':
    534 				return goto_dir;
    535 #endif
    536 			case '?':
    537 				return do_help;
    538 			case 's':
    539 				return do_enter;
    540 			case 'e':
    541 			case 'q':
    542 			case 'x':
    543 				return do_exit;
    544 		}
    545 	}
    546 
    547 	return func_from_key(keycode);
    548 }
    549 #endif /* ENABLE_BROWSER || ENABLE_HELP */
    550 
    551 #if defined(NANO_TINY) && defined(ENABLE_LINENUMBERS)
    552 /* Allow toggling line numbers also in the tiny version. */
    553 void toggle_numbers(void)
    554 {
    555 	TOGGLE(LINE_NUMBERS);
    556 }
    557 #endif
    558 
    559 /* These two tags are used elsewhere too, so they are global. */
    560 /* TRANSLATORS: Try to keep the next two strings at most 10 characters. */
    561 const char *exit_tag = N_("Exit");
    562 const char *close_tag = N_("Close");
    563 
    564 /* Initialize the list of functions and the list of shortcuts. */
    565 void shortcut_init(void)
    566 {
    567 #ifdef ENABLE_HELP
    568 	/* TRANSLATORS: The next long series of strings are shortcut descriptions;
    569 	 * they are best kept shorter than 56 characters, but may be longer. */
    570 	const char *cancel_gist = N_("Cancel the current function");
    571 	const char *help_gist = N_("Display this help text");
    572 	const char *exit_gist = N_("Close the current buffer / Exit from nano");
    573 	const char *writeout_gist =
    574 		N_("Write the current buffer (or the marked region) to disk");
    575 	const char *readfile_gist =
    576 		N_("Insert another file into current buffer (or into new buffer)");
    577 	const char *whereis_gist =
    578 		N_("Search forward for a string or a regular expression");
    579 	const char *wherewas_gist =
    580 		N_("Search backward for a string or a regular expression");
    581 	const char *cut_gist =
    582 		N_("Cut current line (or marked region) and store it in cutbuffer");
    583 	const char *copy_gist =
    584 		N_("Copy current line (or marked region) and store it in cutbuffer");
    585 	const char *paste_gist =
    586 		N_("Paste the contents of cutbuffer at current cursor position");
    587 	const char *cursorpos_gist = N_("Display the position of the cursor");
    588 #ifdef ENABLE_SPELLER
    589 	const char *spell_gist = N_("Invoke the spell checker, if available");
    590 #endif
    591 	const char *replace_gist = N_("Replace a string or a regular expression");
    592 	const char *gotoline_gist = N_("Go to line and column number");
    593 #ifndef NANO_TINY
    594 	const char *bracket_gist = N_("Go to the matching bracket");
    595 	const char *mark_gist = N_("Mark text starting from the cursor position");
    596 	const char *zap_gist = N_("Throw away the current line (or marked region)");
    597 	const char *indent_gist = N_("Indent the current line (or marked lines)");
    598 	const char *unindent_gist = N_("Unindent the current line (or marked lines)");
    599 	const char *undo_gist = N_("Undo the last operation");
    600 	const char *redo_gist = N_("Redo the last undone operation");
    601 #endif
    602 	const char *back_gist = N_("Go back one character");
    603 	const char *forward_gist = N_("Go forward one character");
    604 	const char *prevword_gist = N_("Go back one word");
    605 	const char *nextword_gist = N_("Go forward one word");
    606 	const char *prevline_gist = N_("Go to previous line");
    607 	const char *nextline_gist = N_("Go to next line");
    608 	const char *home_gist = N_("Go to beginning of current line");
    609 	const char *end_gist = N_("Go to end of current line");
    610 	const char *prevblock_gist = N_("Go to previous block of text");
    611 	const char *nextblock_gist = N_("Go to next block of text");
    612 #ifdef ENABLE_JUSTIFY
    613 	const char *parabegin_gist =
    614 		N_("Go to beginning of paragraph; then of previous paragraph");
    615 	const char *paraend_gist =
    616 		N_("Go just beyond end of paragraph; then of next paragraph");
    617 #endif
    618 #ifndef NANO_TINY
    619 	const char *toprow_gist = N_("Go to first row in the viewport");
    620 	const char *bottomrow_gist = N_("Go to last row in the viewport");
    621 	const char *center_gist = N_("Center the line where the cursor is");
    622 	const char *cycle_gist = N_("Push the cursor line to the center, then top, then bottom");
    623 #endif
    624 	const char *prevpage_gist = N_("Go one screenful up");
    625 	const char *nextpage_gist = N_("Go one screenful down");
    626 	const char *firstline_gist = N_("Go to the first line of the file");
    627 	const char *lastline_gist = N_("Go to the last line of the file");
    628 #if !defined(NANO_TINY) || defined(ENABLE_HELP)
    629 	const char *scrollup_gist =
    630 		N_("Scroll up one line without moving the cursor textually");
    631 	const char *scrolldown_gist =
    632 		N_("Scroll down one line without moving the cursor textually");
    633 #endif
    634 #ifdef ENABLE_MULTIBUFFER
    635 	const char *prevfile_gist = N_("Switch to the previous file buffer");
    636 	const char *nextfile_gist = N_("Switch to the next file buffer");
    637 #endif
    638 	const char *verbatim_gist = N_("Insert the next keystroke verbatim");
    639 	const char *tab_gist = N_("Insert a tab at the cursor position (or indent marked lines)");
    640 	const char *enter_gist = N_("Insert a newline at the cursor position");
    641 	const char *delete_gist = N_("Delete the character under the cursor");
    642 	const char *backspace_gist =
    643 		N_("Delete the character to the left of the cursor");
    644 #ifndef NANO_TINY
    645 	const char *chopwordleft_gist =
    646 		N_("Delete backward from cursor to word start");
    647 	const char *chopwordright_gist =
    648 		N_("Delete forward from cursor to next word start");
    649 	const char *cuttilleof_gist =
    650 		N_("Cut from the cursor position to the end of the file");
    651 #endif
    652 #ifdef ENABLE_JUSTIFY
    653 	const char *justify_gist = N_("Justify the current paragraph");
    654 	const char *fulljustify_gist = N_("Justify the entire file");
    655 #endif
    656 #ifndef NANO_TINY
    657 	const char *wordcount_gist =
    658 		N_("Count the number of lines, words, and characters");
    659 	const char *suspend_gist = N_("Suspend the editor (return to the shell)");
    660 #endif
    661 	const char *refresh_gist = N_("Refresh (redraw) the current screen");
    662 #ifdef ENABLE_WORDCOMPLETION
    663 	const char *completion_gist = N_("Try and complete the current word");
    664 #endif
    665 #ifdef ENABLE_COMMENT
    666 	const char *comment_gist =
    667 		N_("Comment/uncomment the current line (or marked lines)");
    668 #endif
    669 	const char *savefile_gist = N_("Save file without prompting");
    670 	const char *findprev_gist = N_("Search next occurrence backward");
    671 	const char *findnext_gist = N_("Search next occurrence forward");
    672 #ifndef NANO_TINY
    673 	const char *recordmacro_gist = N_("Start/stop recording a macro");
    674 	const char *runmacro_gist = N_("Run the last recorded macro");
    675 	const char *anchor_gist = N_("Place or remove an anchor at the current line");
    676 	const char *prevanchor_gist = N_("Jump backward to the nearest anchor");
    677 	const char *nextanchor_gist = N_("Jump forward to the nearest anchor");
    678 #endif
    679 	const char *case_gist = N_("Toggle the case sensitivity of the search");
    680 	const char *reverse_gist = N_("Reverse the direction of the search");
    681 	const char *regexp_gist = N_("Toggle the use of regular expressions");
    682 #ifdef ENABLE_HISTORIES
    683 	const char *older_gist = N_("Recall the previous search/replace string");
    684 	const char *newer_gist = N_("Recall the next search/replace string");
    685 #endif
    686 #ifndef NANO_TINY
    687 	const char *dos_gist = N_("Toggle the use of DOS format");
    688 	const char *mac_gist = N_("Toggle the use of Mac format");
    689 	const char *append_gist = N_("Toggle appending");
    690 	const char *prepend_gist = N_("Toggle prepending");
    691 	const char *backup_gist = N_("Toggle backing up of the original file");
    692 	const char *execute_gist = N_("Execute a function or an external command");
    693 	const char *pipe_gist =
    694 		N_("Pipe the current buffer (or marked region) to the command");
    695 #ifdef ENABLE_HISTORIES
    696 	const char *older_command_gist = N_("Recall the previous command");
    697 	const char *newer_command_gist = N_("Recall the next command");
    698 #endif
    699 	const char *convert_gist = N_("Do not convert from DOS/Mac format");
    700 #endif
    701 #ifdef ENABLE_MULTIBUFFER
    702 	const char *newbuffer_gist = N_("Toggle the use of a new buffer");
    703 #endif
    704 	const char *discardbuffer_gist = N_("Close buffer without saving it");
    705 #ifdef ENABLE_BROWSER
    706 	const char *tofiles_gist = N_("Go to file browser");
    707 	const char *exitbrowser_gist = N_("Exit from the file browser");
    708 	const char *firstfile_gist = N_("Go to the first file in the list");
    709 	const char *lastfile_gist = N_("Go to the last file in the list");
    710 	const char *backfile_gist = N_("Go to the previous file in the list");
    711 	const char *forwardfile_gist = N_("Go to the next file in the list");
    712 #ifndef NANO_TINY
    713 	const char *browserlefthand_gist = N_("Go to lefthand column");
    714 	const char *browserrighthand_gist = N_("Go to righthand column");
    715 	const char *browsertoprow_gist = N_("Go to first row in this column");
    716 	const char *browserbottomrow_gist = N_("Go to last row in this column");
    717 #endif
    718 	const char *browserwhereis_gist = N_("Search forward for a string");
    719 	const char *browserwherewas_gist = N_("Search backward for a string");
    720 	const char *browserrefresh_gist = N_("Refresh the file list");
    721 	const char *gotodir_gist = N_("Go to directory");
    722 #endif
    723 #ifdef ENABLE_LINTER
    724 	const char *lint_gist = N_("Invoke the linter, if available");
    725 	const char *prevlint_gist = N_("Go to previous linter msg");
    726 	const char *nextlint_gist = N_("Go to next linter msg");
    727 #endif
    728 #ifdef ENABLE_FORMATTER
    729 	const char *formatter_gist =
    730 		N_("Invoke a program to format/arrange/manipulate the buffer");
    731 #endif
    732 #endif /* ENABLE_HELP */
    733 
    734 	/* If Backspace is not ^H, then ^H can be used for Help. */
    735 	char *bsp_string = tgetstr("kb", NULL);
    736 	char *help_key = (bsp_string && *bsp_string != 0x08) ? "^H" : "^N";
    737 
    738 #ifdef ENABLE_HELP
    739 #define WHENHELP(description)  description
    740 #else
    741 #define WHENHELP(description)  ""
    742 #endif
    743 
    744 	/* Start populating the different menus with functions. */
    745 #ifdef ENABLE_HELP
    746 	add_to_funcs(do_help, (MMOST | MBROWSER) & ~MFINDINHELP,
    747 			/* TRANSLATORS: Try to keep the next thirteen strings at most 10 characters. */
    748 			N_("Help"), WHENHELP(help_gist), TOGETHER);
    749 #endif
    750 
    751 	add_to_funcs(do_cancel, ((MMOST & ~MMAIN) | MYESNO),
    752 			N_("Cancel"), WHENHELP(cancel_gist), BLANKAFTER);
    753 
    754 	add_to_funcs(do_exit, MMAIN,
    755 			exit_tag, WHENHELP(exit_gist), TOGETHER);
    756 	/* Remember the entry for Exit, to be able to replace it with Close. */
    757 	exitfunc = tailfunc;
    758 
    759 #ifdef ENABLE_BROWSER
    760 	add_to_funcs(do_exit, MBROWSER,
    761 			close_tag, WHENHELP(exitbrowser_gist), TOGETHER);
    762 #endif
    763 
    764 #ifndef ENABLE_HELP
    765 	add_to_funcs(full_refresh, MMAIN|MREPLACE, "Refresh", "x", 0);
    766 #ifndef NANO_TINY
    767 	add_to_funcs(full_refresh, MINSERTFILE|MEXECUTE, "Refresh", "x", 0);
    768 #endif
    769 	add_to_funcs(flip_goto, MWHEREIS, "Go To Line", "x", 0);
    770 	add_to_funcs(flip_goto, MGOTOLINE, "Go To Text", "x", 0);
    771 #endif
    772 
    773 	add_to_funcs(do_writeout, MMAIN,
    774 			N_("Write Out"), WHENHELP(writeout_gist), TOGETHER);
    775 
    776 #ifdef ENABLE_JUSTIFY
    777 	/* In restricted mode, replace Insert with Justify, when possible;
    778 	 * otherwise, show Insert anyway, to keep the help items paired. */
    779 	if (!ISSET(RESTRICTED))
    780 #endif
    781 		add_to_funcs(do_insertfile, MMAIN,
    782 				N_("Read File"), WHENHELP(readfile_gist), BLANKAFTER);
    783 #ifdef ENABLE_JUSTIFY
    784 	else
    785 		add_to_funcs(do_justify, MMAIN,
    786 				N_("Justify"), WHENHELP(justify_gist), BLANKAFTER);
    787 #endif
    788 
    789 #ifdef ENABLE_HELP
    790 	/* The description ("x") and blank_after (0) are irrelevant,
    791 	 * because the help viewer does not have a help text. */
    792 	add_to_funcs(full_refresh, MHELP, N_("Refresh"), "x", 0);
    793 	add_to_funcs(do_exit, MHELP, close_tag, "x", 0);
    794 #endif
    795 
    796 	add_to_funcs(do_search_forward, MMAIN|MHELP,
    797 			N_("Where Is"), WHENHELP(whereis_gist), TOGETHER);
    798 
    799 	add_to_funcs(do_replace, MMAIN,
    800 			N_("Replace"), WHENHELP(replace_gist), TOGETHER);
    801 
    802 #ifdef NANO_TINY
    803 	add_to_funcs(do_search_backward, MHELP,
    804 			"Where Was", WHENHELP(wherewas_gist), TOGETHER);
    805 
    806 	add_to_funcs(do_findprevious, MMAIN|MHELP,
    807 			"Previous", WHENHELP(findprev_gist), TOGETHER);
    808 	add_to_funcs(do_findnext, MMAIN|MHELP,
    809 			"Next", WHENHELP(findnext_gist), BLANKAFTER);
    810 #endif
    811 
    812 	add_to_funcs(cut_text, MMAIN,
    813 			N_("Cut"), WHENHELP(cut_gist), TOGETHER);
    814 
    815 	add_to_funcs(paste_text, MMAIN,
    816 			N_("Paste"), WHENHELP(paste_gist), BLANKAFTER);
    817 
    818 	if (!ISSET(RESTRICTED)) {
    819 #ifndef NANO_TINY
    820 		add_to_funcs(do_execute, MMAIN,
    821 				N_("Execute"), WHENHELP(execute_gist), TOGETHER);
    822 #endif
    823 #ifdef ENABLE_JUSTIFY
    824 		add_to_funcs(do_justify, MMAIN,
    825 				N_("Justify"), WHENHELP(justify_gist), BLANKAFTER);
    826 #endif
    827 	}
    828 
    829 	add_to_funcs(report_cursor_position, MMAIN,
    830 			/* TRANSLATORS: This refers to the position of the cursor. */
    831 			N_("Location"), WHENHELP(cursorpos_gist), TOGETHER);
    832 
    833 #if defined(NANO_TINY) || defined(ENABLE_JUSTIFY)
    834 	/* Conditionally placing this one here or further on, to keep the
    835 	 * help items nicely paired in most conditions. */
    836 	add_to_funcs(do_gotolinecolumn, MMAIN,
    837 			N_("Go To Line"), WHENHELP(gotoline_gist), BLANKAFTER);
    838 #endif
    839 
    840 #ifndef NANO_TINY
    841 	add_to_funcs(do_undo, MMAIN,
    842 			/* TRANSLATORS: Try to keep the next ten strings at most 12 characters. */
    843 			N_("Undo"), WHENHELP(undo_gist), TOGETHER);
    844 	add_to_funcs(do_redo, MMAIN,
    845 			N_("Redo"), WHENHELP(redo_gist), BLANKAFTER);
    846 
    847 	add_to_funcs(do_mark, MMAIN,
    848 			N_("Set Mark"), WHENHELP(mark_gist), TOGETHER);
    849 	add_to_funcs(copy_text, MMAIN,
    850 			N_("Copy"), WHENHELP(copy_gist), BLANKAFTER);
    851 #endif
    852 
    853 	add_to_funcs(case_sens_void, MWHEREIS|MREPLACE,
    854 			N_("Case Sens"), WHENHELP(case_gist), TOGETHER);
    855 	add_to_funcs(regexp_void, MWHEREIS|MREPLACE,
    856 			N_("Reg.exp."), WHENHELP(regexp_gist), TOGETHER);
    857 	add_to_funcs(backwards_void, MWHEREIS|MREPLACE,
    858 			N_("Backwards"), WHENHELP(reverse_gist), BLANKAFTER);
    859 
    860 	add_to_funcs(flip_replace, MWHEREIS,
    861 			N_("Replace"), WHENHELP(replace_gist), BLANKAFTER);
    862 	add_to_funcs(flip_replace, MREPLACE,
    863 			N_("No Replace"), WHENHELP(whereis_gist), BLANKAFTER);
    864 
    865 #ifdef ENABLE_HISTORIES
    866 	add_to_funcs(get_older_item, MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE,
    867 			N_("Older"), WHENHELP(older_gist), TOGETHER);
    868 	add_to_funcs(get_newer_item, MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE,
    869 			N_("Newer"), WHENHELP(newer_gist), BLANKAFTER);
    870 #ifndef NANO_TINY
    871 	add_to_funcs(get_older_item, MEXECUTE,
    872 			N_("Older"), WHENHELP(older_command_gist), TOGETHER);
    873 	add_to_funcs(get_newer_item, MEXECUTE,
    874 			N_("Newer"), WHENHELP(newer_command_gist), BLANKAFTER);
    875 #endif
    876 #endif
    877 
    878 #ifdef ENABLE_BROWSER
    879 	add_to_funcs(goto_dir, MBROWSER,
    880 			/* TRANSLATORS: Try to keep the next four strings at most 10 characters. */
    881 			N_("Go To Dir"), WHENHELP(gotodir_gist), TOGETHER);
    882 #ifdef ENABLE_HELP
    883 	add_to_funcs(full_refresh, MBROWSER,
    884 			N_("Refresh"), WHENHELP(browserrefresh_gist), BLANKAFTER);
    885 #endif
    886 	add_to_funcs(do_search_forward, MBROWSER,
    887 			N_("Where Is"), WHENHELP(browserwhereis_gist), TOGETHER);
    888 	add_to_funcs(do_search_backward, MBROWSER,
    889 			N_("Where Was"), WHENHELP(browserwherewas_gist), TOGETHER);
    890 
    891 	add_to_funcs(do_findprevious, MBROWSER,
    892 			N_("Previous"), WHENHELP(findprev_gist), TOGETHER);
    893 	add_to_funcs(do_findnext, MBROWSER,
    894 			N_("Next"), WHENHELP(findnext_gist), BLANKAFTER);
    895 #endif
    896 
    897 #ifdef NANO_TINY
    898 	add_to_funcs(to_prev_word, MMAIN,
    899 			"Prev Word", WHENHELP(prevword_gist), TOGETHER);
    900 	add_to_funcs(to_next_word, MMAIN,
    901 			"Next Word", WHENHELP(nextword_gist), BLANKAFTER);
    902 #else
    903 	add_to_funcs(do_find_bracket, MMAIN,
    904 			N_("To Bracket"), WHENHELP(bracket_gist), BLANKAFTER);
    905 
    906 	add_to_funcs(do_search_backward, MMAIN|MHELP,
    907 			/* TRANSLATORS: This starts a backward search. */
    908 			N_("Where Was"), WHENHELP(wherewas_gist), TOGETHER);
    909 
    910 	add_to_funcs(do_findprevious, MMAIN|MHELP,
    911 			/* TRANSLATORS: This refers to searching the preceding occurrence. */
    912 			N_("Previous"), WHENHELP(findprev_gist), TOGETHER);
    913 	add_to_funcs(do_findnext, MMAIN|MHELP,
    914 			N_("Next"), WHENHELP(findnext_gist), BLANKAFTER);
    915 #endif
    916 
    917 	add_to_funcs(do_left, MMAIN,
    918 			/* TRANSLATORS: This means move the cursor one character back. */
    919 			N_("Back"), WHENHELP(back_gist), TOGETHER);
    920 	add_to_funcs(do_right, MMAIN,
    921 			N_("Forward"), WHENHELP(forward_gist), TOGETHER);
    922 #ifdef ENABLE_BROWSER
    923 	add_to_funcs(do_left, MBROWSER,
    924 			N_("Back"), WHENHELP(backfile_gist), TOGETHER);
    925 	add_to_funcs(do_right, MBROWSER,
    926 			N_("Forward"), WHENHELP(forwardfile_gist), TOGETHER);
    927 #endif
    928 
    929 #ifndef NANO_TINY
    930 	add_to_funcs(to_prev_word, MMAIN,
    931 			/* TRANSLATORS: Try to keep the next four strings at most 12 characters. */
    932 			N_("Prev Word"), WHENHELP(prevword_gist), TOGETHER);
    933 	add_to_funcs(to_next_word, MMAIN,
    934 			N_("Next Word"), WHENHELP(nextword_gist), TOGETHER);
    935 #endif
    936 
    937 	add_to_funcs(do_home, MMAIN,
    938 			/* TRANSLATORS: These two mean: "to beginning of line", "to end of line". */
    939 			N_("Home"), WHENHELP(home_gist), TOGETHER);
    940 	add_to_funcs(do_end, MMAIN,
    941 			N_("End"), WHENHELP(end_gist), BLANKAFTER);
    942 
    943 	add_to_funcs(do_up, MMAIN|MBROWSER|MHELP,
    944 			/* TRANSLATORS: Try to keep the next two strings at most 10 characters. */
    945 			N_("Prev Line"), WHENHELP(prevline_gist), TOGETHER);
    946 	add_to_funcs(do_down, MMAIN|MBROWSER|MHELP,
    947 			N_("Next Line"), WHENHELP(nextline_gist), TOGETHER);
    948 #if !defined(NANO_TINY) || defined(ENABLE_HELP)
    949 	add_to_funcs(do_scroll_up, MMAIN,
    950 			/* TRANSLATORS: Try to keep the next four strings at most 12 characters. */
    951 			N_("Scroll Up"), WHENHELP(scrollup_gist), TOGETHER);
    952 	add_to_funcs(do_scroll_down, MMAIN,
    953 			N_("Scroll Down"), WHENHELP(scrolldown_gist), BLANKAFTER);
    954 #endif
    955 
    956 	add_to_funcs(to_prev_block, MMAIN,
    957 			N_("Prev Block"), WHENHELP(prevblock_gist), TOGETHER);
    958 	add_to_funcs(to_next_block, MMAIN,
    959 			N_("Next Block"), WHENHELP(nextblock_gist), TOGETHER);
    960 #ifdef ENABLE_JUSTIFY
    961 	add_to_funcs(to_para_begin, MMAIN|MGOTOLINE,
    962 			/* TRANSLATORS: Try to keep these two strings at most 16 characters. */
    963 			N_("Begin of Paragr."), WHENHELP(parabegin_gist), TOGETHER);
    964 	add_to_funcs(to_para_end, MMAIN|MGOTOLINE,
    965 			N_("End of Paragraph"), WHENHELP(paraend_gist), BLANKAFTER);
    966 #endif
    967 
    968 #ifndef NANO_TINY
    969 	add_to_funcs(to_top_row, MMAIN,
    970 			N_("Top Row"), WHENHELP(toprow_gist), TOGETHER);
    971 	add_to_funcs(to_bottom_row, MMAIN,
    972 			N_("Bottom Row"), WHENHELP(bottomrow_gist), BLANKAFTER);
    973 #endif
    974 
    975 	add_to_funcs(do_page_up, MMAIN|MHELP,
    976 			/* TRANSLATORS: Try to keep the next four strings at most 10 characters. */
    977 			N_("Prev Page"), WHENHELP(prevpage_gist), TOGETHER);
    978 	add_to_funcs(do_page_down, MMAIN|MHELP,
    979 			N_("Next Page"), WHENHELP(nextpage_gist), TOGETHER);
    980 
    981 	add_to_funcs(to_first_line, MMAIN|MHELP|MGOTOLINE,
    982 			N_("First Line"), WHENHELP(firstline_gist), TOGETHER);
    983 	add_to_funcs(to_last_line, MMAIN|MHELP|MGOTOLINE,
    984 			N_("Last Line"), WHENHELP(lastline_gist), BLANKAFTER);
    985 
    986 #ifdef ENABLE_MULTIBUFFER
    987 	add_to_funcs(switch_to_prev_buffer, MMAIN,
    988 			/* TRANSLATORS: Try to keep these two strings at most 15 characters. */
    989 			N_("Prev File"), WHENHELP(prevfile_gist), TOGETHER);
    990 	add_to_funcs(switch_to_next_buffer, MMAIN,
    991 			N_("Next File"), WHENHELP(nextfile_gist), BLANKAFTER);
    992 #endif
    993 
    994 #if !defined(NANO_TINY) && !defined(ENABLE_JUSTIFY)
    995 	add_to_funcs(do_gotolinecolumn, MMAIN,
    996 			N_("Go To Line"), WHENHELP(gotoline_gist), BLANKAFTER);
    997 #endif
    998 
    999 	add_to_funcs(do_tab, MMAIN,
   1000 			/* TRANSLATORS: The next four strings are names of keyboard keys. */
   1001 			N_("Tab"), WHENHELP(tab_gist), TOGETHER);
   1002 	add_to_funcs(do_enter, MMAIN,
   1003 			N_("Enter"), WHENHELP(enter_gist), BLANKAFTER);
   1004 
   1005 	add_to_funcs(do_backspace, MMAIN,
   1006 			N_("Backspace"), WHENHELP(backspace_gist), TOGETHER);
   1007 	add_to_funcs(do_delete, MMAIN,
   1008 			N_("Delete"), WHENHELP(delete_gist), BLANKAFTER);
   1009 
   1010 #ifndef NANO_TINY
   1011 	add_to_funcs(chop_previous_word, MMAIN,
   1012 			/* TRANSLATORS: The next two strings refer to deleting words. */
   1013 			N_("Chop Left"), WHENHELP(chopwordleft_gist), TOGETHER);
   1014 	add_to_funcs(chop_next_word, MMAIN,
   1015 			N_("Chop Right"), WHENHELP(chopwordright_gist), TOGETHER);
   1016 	add_to_funcs(cut_till_eof, MMAIN,
   1017 			N_("Cut Till End"), WHENHELP(cuttilleof_gist), BLANKAFTER);
   1018 #endif
   1019 
   1020 #ifdef ENABLE_JUSTIFY
   1021 	add_to_funcs(do_full_justify, MMAIN,
   1022 			N_("Full Justify"), WHENHELP(fulljustify_gist), TOGETHER);
   1023 #endif
   1024 
   1025 #ifndef NANO_TINY
   1026 	add_to_funcs(count_lines_words_and_characters, MMAIN,
   1027 			N_("Word Count"), WHENHELP(wordcount_gist), TOGETHER);
   1028 #else
   1029 	add_to_funcs(copy_text, MMAIN,
   1030 			N_("Copy"), WHENHELP(copy_gist), BLANKAFTER);
   1031 #endif
   1032 
   1033 	add_to_funcs(do_verbatim_input, MMAIN,
   1034 			N_("Verbatim"), WHENHELP(verbatim_gist), BLANKAFTER);
   1035 
   1036 #ifdef NANO_TINY
   1037 	add_to_funcs(do_search_backward, MMAIN,
   1038 			"Where Was", WHENHELP(wherewas_gist), BLANKAFTER);
   1039 #else
   1040 	add_to_funcs(do_indent, MMAIN,
   1041 			N_("Indent"), WHENHELP(indent_gist), TOGETHER);
   1042 	add_to_funcs(do_unindent, MMAIN,
   1043 			N_("Unindent"), WHENHELP(unindent_gist), BLANKAFTER);
   1044 #endif
   1045 #ifdef ENABLE_COMMENT
   1046 	add_to_funcs(do_comment, MMAIN,
   1047 			N_("Comment Lines"), WHENHELP(comment_gist), TOGETHER);
   1048 #endif
   1049 #ifdef ENABLE_WORDCOMPLETION
   1050 	add_to_funcs(complete_a_word, MMAIN,
   1051 			N_("Complete"), WHENHELP(completion_gist), BLANKAFTER);
   1052 #endif
   1053 
   1054 #ifndef NANO_TINY
   1055 	add_to_funcs(record_macro, MMAIN,
   1056 			N_("Record"), WHENHELP(recordmacro_gist), TOGETHER);
   1057 	add_to_funcs(run_macro, MMAIN,
   1058 			N_("Run Macro"), WHENHELP(runmacro_gist), BLANKAFTER);
   1059 
   1060 	add_to_funcs(zap_text, MMAIN,
   1061 			/* TRANSLATORS: This refers to deleting a line or marked region. */
   1062 			N_("Zap"), WHENHELP(zap_gist), BLANKAFTER);
   1063 
   1064 	add_to_funcs(put_or_lift_anchor, MMAIN,
   1065 			N_("Anchor"), WHENHELP(anchor_gist), TOGETHER);
   1066 	add_to_funcs(to_prev_anchor, MMAIN,
   1067 			N_("Up to anchor"), WHENHELP(prevanchor_gist), TOGETHER);
   1068 	add_to_funcs(to_next_anchor, MMAIN,
   1069 			N_("Down to anchor"), WHENHELP(nextanchor_gist), BLANKAFTER);
   1070 
   1071 #ifdef ENABLE_SPELLER
   1072 	add_to_funcs(do_spell, MMAIN,
   1073 			N_("Spell Check"), WHENHELP(spell_gist), TOGETHER);
   1074 #endif
   1075 #ifdef ENABLE_LINTER
   1076 	add_to_funcs(do_linter, MMAIN,
   1077 			N_("Linter"), WHENHELP(lint_gist), TOGETHER);
   1078 #endif
   1079 #ifdef ENABLE_FORMATTER
   1080 	add_to_funcs(do_formatter, MMAIN,
   1081 			N_("Formatter"), WHENHELP(formatter_gist), BLANKAFTER);
   1082 #endif
   1083 	/* Although not allowed in restricted mode, keep execution rebindable. */
   1084 	if (ISSET(RESTRICTED))
   1085 		add_to_funcs(do_execute, MMAIN,
   1086 				N_("Execute"), WHENHELP(execute_gist), TOGETHER);
   1087 
   1088 	add_to_funcs(do_suspend, MMAIN,
   1089 			N_("Suspend"), WHENHELP(suspend_gist), TOGETHER);
   1090 #endif /* !NANO_TINY */
   1091 
   1092 #ifdef ENABLE_HELP
   1093 	add_to_funcs(full_refresh, MMAIN,
   1094 			N_("Refresh"), WHENHELP(refresh_gist), BLANKAFTER);
   1095 #endif
   1096 #ifndef NANO_TINY
   1097 	add_to_funcs(do_center, MMAIN,
   1098 			N_("Center"), WHENHELP(center_gist), TOGETHER);
   1099 	add_to_funcs(do_cycle, MMAIN,
   1100 			N_("Cycle"), WHENHELP(cycle_gist), BLANKAFTER);
   1101 #endif
   1102 
   1103 	add_to_funcs(do_savefile, MMAIN,
   1104 			N_("Save"), WHENHELP(savefile_gist), BLANKAFTER);
   1105 
   1106 #ifdef ENABLE_MULTIBUFFER
   1107 	/* Include the new-buffer toggle only when it can actually be used. */
   1108 	if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE))
   1109 		add_to_funcs(flip_newbuffer, MINSERTFILE|MEXECUTE,
   1110 				N_("New Buffer"), WHENHELP(newbuffer_gist), TOGETHER);
   1111 #endif
   1112 #ifndef NANO_TINY
   1113 	add_to_funcs(flip_pipe, MEXECUTE,
   1114 			N_("Pipe Text"), WHENHELP(pipe_gist), BLANKAFTER);
   1115 #endif
   1116 #ifdef ENABLE_SPELLER
   1117 	add_to_funcs(do_spell, MEXECUTE,
   1118 			/* TRANSLATORS: Try to keep the next four strings at most 12 characters. */
   1119 			N_("Spell Check"), WHENHELP(spell_gist), TOGETHER);
   1120 #endif
   1121 #ifdef ENABLE_LINTER
   1122 	add_to_funcs(do_linter, MEXECUTE,
   1123 			N_("Linter"), WHENHELP(lint_gist), BLANKAFTER);
   1124 #endif
   1125 #ifdef ENABLE_JUSTIFY
   1126 	add_to_funcs(do_full_justify, MEXECUTE,
   1127 			N_("Full Justify"), WHENHELP(fulljustify_gist), TOGETHER);
   1128 #endif
   1129 #ifdef ENABLE_FORMATTER
   1130 	add_to_funcs(do_formatter, MEXECUTE,
   1131 			N_("Formatter"), WHENHELP(formatter_gist), BLANKAFTER);
   1132 #endif
   1133 
   1134 #ifdef ENABLE_HELP
   1135 	add_to_funcs(flip_goto, MWHEREIS,
   1136 			N_("Go To Line"), WHENHELP(gotoline_gist), BLANKAFTER);
   1137 	add_to_funcs(flip_goto, MGOTOLINE,
   1138 			N_("Go To Text"), WHENHELP(whereis_gist), BLANKAFTER);
   1139 #endif
   1140 
   1141 #ifndef NANO_TINY
   1142 	add_to_funcs(dos_format, MWRITEFILE,
   1143 			N_("DOS Format"), WHENHELP(dos_gist), TOGETHER);
   1144 	add_to_funcs(mac_format, MWRITEFILE,
   1145 			N_("Mac Format"), WHENHELP(mac_gist), TOGETHER);
   1146 
   1147 	/* If we're using restricted mode, the Append, Prepend, and Backup toggles
   1148 	 * are disabled.  The first and second are not useful as they only allow
   1149 	 * reduplicating the current file, and the third is not allowed as it
   1150 	 * would write to a file not specified on the command line. */
   1151 	if (!ISSET(RESTRICTED)) {
   1152 		add_to_funcs(append_it, MWRITEFILE,
   1153 				N_("Append"), WHENHELP(append_gist), TOGETHER);
   1154 		add_to_funcs(prepend_it, MWRITEFILE,
   1155 				N_("Prepend"), WHENHELP(prepend_gist), TOGETHER);
   1156 
   1157 		add_to_funcs(back_it_up, MWRITEFILE,
   1158 				N_("Backup File"), WHENHELP(backup_gist), BLANKAFTER);
   1159 	}
   1160 
   1161 	add_to_funcs(flip_convert, MINSERTFILE,
   1162 			N_("No Conversion"), WHENHELP(convert_gist), BLANKAFTER);
   1163 
   1164 	/* Command execution is only available when not in restricted mode. */
   1165 	if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE))
   1166 		add_to_funcs(flip_execute, MINSERTFILE,
   1167 				N_("Execute Command"), WHENHELP(execute_gist), BLANKAFTER);
   1168 
   1169 	add_to_funcs(cut_till_eof, MEXECUTE,
   1170 			N_("Cut Till End"), WHENHELP(cuttilleof_gist), BLANKAFTER);
   1171 
   1172 	add_to_funcs(do_suspend, MEXECUTE,
   1173 			N_("Suspend"), WHENHELP(suspend_gist), BLANKAFTER);
   1174 #endif /* !NANO_TINY */
   1175 
   1176 	add_to_funcs(discard_buffer, MWRITEFILE,
   1177 			N_("Discard buffer"), WHENHELP(discardbuffer_gist), BLANKAFTER);
   1178 
   1179 #ifdef ENABLE_BROWSER
   1180 	/* The file browser is only available when not in restricted mode. */
   1181 	if (!ISSET(RESTRICTED))
   1182 		add_to_funcs(to_files, MWRITEFILE|MINSERTFILE,
   1183 				/* TRANSLATORS: This invokes the file browser. */
   1184 				N_("Browse"), WHENHELP(tofiles_gist), BLANKAFTER);
   1185 
   1186 	add_to_funcs(do_page_up, MBROWSER,
   1187 			N_("Prev Page"), WHENHELP(prevpage_gist), TOGETHER);
   1188 	add_to_funcs(do_page_down, MBROWSER,
   1189 			N_("Next Page"), WHENHELP(nextpage_gist), TOGETHER);
   1190 
   1191 	add_to_funcs(to_first_file, MBROWSER|MWHEREISFILE,
   1192 			N_("First File"), WHENHELP(firstfile_gist), TOGETHER);
   1193 	add_to_funcs(to_last_file, MBROWSER|MWHEREISFILE,
   1194 			N_("Last File"), WHENHELP(lastfile_gist), BLANKAFTER);
   1195 
   1196 #ifndef NANO_TINY
   1197 	add_to_funcs(to_prev_word, MBROWSER,
   1198 			N_("Left Column"), WHENHELP(browserlefthand_gist), TOGETHER);
   1199 	add_to_funcs(to_next_word, MBROWSER,
   1200 			N_("Right Column"), WHENHELP(browserrighthand_gist), TOGETHER);
   1201 	add_to_funcs(to_prev_block, MBROWSER,
   1202 			N_("Top Row"), WHENHELP(browsertoprow_gist), TOGETHER);
   1203 	add_to_funcs(to_next_block, MBROWSER,
   1204 			N_("Bottom Row"), WHENHELP(browserbottomrow_gist), BLANKAFTER);
   1205 #endif
   1206 #endif /* ENABLE_BROWSER */
   1207 
   1208 #ifdef ENABLE_LINTER
   1209 	add_to_funcs(do_page_up, MLINTER,
   1210 			/* TRANSLATORS: The next two strings may be up to 37 characters each. */
   1211 			N_("Previous Linter message"), WHENHELP(prevlint_gist), TOGETHER);
   1212 	add_to_funcs(do_page_down, MLINTER,
   1213 			N_("Next Linter message"), WHENHELP(nextlint_gist), TOGETHER);
   1214 #endif
   1215 
   1216 #ifdef __linux__
   1217 #define SLASH_OR_DASH  (on_a_vt) ? "^-" : "^/"
   1218 #else
   1219 #define SLASH_OR_DASH  "^/"
   1220 #endif
   1221 
   1222 	/* Link key combos to functions in certain menus. */
   1223 	add_to_sclist(MMOST|MBROWSER, "^M", '\r', do_enter, 0);
   1224 	add_to_sclist(MMOST|MBROWSER, "Enter", KEY_ENTER, do_enter, 0);
   1225 	add_to_sclist(MMOST, "^I", '\t', do_tab, 0);
   1226 	add_to_sclist(MMOST, "Tab", '\t', do_tab, 0);
   1227 	add_to_sclist(MMAIN|MBROWSER|MHELP, "^B", 0, do_search_backward, 0);
   1228 	add_to_sclist(MMAIN|MBROWSER|MHELP, "^F", 0, do_search_forward, 0);
   1229 	if (ISSET(MODERN_BINDINGS)) {
   1230 		add_to_sclist((MMOST|MBROWSER) & ~MFINDINHELP, help_key, 0, do_help, 0);
   1231 		add_to_sclist(MHELP, help_key, 0, do_exit, 0);
   1232 		add_to_sclist(MMAIN|MBROWSER|MHELP, "^Q", 0, do_exit, 0);
   1233 		add_to_sclist(MMAIN, "^S", 0, do_savefile, 0);
   1234 		add_to_sclist(MMAIN, "^W", 0, do_writeout, 0);
   1235 		add_to_sclist(MMAIN, "^O", 0, do_insertfile, 0);
   1236 		add_to_sclist(MMAIN|MBROWSER|MHELP, "^D", 0, do_findprevious, 0);
   1237 		add_to_sclist(MMAIN|MBROWSER|MHELP, "^G", 0, do_findnext, 0);
   1238 		add_to_sclist(MMAIN, "^R", 0, do_replace, 0);
   1239 		add_to_sclist(MMAIN, "^T", 0, do_gotolinecolumn, 0);
   1240 		add_to_sclist(MMAIN, "^P", 0, report_cursor_position, 0);
   1241 #ifndef NANO_TINY
   1242 		add_to_sclist(MMAIN, "^Z", 0, do_undo, 0);
   1243 		add_to_sclist(MMAIN, "^Y", 0, do_redo, 0);
   1244 		add_to_sclist(MMAIN, "^A", 0, do_mark, 0);
   1245 #endif
   1246 		add_to_sclist(MMAIN, "^X", 0, cut_text, 0);
   1247 		add_to_sclist(MMAIN, "^C", 0, copy_text, 0);
   1248 		add_to_sclist(MMAIN, "^V", 0, paste_text, 0);
   1249 	} else {
   1250 		add_to_sclist((MMOST|MBROWSER) & ~MFINDINHELP, "^G", 0, do_help, 0);
   1251 		add_to_sclist(MMAIN|MBROWSER|MHELP, "^X", 0, do_exit, 0);
   1252 		if (!ISSET(PRESERVE))
   1253 			add_to_sclist(MMAIN, "^S", 0, do_savefile, 0);
   1254 		add_to_sclist(MMAIN, "^O", 0, do_writeout, 0);
   1255 		add_to_sclist(MMAIN, "^R", 0, do_insertfile, 0);
   1256 		if (!ISSET(PRESERVE))
   1257 			add_to_sclist(MMAIN|MBROWSER|MHELP, "^Q", 0, do_search_backward, 0);
   1258 		add_to_sclist(MMAIN|MBROWSER|MHELP, "^W", 0, do_search_forward, 0);
   1259 		add_to_sclist(MMOST, "^A", 0, do_home, 0);
   1260 		add_to_sclist(MMOST, "^E", 0, do_end, 0);
   1261 		add_to_sclist(MMAIN|MBROWSER|MHELP, "^P", 0, do_up, 0);
   1262 		add_to_sclist(MMAIN|MBROWSER|MHELP, "^N", 0, do_down, 0);
   1263 		add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "^Y", 0, do_page_up, 0);
   1264 		add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "^V", 0, do_page_down, 0);
   1265 		add_to_sclist(MMAIN, "^C", 0, report_cursor_position, 0);
   1266 		add_to_sclist(MMOST, "^H", '\b', do_backspace, 0);
   1267 		add_to_sclist(MMOST, "^D", 0, do_delete, 0);
   1268 	}
   1269 	add_to_sclist(MMOST, "Bsp", KEY_BACKSPACE, do_backspace, 0);
   1270 	add_to_sclist(MMOST, "Sh-Del", SHIFT_DELETE, do_backspace, 0);
   1271 	add_to_sclist(MMOST, "Del", KEY_DC, do_delete, 0);
   1272 	add_to_sclist(MMAIN, "Ins", KEY_IC, do_insertfile, 0);
   1273 	add_to_sclist(MMAIN, "^\\", 0, do_replace, 0);
   1274 	add_to_sclist(MMAIN, "M-R", 0, do_replace, 0);
   1275 	add_to_sclist(MMOST, "^K", 0, cut_text, 0);
   1276 #ifdef NANO_TINY
   1277 	add_to_sclist(MMAIN, "M-6", 0, copy_text, 0);
   1278 	add_to_sclist(MMAIN, "M-^", 0, copy_text, 0);
   1279 	add_to_sclist(MMAIN, "^U", 0, paste_text, 0);
   1280 #ifdef ENABLE_SPELLER
   1281 	add_to_sclist(MMAIN, ISSET(MODERN_BINDINGS) ? "^E" : "^T", 0, do_spell, 0);
   1282 #endif
   1283 #else
   1284 	add_to_sclist(MMOST, "M-6", 0, copy_text, 0);
   1285 	add_to_sclist(MMOST, "M-^", 0, copy_text, 0);
   1286 	add_to_sclist(MMOST, "^U", 0, paste_text, 0);
   1287 	add_to_sclist(MMAIN, ISSET(MODERN_BINDINGS) ? "^E" : "^T", 0, do_execute, 0);
   1288 #ifdef ENABLE_SPELLER
   1289 	if (!ISSET(PRESERVE))
   1290 		add_to_sclist(MEXECUTE, "^S", 0, do_spell, 0);
   1291 	add_to_sclist(MEXECUTE, "^T", 0, do_spell, 0);
   1292 #endif
   1293 #endif
   1294 #ifdef ENABLE_JUSTIFY
   1295 	add_to_sclist(MMAIN, "^J", '\n', do_justify, 0);
   1296 #endif
   1297 #ifdef ENABLE_LINTER
   1298 	add_to_sclist(MEXECUTE, "^Y", 0, do_linter, 0);
   1299 #endif
   1300 #ifdef ENABLE_FORMATTER
   1301 	add_to_sclist(MEXECUTE, "^O", 0, do_formatter, 0);
   1302 #endif
   1303 	add_to_sclist(MMAIN, SLASH_OR_DASH, 0, do_gotolinecolumn, 0);
   1304 	add_to_sclist(MMAIN, "M-G", 0, do_gotolinecolumn, 0);
   1305 	add_to_sclist(MMAIN, "^_", 0, do_gotolinecolumn, 0);
   1306 	add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "PgUp", KEY_PPAGE, do_page_up, 0);
   1307 	add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "PgDn", KEY_NPAGE, do_page_down, 0);
   1308 	add_to_sclist(MBROWSER|MHELP, "Bsp", KEY_BACKSPACE, do_page_up, 0);
   1309 	add_to_sclist(MBROWSER|MHELP, "Sh-Del", SHIFT_DELETE, do_page_up, 0);
   1310 	add_to_sclist(MBROWSER|MHELP, "Space", 0x20, do_page_down, 0);
   1311 	add_to_sclist(MMAIN|MHELP, "M-\\", 0, to_first_line, 0);
   1312 	add_to_sclist(MMAIN|MHELP, "^Home", CONTROL_HOME, to_first_line, 0);
   1313 	add_to_sclist(MMAIN|MHELP, "M-/", 0, to_last_line, 0);
   1314 	add_to_sclist(MMAIN|MHELP, "^End", CONTROL_END, to_last_line, 0);
   1315 	add_to_sclist(MMAIN|MBROWSER|MHELP, "M-B", 0, do_findprevious, 0);
   1316 	add_to_sclist(MMAIN|MBROWSER|MHELP, "M-F", 0, do_findnext, 0);
   1317 	add_to_sclist(MMAIN|MBROWSER|MHELP, "M-W", 0, do_findnext, 0);
   1318 	add_to_sclist(MMAIN|MBROWSER|MHELP, "M-Q", 0, do_findprevious, 0);
   1319 #ifdef NANO_TINY
   1320 #ifdef ENABLE_LINENUMBERS
   1321 	add_to_sclist(MMAIN, "M-N", 0, toggle_numbers, 0);
   1322 #else
   1323 	add_to_sclist(MMAIN, "M-N", 0, to_next_word, 0);
   1324 #endif
   1325 	add_to_sclist(MMAIN, "M-D", 0, to_prev_word, 0);
   1326 #else
   1327 	add_to_sclist(MMAIN, "M-]", 0, do_find_bracket, 0);
   1328 	add_to_sclist(MMAIN, "M-A", 0, do_mark, 0);
   1329 	add_to_sclist(MMAIN, "^6", 0, do_mark, 0);
   1330 	add_to_sclist(MMAIN, "^^", 0, do_mark, 0);
   1331 	add_to_sclist(MMAIN, "M-}", 0, do_indent, 0);
   1332 	add_to_sclist(MMAIN, "M-{", 0, do_unindent, 0);
   1333 	add_to_sclist(MMAIN, "Sh-Tab", SHIFT_TAB, do_unindent, 0);
   1334 	add_to_sclist(MMAIN, "M-:", 0, record_macro, 0);
   1335 	add_to_sclist(MMAIN, "M-;", 0, run_macro, 0);
   1336 	add_to_sclist(MMAIN, "M-U", 0, do_undo, 0);
   1337 	add_to_sclist(MMAIN, "M-E", 0, do_redo, 0);
   1338 	add_to_sclist(MMAIN, "M-Bsp", CONTROL_SHIFT_DELETE, chop_previous_word, 0);
   1339 	add_to_sclist(MMAIN, "Sh-^Del", CONTROL_SHIFT_DELETE, chop_previous_word, 0);
   1340 	add_to_sclist(MMAIN, "^Del", CONTROL_DELETE, chop_next_word, 0);
   1341 	add_to_sclist(MMAIN, "M-Del", ALT_DELETE, zap_text, 0);
   1342 	add_to_sclist(MMAIN, "M-Ins", ALT_INSERT, put_or_lift_anchor, 0);
   1343 	add_to_sclist(MMAIN, "M-Home", ALT_HOME, to_top_row, 0);
   1344 	add_to_sclist(MMAIN, "M-End", ALT_END, to_bottom_row, 0);
   1345 	add_to_sclist(MMAIN, "M-PgUp", ALT_PAGEUP, to_prev_anchor, 0);
   1346 	add_to_sclist(MMAIN, "M-PgDn", ALT_PAGEDOWN, to_next_anchor, 0);
   1347 	add_to_sclist(MMAIN, "M-\"", 0, put_or_lift_anchor, 0);
   1348 	add_to_sclist(MMAIN, "M-'", 0, to_next_anchor, 0);
   1349 #endif
   1350 #ifdef ENABLE_WORDCOMPLETION
   1351 	add_to_sclist(MMAIN, "^]", 0, complete_a_word, 0);
   1352 #endif
   1353 #ifdef ENABLE_COMMENT
   1354 	add_to_sclist(MMAIN, "M-3", 0, do_comment, 0);
   1355 #endif
   1356 	add_to_sclist(MMOST & ~MMAIN, "^B", 0, do_left, 0);
   1357 	add_to_sclist(MMOST & ~MMAIN, "^F", 0, do_right, 0);
   1358 #ifdef ENABLE_UTF8
   1359 	if (using_utf8) {
   1360 		add_to_sclist(MMOST|MBROWSER|MHELP, "\xE2\x97\x82", KEY_LEFT, do_left, 0);
   1361 		add_to_sclist(MMOST|MBROWSER|MHELP, "\xE2\x96\xb8", KEY_RIGHT, do_right, 0);
   1362 		add_to_sclist(MSOME, "^\xE2\x97\x82", CONTROL_LEFT, to_prev_word, 0);
   1363 		add_to_sclist(MSOME, "^\xE2\x96\xb8", CONTROL_RIGHT, to_next_word, 0);
   1364 #if defined(ENABLE_MULTIBUFFER) && !defined(NANO_TINY)
   1365 		if (!on_a_vt) {
   1366 			add_to_sclist(MMAIN, "M-\xE2\x97\x82", ALT_LEFT, switch_to_prev_buffer, 0);
   1367 			add_to_sclist(MMAIN, "M-\xE2\x96\xb8", ALT_RIGHT, switch_to_next_buffer, 0);
   1368 		}
   1369 #endif
   1370 	} else
   1371 #endif
   1372 	{
   1373 		add_to_sclist(MMOST|MBROWSER|MHELP, "Left", KEY_LEFT, do_left, 0);
   1374 		add_to_sclist(MMOST|MBROWSER|MHELP, "Right", KEY_RIGHT, do_right, 0);
   1375 		add_to_sclist(MSOME, "^Left", CONTROL_LEFT, to_prev_word, 0);
   1376 		add_to_sclist(MSOME, "^Right", CONTROL_RIGHT, to_next_word, 0);
   1377 #if defined(ENABLE_MULTIBUFFER) && !defined(NANO_TINY)
   1378 		if (!on_a_vt) {
   1379 			add_to_sclist(MMAIN, "M-Left", ALT_LEFT, switch_to_prev_buffer, 0);
   1380 			add_to_sclist(MMAIN, "M-Right", ALT_RIGHT, switch_to_next_buffer, 0);
   1381 		}
   1382 #endif
   1383 	}
   1384 	add_to_sclist(MMOST, "M-Space", 0, to_prev_word, 0);
   1385 	add_to_sclist(MMOST, "^Space", 0, to_next_word, 0);
   1386 	add_to_sclist(MMOST, "Home", KEY_HOME, do_home, 0);
   1387 	add_to_sclist(MMOST, "End", KEY_END, do_end, 0);
   1388 #ifdef ENABLE_UTF8
   1389 	if (using_utf8) {
   1390 		add_to_sclist(MMAIN|MBROWSER|MHELP, "\xE2\x96\xb4", KEY_UP, do_up, 0);
   1391 		add_to_sclist(MMAIN|MBROWSER|MHELP, "\xE2\x96\xbe", KEY_DOWN, do_down, 0);
   1392 		add_to_sclist(MMAIN|MBROWSER|MLINTER, "^\xE2\x96\xb4", CONTROL_UP, to_prev_block, 0);
   1393 		add_to_sclist(MMAIN|MBROWSER|MLINTER, "^\xE2\x96\xbe", CONTROL_DOWN, to_next_block, 0);
   1394 	} else
   1395 #endif
   1396 	{
   1397 		add_to_sclist(MMAIN|MBROWSER|MHELP, "Up", KEY_UP, do_up, 0);
   1398 		add_to_sclist(MMAIN|MBROWSER|MHELP, "Down", KEY_DOWN, do_down, 0);
   1399 		add_to_sclist(MMAIN|MBROWSER|MLINTER, "^Up", CONTROL_UP, to_prev_block, 0);
   1400 		add_to_sclist(MMAIN|MBROWSER|MLINTER, "^Down", CONTROL_DOWN, to_next_block, 0);
   1401 	}
   1402 	add_to_sclist(MMAIN, "M-7", 0, to_prev_block, 0);
   1403 	add_to_sclist(MMAIN, "M-8", 0, to_next_block, 0);
   1404 #ifdef ENABLE_JUSTIFY
   1405 	add_to_sclist(MMAIN, "M-(", 0, to_para_begin, 0);
   1406 	add_to_sclist(MMAIN, "M-9", 0, to_para_begin, 0);
   1407 	add_to_sclist(MMAIN, "M-)", 0, to_para_end, 0);
   1408 	add_to_sclist(MMAIN, "M-0", 0, to_para_end, 0);
   1409 #endif
   1410 #ifndef NANO_TINY
   1411 #ifdef ENABLE_UTF8
   1412 	if (using_utf8) {
   1413 		add_to_sclist(MMAIN|MHELP, "M-\xE2\x96\xb4", ALT_UP, do_scroll_up, 0);
   1414 		add_to_sclist(MMAIN|MHELP, "M-\xE2\x96\xbe", ALT_DOWN, do_scroll_down, 0);
   1415 	} else
   1416 #endif
   1417 	{
   1418 		add_to_sclist(MMAIN|MHELP, "M-Up", ALT_UP, do_scroll_up, 0);
   1419 		add_to_sclist(MMAIN|MHELP, "M-Down", ALT_DOWN, do_scroll_down, 0);
   1420 	}
   1421 #endif
   1422 #if !defined(NANO_TINY) || defined(ENABLE_HELP)
   1423 	add_to_sclist(MMAIN|MHELP, "M--", 0, do_scroll_up, 0);
   1424 	add_to_sclist(MMAIN|MHELP, "M-_", 0, do_scroll_up, 0);
   1425 	add_to_sclist(MMAIN|MHELP, "M-+", 0, do_scroll_down, 0);
   1426 	add_to_sclist(MMAIN|MHELP, "M-=", 0, do_scroll_down, 0);
   1427 #endif
   1428 #ifdef ENABLE_MULTIBUFFER
   1429 	add_to_sclist(MMAIN, "M-,", 0, switch_to_prev_buffer, 0);
   1430 	add_to_sclist(MMAIN, "M-<", 0, switch_to_prev_buffer, 0);
   1431 	add_to_sclist(MMAIN, "M-.", 0, switch_to_next_buffer, 0);
   1432 	add_to_sclist(MMAIN, "M->", 0, switch_to_next_buffer, 0);
   1433 #endif
   1434 	add_to_sclist(MMOST, "M-V", 0, do_verbatim_input, 0);
   1435 #ifndef NANO_TINY
   1436 	add_to_sclist(MMAIN, "M-T", 0, cut_till_eof, 0);
   1437 	add_to_sclist(MEXECUTE, "^V", 0, cut_till_eof, 0);
   1438 	add_to_sclist(MEXECUTE, "^Z", 0, do_suspend, 0);
   1439 	add_to_sclist(MMAIN, "^Z", 0, suggest_ctrlT_ctrlZ, 0);
   1440 	add_to_sclist(MMAIN, "M-D", 0, count_lines_words_and_characters, 0);
   1441 #else
   1442 	add_to_sclist(MMAIN, "M-H", 0, do_help, 0);
   1443 #endif
   1444 #ifdef ENABLE_JUSTIFY
   1445 	add_to_sclist(MMAIN, "M-J", 0, do_full_justify, 0);
   1446 	add_to_sclist(MEXECUTE, "^J", 0, do_full_justify, 0);
   1447 #endif
   1448 #ifndef NANO_TINY
   1449 	add_to_sclist(MMAIN, "^L", 0, do_center, 0);
   1450 	add_to_sclist(MMAIN, "M-%", 0, do_cycle, 0);
   1451 	add_to_sclist((MMOST|MBROWSER|MHELP|MYESNO)&~MMAIN, "^L", 0, full_refresh, 0);
   1452 #else
   1453 	add_to_sclist(MMOST|MBROWSER|MHELP|MYESNO, "^L", 0, full_refresh, 0);
   1454 #endif
   1455 
   1456 #ifndef NANO_TINY
   1457 	/* Group of "Appearance" toggles. */
   1458 	add_to_sclist(MMAIN, "M-Z", 0, do_toggle, ZERO);
   1459 	add_to_sclist((MMOST|MBROWSER|MYESNO) & ~MFINDINHELP, "M-X", 0, do_toggle, NO_HELP);
   1460 	add_to_sclist(MMAIN, "M-C", 0, do_toggle, CONSTANT_SHOW);
   1461 	add_to_sclist(MMAIN, "M-S", 0, do_toggle, SOFTWRAP);
   1462 	add_to_sclist(MMAIN, "M-$", 0, do_toggle, SOFTWRAP);  /* Legacy keystroke. */
   1463 #ifdef ENABLE_LINENUMBERS
   1464 	add_to_sclist(MMAIN, "M-N", 0, do_toggle, LINE_NUMBERS);
   1465 	add_to_sclist(MMAIN, "M-#", 0, do_toggle, LINE_NUMBERS);  /* Legacy keystroke. */
   1466 #endif
   1467 	add_to_sclist(MMAIN, "M-P", 0, do_toggle, WHITESPACE_DISPLAY);
   1468 #ifdef ENABLE_COLOR
   1469 	add_to_sclist(MMAIN, "M-Y", 0, do_toggle, NO_SYNTAX);
   1470 #endif
   1471 
   1472 	/* Group of "Behavior" toggles. */
   1473 	add_to_sclist(MMAIN, "M-H", 0, do_toggle, SMART_HOME);
   1474 	add_to_sclist(MMAIN, "M-I", 0, do_toggle, AUTOINDENT);
   1475 	add_to_sclist(MMAIN, "M-K", 0, do_toggle, CUT_FROM_CURSOR);
   1476 #ifdef ENABLE_WRAPPING
   1477 	add_to_sclist(MMAIN, "M-L", 0, do_toggle, BREAK_LONG_LINES);
   1478 #endif
   1479 	add_to_sclist(MMAIN, "M-O", 0, do_toggle, TABS_TO_SPACES);
   1480 #ifdef ENABLE_MOUSE
   1481 	add_to_sclist(MMAIN, "M-M", 0, do_toggle, USE_MOUSE);
   1482 #endif
   1483 #endif /* !NANO_TINY */
   1484 
   1485 	add_to_sclist(((MMOST & ~MMAIN) | MYESNO), "^C", 0, do_cancel, 0);
   1486 
   1487 	add_to_sclist(MWHEREIS|MREPLACE, "M-C", 0, case_sens_void, 0);
   1488 	add_to_sclist(MWHEREIS|MREPLACE, "M-R", 0, regexp_void, 0);
   1489 	add_to_sclist(MWHEREIS|MREPLACE, "M-B", 0, backwards_void, 0);
   1490 	add_to_sclist(MWHEREIS|MREPLACE, "^R", 0, flip_replace, 0);
   1491 	add_to_sclist(MWHEREIS|MGOTOLINE, "^T", 0, flip_goto, 0);
   1492 	add_to_sclist(MWHEREIS|MGOTOLINE, SLASH_OR_DASH, 0, flip_goto, 0);
   1493 #ifdef ENABLE_HISTORIES
   1494 	add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXECUTE, "^P", 0, get_older_item, 0);
   1495 	add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXECUTE, "^N", 0, get_newer_item, 0);
   1496 #ifdef ENABLE_UTF8
   1497 	if (using_utf8) {
   1498 		add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXECUTE, "\xE2\x96\xb4", KEY_UP, get_older_item, 0);
   1499 		add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXECUTE, "\xE2\x96\xbe", KEY_DOWN, get_newer_item, 0);
   1500 	} else
   1501 #endif
   1502 	{
   1503 		add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXECUTE, "Up", KEY_UP, get_older_item, 0);
   1504 		add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXECUTE, "Down", KEY_DOWN, get_newer_item, 0);
   1505 	}
   1506 #endif
   1507 #ifdef ENABLE_JUSTIFY
   1508 	add_to_sclist(MGOTOLINE, "^W", 0, to_para_begin, 0);
   1509 	add_to_sclist(MGOTOLINE, "^O", 0, to_para_end, 0);
   1510 #endif
   1511 	/* Some people are used to having these keystrokes in the Search menu. */
   1512 	add_to_sclist(MGOTOLINE|MWHEREIS|MFINDINHELP, "^Y", 0, to_first_line, 0);
   1513 	add_to_sclist(MGOTOLINE|MWHEREIS|MFINDINHELP, "^V", 0, to_last_line, 0);
   1514 #ifdef ENABLE_BROWSER
   1515 	add_to_sclist(MWHEREISFILE, "^Y", 0, to_first_file, 0);
   1516 	add_to_sclist(MWHEREISFILE, "^V", 0, to_last_file, 0);
   1517 	add_to_sclist(MBROWSER|MWHEREISFILE, "M-\\", 0, to_first_file, 0);
   1518 	add_to_sclist(MBROWSER|MWHEREISFILE, "M-/", 0, to_last_file, 0);
   1519 	add_to_sclist(MBROWSER, "Home", KEY_HOME, to_first_file, 0);
   1520 	add_to_sclist(MBROWSER, "End", KEY_END, to_last_file, 0);
   1521 	add_to_sclist(MBROWSER, "^Home", CONTROL_HOME, to_first_file, 0);
   1522 	add_to_sclist(MBROWSER, "^End", CONTROL_END, to_last_file, 0);
   1523 	add_to_sclist(MBROWSER, SLASH_OR_DASH, 0, goto_dir, 0);
   1524 	add_to_sclist(MBROWSER, "M-G", 0, goto_dir, 0);
   1525 	add_to_sclist(MBROWSER, "^_", 0, goto_dir, 0);
   1526 #endif
   1527 	if (!ISSET(PRESERVE))
   1528 		add_to_sclist(MWRITEFILE, "^Q", 0, discard_buffer, 0);
   1529 #ifndef NANO_TINY
   1530 	add_to_sclist(MWRITEFILE, "M-D", 0, dos_format, 0);
   1531 	add_to_sclist(MWRITEFILE, "M-M", 0, mac_format, 0);
   1532 	/* Only when not in restricted mode, allow Appending, Prepending,
   1533 	 * making backups, and executing a command. */
   1534 	if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE)) {
   1535 		add_to_sclist(MWRITEFILE, "M-A", 0, append_it, 0);
   1536 		add_to_sclist(MWRITEFILE, "M-P", 0, prepend_it, 0);
   1537 		add_to_sclist(MWRITEFILE, "M-B", 0, back_it_up, 0);
   1538 		add_to_sclist(MINSERTFILE|MEXECUTE, "^X", 0, flip_execute, 0);
   1539 	}
   1540 	add_to_sclist(MINSERTFILE, "M-N", 0, flip_convert, 0);
   1541 #endif
   1542 #ifdef ENABLE_MULTIBUFFER
   1543 	if (!ISSET(RESTRICTED) && !ISSET(VIEW_MODE)) {
   1544 		add_to_sclist(MINSERTFILE|MEXECUTE, "M-F", 0, flip_newbuffer, 0);
   1545 #ifndef NANO_TINY
   1546 		add_to_sclist(MEXECUTE, "M-\\", 0, flip_pipe, 0);
   1547 #endif
   1548 	}
   1549 #endif
   1550 	add_to_sclist(MBROWSER|MHELP, "^C", 0, do_exit, 0);
   1551 #ifdef ENABLE_BROWSER
   1552 	/* Only when not in restricted mode, allow entering the file browser. */
   1553 	if (!ISSET(RESTRICTED))
   1554 		add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", 0, to_files, 0);
   1555 	/* Allow exiting the file browser with the same key as used for entry. */
   1556 	add_to_sclist(MBROWSER, "^T", 0, do_exit, 0);
   1557 #endif
   1558 #ifdef ENABLE_HELP
   1559 	/* Allow exiting the help viewer with the same keys as used for entry. */
   1560 	add_to_sclist(MHELP, "^G", 0, do_exit, 0);
   1561 	add_to_sclist(MHELP, "F1", KEY_F(1), do_exit, 0);
   1562 	add_to_sclist(MHELP, "Home", KEY_HOME, to_first_line, 0);
   1563 	add_to_sclist(MHELP, "End", KEY_END, to_last_line, 0);
   1564 #endif
   1565 #ifdef ENABLE_LINTER
   1566 	add_to_sclist(MLINTER, "^X", 0, do_cancel, 0);
   1567 #endif
   1568 	add_to_sclist(MMOST & ~MFINDINHELP, "F1", KEY_F(1), do_help, 0);
   1569 	add_to_sclist(MMAIN|MBROWSER|MHELP, "F2", KEY_F(2), do_exit, 0);
   1570 	add_to_sclist(MMAIN, "F3", KEY_F(3), do_writeout, 0);
   1571 #ifdef ENABLE_JUSTIFY
   1572 	add_to_sclist(MMAIN, "F4", KEY_F(4), do_justify, 0);
   1573 #endif
   1574 	add_to_sclist(MMAIN, "F5", KEY_F(5), do_insertfile, 0);
   1575 	add_to_sclist(MMAIN|MBROWSER|MHELP, "F6", KEY_F(6), do_search_forward, 0);
   1576 	add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "F7", KEY_F(7), do_page_up, 0);
   1577 	add_to_sclist(MMAIN|MBROWSER|MHELP|MLINTER, "F8", KEY_F(8), do_page_down, 0);
   1578 	add_to_sclist(MMOST, "F9", KEY_F(9), cut_text, 0);
   1579 	add_to_sclist(MMOST, "F10", KEY_F(10), paste_text, 0);
   1580 	add_to_sclist(MMAIN, "F11", KEY_F(11), report_cursor_position, 0);
   1581 #ifdef ENABLE_SPELLER
   1582 	add_to_sclist(MMAIN, "F12", KEY_F(12), do_spell, 0);
   1583 #endif
   1584 #if defined(ENABLE_EXTRA) && defined(NCURSES_VERSION_PATCH)
   1585 	add_to_sclist(MMAIN, "M-&", 0, show_curses_version, 0);
   1586 #endif
   1587 #ifndef NANO_TINY
   1588 	add_to_sclist((MMOST & ~MMAIN) | MYESNO, "", KEY_CANCEL, do_cancel, 0);
   1589 	add_to_sclist(MMAIN, "", KEY_CENTER, do_center, 0);
   1590 	add_to_sclist(MMAIN, "", KEY_SIC, do_insertfile, 0);
   1591 	add_to_sclist(MMAIN, "", START_OF_PASTE, suck_up_input_and_paste_it, 0);
   1592 	add_to_sclist(MMOST, "", START_OF_PASTE, do_nothing, 0);
   1593 	add_to_sclist(MMOST, "", END_OF_PASTE, do_nothing, 0);
   1594 #else
   1595 	add_to_sclist(MMOST|MBROWSER|MHELP|MYESNO, "", KEY_FRESH, full_refresh, 0);
   1596 #endif
   1597 }
   1598 
   1599 #ifndef NANO_TINY
   1600 /* Return the textual description that corresponds to the given flag. */
   1601 const char *epithet_of_flag(int flag)
   1602 {
   1603 	switch (flag) {
   1604 		case ZERO:
   1605 			/* TRANSLATORS: The next thirteen strings are toggle descriptions;
   1606 			 * they are best kept shorter than 40 characters, but may be longer. */
   1607 			return N_("Hidden interface");
   1608 		case NO_HELP:
   1609 			return N_("Help mode");
   1610 		case CONSTANT_SHOW:
   1611 			return N_("Constant cursor position display");
   1612 		case SOFTWRAP:
   1613 			return N_("Soft wrapping of overlong lines");
   1614 		case LINE_NUMBERS:
   1615 			return N_("Line numbering");
   1616 		case WHITESPACE_DISPLAY:
   1617 			return N_("Whitespace display");
   1618 		case NO_SYNTAX:
   1619 			return N_("Color syntax highlighting");
   1620 		case SMART_HOME:
   1621 			return N_("Smart home key");
   1622 		case AUTOINDENT:
   1623 			return N_("Auto indent");
   1624 		case CUT_FROM_CURSOR:
   1625 			return N_("Cut to end");
   1626 		case BREAK_LONG_LINES:
   1627 			return N_("Hard wrapping of overlong lines");
   1628 		case TABS_TO_SPACES:
   1629 			return N_("Conversion of typed tabs to spaces");
   1630 		case USE_MOUSE:
   1631 			return N_("Mouse support");
   1632 		default:
   1633 			return "Ehm...";
   1634 	}
   1635 }
   1636 #endif /* !NANO_TINY */