global.c 64.2 KB
Newer Older
Chris Allegretta's avatar
Chris Allegretta committed
1
/**************************************************************************
2
 *   global.c  --  This file is part of GNU nano.                         *
Chris Allegretta's avatar
Chris Allegretta committed
3
 *                                                                        *
4
 *   Copyright (C) 1999-2011, 2013-2017 Free Software Foundation, Inc.    *
5
6
 *   Copyright (C) 2014, 2015, 2016 Benno Schulenberg                     *
 *                                                                        *
7
8
9
10
 *   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.                               *
Chris Allegretta's avatar
Chris Allegretta committed
11
 *                                                                        *
12
13
14
15
 *   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.                 *
Chris Allegretta's avatar
Chris Allegretta committed
16
17
 *                                                                        *
 *   You should have received a copy of the GNU General Public License    *
18
 *   along with this program.  If not, see http://www.gnu.org/licenses/.  *
Chris Allegretta's avatar
Chris Allegretta committed
19
20
21
 *                                                                        *
 **************************************************************************/

22
23
#include "proto.h"

24
#include <ctype.h>
25
#include <string.h>
26
#include <strings.h>
Chris Allegretta's avatar
Chris Allegretta committed
27

28
29
/* Global variables. */
#ifndef NANO_TINY
30
31
volatile sig_atomic_t the_window_resized = FALSE;
	/* Set to TRUE by the handler whenever a SIGWINCH occurs. */
32
33
#endif

34
#ifdef __linux__
35
36
bool console;
	/* Whether we're running on a Linux VC (TRUE) or under X (FALSE). */
37
38
#endif

39
40
bool meta_key;
	/* Whether the current keystroke is a Meta key. */
41
42
bool shift_held;
	/* Whether Shift was being held together with a movement key. */
43
bool focusing = TRUE;
44
	/* Whether an update of the edit window should center the cursor. */
45

46
47
48
bool as_an_at = TRUE;
	/* Whether a 0x0A byte should be shown as a ^@ instead of a ^J. */

49
50
51
52
53
int margin = 0;
	/* The amount of space reserved at the left for line numbers. */
int editwincols = -1;
	/* The number of usable columns in the edit window: COLS - margin. */

54
55
56
57
58
#ifndef DISABLE_COLOR
bool have_palette = FALSE;
	/* Whether the colors for the current syntax have been initialized. */
#endif

59
60
61
bool suppress_cursorpos = FALSE;
	/* Should we skip constant position display for current keystroke? */

62
63
message_type lastmessage = HUSH;
	/* Messages of type HUSH should not overwrite type MILD nor ALERT. */
64

65
66
67
filestruct *pletion_line = NULL;
	/* The line where the last completion was found, if any. */

68
69
70
71
72
bool inhelp = FALSE;
	/* Whether we are in the help viewer. */
char *title = NULL;
	/* When not NULL: the title of the current help text. */

73
74
75
bool more_than_one = FALSE;
	/* Whether more than one buffer is or has been open. */

76
77
78
int didfind = 0;
	/* Whether the last search found something. */

79
int controlleft, controlright, controlup, controldown, controlhome, controlend;
80
#ifndef NANO_TINY
81
int shiftcontrolleft, shiftcontrolright, shiftcontrolup, shiftcontroldown;
82
int shiftcontrolhome, shiftcontrolend;
83
int altleft, altright, altup, altdown;
84
int shiftaltleft, shiftaltright, shiftaltup, shiftaltdown;
85
86
#endif

87
#ifndef DISABLE_WRAPJUSTIFY
88
89
ssize_t fill = 0;
	/* The column where we will wrap lines. */
90
ssize_t wrap_at = -CHARS_FROM_EOL;
91
92
93
94
95
96
97
98
	/* The position where we will wrap lines.  fill is equal to this
	 * if it's greater than zero, and equal to (COLS + this) if it
	 * isn't. */
#endif

char *last_search = NULL;
	/* The last string we searched for. */

99
100
101
char *present_path = NULL;
	/* The current browser directory when trying to do tab completion. */

102
unsigned flags[4] = {0, 0, 0, 0};
103
	/* Our flag containing the states of all global options. */
104
WINDOW *topwin = NULL;
105
106
107
	/* The top portion of the window, where we display the version
	 * number of nano, the name of the current file, and whether the
	 * current file has been modified. */
108
WINDOW *edit = NULL;
109
	/* The middle portion of the window, i.e. the edit window, where
110
	 * we display the current file we're editing. */
111
WINDOW *bottomwin = NULL;
112
113
114
115
116
117
118
	/* The bottom portion of the window, where we display statusbar
	 * messages, the statusbar prompt, and a list of shortcuts. */
int editwinrows = 0;
	/* How many rows does the edit window take up? */

filestruct *cutbuffer = NULL;
	/* The buffer where we store cut text. */
119
filestruct *cutbottom = NULL;
120
	/* The last line in the cutbuffer. */
121
partition *filepart = NULL;
122
	/* The "partition" where we store a portion of the current file. */
123
openfilestruct *openfile = NULL;
124
	/* The list of all open file buffers. */
125
126
openfilestruct *firstfile = NULL;
	/* The first open buffer. */
127

128
129
130
131
#ifndef NANO_TINY
char *matchbrackets = NULL;
	/* The opening and closing brackets that can be found by bracket
	 * searches. */
132
char *whitespace = NULL;
133
	/* The characters used when visibly showing tabs and spaces. */
134
int whitespace_len[2];
135
	/* The length in bytes of these characters. */
136
137
#endif

138
#ifndef DISABLE_JUSTIFY
139
140
141
142
143
144
145
146
147
148
char *punct = NULL;
	/* The closing punctuation that can end sentences. */
char *brackets = NULL;
	/* The closing brackets that can follow closing punctuation and
	 * can end sentences. */
char *quotestr = NULL;
	/* The quoting string.  The default value is set in main(). */
regex_t quotereg;
	/* The compiled regular expression from the quoting string. */
int quoterc;
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
149
	/* Whether it was compiled successfully. */
150
151
char *quoteerr = NULL;
	/* The error message, if it didn't. */
152
#endif /* !DISABLE_JUSTIFY */
153

154
155
156
char *word_chars = NULL;
	/* Nonalphanumeric characters that also form words. */

157
char *answer = NULL;
158
	/* The answer string used by the statusbar prompt. */
Chris Allegretta's avatar
Chris Allegretta committed
159

160
ssize_t tabsize = -1;
161
	/* The width of a tab in spaces.  The default is set in main(). */
162

163
164
165
#ifndef NANO_TINY
char *backup_dir = NULL;
	/* The directory where we store backup files. */
166

167
const char *locking_prefix = ".";
168
	/* Prefix of how to store the vim-style lock file. */
169
const char *locking_suffix = ".swp";
170
	/* Suffix of the vim-style lock file. */
171
#endif
172
#ifndef DISABLE_OPERATINGDIR
173
char *operating_dir = NULL;
174
	/* The path to our confining "operating" directory, when given. */
175
176
#endif

177
#ifndef DISABLE_SPELLER
178
179
char *alt_speller = NULL;
	/* The command to use for the alternate spell checker. */
180
181
#endif

182
#ifndef DISABLE_COLOR
183
syntaxtype *syntaxes = NULL;
184
	/* The global list of color syntaxes. */
185
char *syntaxstr = NULL;
186
	/* The color syntax name specified on the command line. */
187
188
#endif

189
190
191
bool refresh_needed = FALSE;
	/* Did a command mangle enough of the buffer that we should
	 * repaint the screen? */
192

193
194
int currmenu = MMOST;
	/* The currently active menu, initialized to a dummy value. */
195
sc *sclist = NULL;
196
	/* The start of the shortcuts list. */
197
subnfunc *allfuncs = NULL;
198
	/* The start of the functions list. */
199
subnfunc *tailfunc;
200
	/* The last function in the list. */
201
subnfunc *exitfunc;
202
	/* A pointer to the special Exit/Close item. */
203
subnfunc *uncutfunc;
204
	/* A pointer to the special Uncut/Unjustify item. */
205

206
#ifndef DISABLE_HISTORIES
207
filestruct *search_history = NULL;
208
	/* The current item in the list of strings that were searched for. */
209
filestruct *searchtop = NULL;
210
	/* The oldest item in the list of search strings. */
211
filestruct *searchbot = NULL;
212
213
	/* The newest item in the list of search strings. */

214
filestruct *replace_history = NULL;
215
	/* The current item in the list of replace strings. */
216
filestruct *replacetop = NULL;
217
filestruct *replacebot = NULL;
218

219
filestruct *execute_history = NULL;
220
	/* The current item in the list of commands that were run with ^R ^X. */
221
222
filestruct *executetop = NULL;
filestruct *executebot = NULL;
223

224
poshiststruct *position_history = NULL;
225
	/* The list of filenames with their last cursor positions. */
226
227
#endif

228
229
230
231
232
regex_t search_regexp;
	/* The compiled regular expression to use in searches. */
regmatch_t regmatches[10];
	/* The match positions for parenthetical subexpressions, 10
	 * maximum, used in regular expression searches. */
233

234
int hilite_attribute = A_REVERSE;
235
	/* The curses attribute we use to highlight something. */
236
#ifndef DISABLE_COLOR
237
char* specified_color_combo[] = {NULL};
238
239
	/* The color combinations as specified in the rcfile. */
#endif
240
int interface_color_pair[] = {0};
241
	/* The processed color pairs for the interface elements. */
242

243
char *homedir = NULL;
244
	/* The user's home directory, from $HOME or /etc/passwd. */
245

246

247
/* Return the number of entries in the shortcut list for a given menu. */
248
size_t length_of_list(int menu)
249
{
250
    subnfunc *f;
251
    size_t i = 0;
252

253
    for (f = allfuncs; f != NULL; f = f->next)
254
	if ((f->menus & menu) && first_sc_for(menu, f->scfunc) != NULL)
255
	    i++;
256

257
258
259
    return i;
}

260
261
262
263
264
265
/* To make the functions and shortcuts lists clearer. */
#define VIEW  TRUE		/* Is allowed in view mode. */
#define NOVIEW  FALSE
#define BLANKAFTER  TRUE	/* A blank line after this one. */
#define TOGETHER  FALSE

266
/* Just throw this here. */
267
268
269
270
271
272
void case_sens_void(void)
{
}
void regexp_void(void)
{
}
273
274
275
void backwards_void(void)
{
}
276
277
278
void flip_replace(void)
{
}
279
280
281
void gototext_void(void)
{
}
282
#ifdef ENABLE_BROWSER
283
284
285
void to_files_void(void)
{
}
286
287
288
289
void goto_dir_void(void)
{
}
#endif
290
#ifndef NANO_TINY
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
void dos_format_void(void)
{
}
void mac_format_void(void)
{
}
void append_void(void)
{
}
void prepend_void(void)
{
}
void backup_file_void(void)
{
}
306
void flip_execute(void)
307
308
{
}
309
#endif
310
#ifdef ENABLE_MULTIBUFFER
311
void flip_newbuffer(void)
312
313
{
}
314
#endif
315
void discard_buffer(void)
316
317
318
{
}

319
/* Add a function to the function list. */
320
void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *help,
321
322
    bool blank_after, bool viewok)
{
323
    subnfunc *f = nmalloc(sizeof(subnfunc));
324
325
326
327
328
329

    if (allfuncs == NULL)
	allfuncs = f;
    else
	tailfunc->next = f;
    tailfunc = f;
330
331
332
333
334
335

    f->next = NULL;
    f->scfunc = func;
    f->menus = menus;
    f->desc = desc;
    f->viewok = viewok;
336
#ifdef ENABLE_HELP
337
338
339
340
341
    f->help = help;
    f->blank_after = blank_after;
#endif

#ifdef DEBUG
342
    fprintf(stderr, "Added func %ld (%s) for menus %x\n", (long)func, f->desc, menus);
343
#endif
344
345
}

346
/* Add a key combo to the shortcut list. */
347
348
void add_to_sclist(int menus, const char *scstring, const int keycode,
			void (*func)(void), int toggle)
Chris Allegretta's avatar
Chris Allegretta committed
349
{
350
    static sc *tailsc;
351
#ifndef NANO_TINY
352
    static int counter = 0;
353
#endif
354
    sc *s = nmalloc(sizeof(sc));
355

356
357
358
359
360
361
362
363
364
    /* Start the list, or tack on the next item. */
    if (sclist == NULL)
	sclist = s;
    else
	tailsc->next = s;
    tailsc = s;
    s->next = NULL;

    /* Fill in the data. */
365
    s->menus = menus;
366
    s->scfunc = func;
367
#ifndef NANO_TINY
368
    s->toggle = toggle;
369
370
    if (toggle)
	s->ordinal = ++counter;
371
#endif
372
    assign_keyinfo(s, scstring, keycode);
373
374

#ifdef DEBUG
375
    fprintf(stderr, "Setting keycode to %d for shortcut \"%s\" in menus %x\n", s->keycode, scstring, s->menus);
376
#endif
Chris Allegretta's avatar
Chris Allegretta committed
377
378
}

379
/* Assign one function's shortcuts to another function. */
380
381
382
383
void replace_scs_for(void (*oldfunc)(void), void (*newfunc)(void))
{
    sc *s;

384
    for (s = sclist; s != NULL; s = s->next)
385
	if (s->scfunc == oldfunc)
386
387
388
	    s->scfunc = newfunc;
}

389
390
391
392
393
394
395
/* Return the first shortcut in the list of shortcuts that
 * matches the given func in the given menu. */
const sc *first_sc_for(int menu, void (*func)(void))
{
    const sc *s;

    for (s = sclist; s != NULL; s = s->next)
396
	if ((s->menus & menu) && s->scfunc == func)
397
398
399
400
401
402
403
404
405
	    return s;

#ifdef DEBUG
    fprintf(stderr, "Whoops, returning null given func %ld in menu %x\n", (long)func, menu);
#endif
    /* Otherwise... */
    return NULL;
}

406
407
408
/* Return the first keycode that is bound to the given function in the
 * current menu, if any; otherwise, return the given default value. */
int the_code_for(void (*func)(void), int defaultval)
Chris Allegretta's avatar
Chris Allegretta committed
409
410
411
{
    const sc *s = first_sc_for(currmenu, func);

412
413
414
415
416
    if (s == NULL)
	return defaultval;

    meta_key = s->meta;
    return s->keycode;
Chris Allegretta's avatar
Chris Allegretta committed
417
418
}

419
420
421
422
423
424
425
426
427
428
429
/* Return a pointer to the function that is bound to the given key. */
functionptrtype func_from_key(int *kbinput)
{
    const sc *s = get_shortcut(kbinput);

    if (s)
	return s->scfunc;
    else
	return NULL;
}

430
/* Set the string and its corresponding keycode for the given shortcut s. */
431
void assign_keyinfo(sc *s, const char *keystring, const int keycode)
432
{
433
    s->keystr = keystring;
434
    s->meta = (keystring[0] == 'M' && keystring[2] != '\xE2');
435

436
437
    assert(strlen(keystring) > 1 && (!s->meta || strlen(keystring) > 2));

438
439
    if (keycode)
	s->keycode = keycode;
440
441
442
443
444
445
446
447
448
    else
	s->keycode = keycode_from_string(keystring);
}

/* Parse the given keystring and return the corresponding keycode,
 * or return -1 when the string is invalid. */
int keycode_from_string(const char *keystring)
{
    if (keystring[0] == '^') {
449
	if (strcasecmp(keystring, "^Space") == 0)
450
451
452
	    return 0;
	if (strlen(keystring) == 2)
	    return keystring[1] - 64;
453
	else
454
455
	    return -1;
    } else if (keystring[0] == 'M') {
456
	if (strcasecmp(keystring, "M-Space") == 0)
457
458
459
	    return (int)' ';
	if (keystring[1] == '-')
	    return tolower((unsigned char)keystring[2]);
460
	else
461
462
463
	    return -1;
    } else if (keystring[0] == 'F') {
	int fn = atoi(&keystring[1]);
464
	if (fn < 0 || fn > 63)
465
466
467
468
	    return -1;
	return KEY_F0 + fn;
    } else if (!strcasecmp(keystring, "Ins"))
	return KEY_IC;
469
    else if (!strcasecmp(keystring, "Del"))
470
471
472
	return KEY_DC;
    else
	return -1;
473
474
475
476
477
478
479
480
}

#ifdef DEBUG
void print_sclist(void)
{
    sc *s;
    const subnfunc *f;

481
    for (s = sclist; s != NULL; s = s->next) {
482
	f = sctofunc(s);
483
	if (f)
484
	    fprintf(stderr, "Shortcut \"%s\", function: %s, menus %x\n", s->keystr, f->desc, f->menus);
485
	else
486
	    fprintf(stderr, "Hmm, didn't find a func for \"%s\"\n", s->keystr);
487
488
489
490
    }
}
#endif

491
492
/* These four tags are used elsewhere too, so they are global. */
/* TRANSLATORS: Try to keep the next fifteen strings at most 10 characters. */
493
494
const char *exit_tag = N_("Exit");
const char *close_tag = N_("Close");
495
const char *uncut_tag = N_("Uncut Text");
496
#ifndef DISABLE_JUSTIFY
497
498
const char *unjust_tag = N_("Unjustify");
#endif
499

500
501
/* Initialize the list of functions and the list of shortcuts. */
void shortcut_init(void)
502
{
503
    const char *read_file_tag = N_("Read File");
504
    const char *whereis_tag = N_("Where Is");
505
506
    const char *replace_tag = N_("Replace");
    const char *gotoline_tag = N_("Go To Line");
507
508
    const char *prev_line_tag = N_("Prev Line");
    const char *next_line_tag = N_("Next Line");
509
510
    const char *prev_page_tag = N_("Prev Page");
    const char *next_page_tag = N_("Next Page");
511
#ifndef DISABLE_JUSTIFY
512
    const char *justify_tag = N_("Justify");
513
    const char *fulljustify_tag = N_("FullJstify");
514
#endif
515
    const char *refresh_tag = N_("Refresh");
516
517
    /* TRANSLATORS: Try to keep this string at most 12 characters. */
    const char *whereis_next_tag = N_("WhereIs Next");
518

519
#ifdef ENABLE_HELP
520
521
    /* TRANSLATORS: The next long series of strings are shortcut descriptions;
     * they are best kept shorter than 56 characters, but may be longer. */
522
    const char *nano_cancel_msg = N_("Cancel the current function");
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
523
    const char *nano_help_msg = N_("Display this help text");
524
    const char *nano_exit_msg =
525
#ifdef ENABLE_MULTIBUFFER
526
	N_("Close the current file buffer / Exit from nano")
527
#else
528
	N_("Exit from nano")
529
530
#endif
	;
531
532
    const char *nano_writeout_msg =
	N_("Write the current file to disk");
533
534
    const char *nano_insert_msg =
	N_("Insert another file into the current one");
535
    const char *nano_whereis_msg =
536
	N_("Search forward for a string or a regular expression");
537
    const char *nano_wherewas_msg =
538
	N_("Search backward for a string or a regular expression");
539
#ifdef ENABLE_BROWSER
540
541
    const char *nano_browser_whereis_msg = N_("Search for a string");
    const char *nano_browser_refresh_msg = N_("Refresh the file list");
542
#ifndef NANO_TINY
543
544
    const char *nano_browser_lefthand_msg = N_("Go to lefthand column");
    const char *nano_browser_righthand_msg = N_("Go to righthand column");
545
546
    const char *nano_browser_toprow_msg = N_("Go to first row in this column");
    const char *nano_browser_bottomrow_msg = N_("Go to last row in this column");
547
#endif
548
#endif
549
550
    const char *nano_prevpage_msg = N_("Go one screenful up");
    const char *nano_nextpage_msg = N_("Go one screenful down");
551
552
553
554
    const char *nano_cut_msg =
	N_("Cut the current line and store it in the cutbuffer");
    const char *nano_uncut_msg =
	N_("Uncut from the cutbuffer into the current line");
555
    const char *nano_cursorpos_msg = N_("Display the position of the cursor");
556
#ifndef DISABLE_SPELLER
557
    const char *nano_spell_msg = N_("Invoke the spell checker, if available");
558
#endif
559
    const char *nano_replace_msg = N_("Replace a string or a regular expression");
Benno Schulenberg's avatar
Benno Schulenberg committed
560
    const char *nano_gotoline_msg = N_("Go to line and column number");
561
    const char *nano_whereis_next_msg = N_("Repeat the last search");
562
#ifndef NANO_TINY
563
    const char *nano_mark_msg = N_("Mark text starting from the cursor position");
564
565
    const char *nano_copy_msg =
	N_("Copy the current line and store it in the cutbuffer");
566
567
    const char *nano_indent_msg = N_("Indent the current line");
    const char *nano_unindent_msg = N_("Unindent the current line");
568
569
    const char *nano_undo_msg = N_("Undo the last operation");
    const char *nano_redo_msg = N_("Redo the last undone operation");
570
#endif
571
    const char *nano_back_msg = N_("Go back one character");
572
    const char *nano_forward_msg = N_("Go forward one character");
573
    const char *nano_prevword_msg = N_("Go back one word");
574
    const char *nano_nextword_msg = N_("Go forward one word");
575
576
577
578
    const char *nano_prevline_msg = N_("Go to previous line");
    const char *nano_nextline_msg = N_("Go to next line");
    const char *nano_home_msg = N_("Go to beginning of current line");
    const char *nano_end_msg = N_("Go to end of current line");
579
580
    const char *nano_prevblock_msg = N_("Go to previous block of text");
    const char *nano_nextblock_msg = N_("Go to next block of text");
581
582
#ifndef DISABLE_JUSTIFY
    const char *nano_parabegin_msg =
583
	N_("Go to beginning of paragraph; then of previous paragraph");
584
    const char *nano_paraend_msg =
585
	N_("Go just beyond end of paragraph; then of next paragraph");
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
586
#endif
587
588
    const char *nano_firstline_msg = N_("Go to the first line of the file");
    const char *nano_lastline_msg = N_("Go to the last line of the file");
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
589
#ifndef NANO_TINY
590
    const char *nano_bracket_msg = N_("Go to the matching bracket");
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
591
592
593
594
    const char *nano_scrollup_msg =
	N_("Scroll up one line without scrolling the cursor");
    const char *nano_scrolldown_msg =
	N_("Scroll down one line without scrolling the cursor");
595
#endif
596
#ifdef ENABLE_MULTIBUFFER
597
598
599
600
601
602
603
    const char *nano_prevfile_msg = N_("Switch to the previous file buffer");
    const char *nano_nextfile_msg = N_("Switch to the next file buffer");
#endif
    const char *nano_verbatim_msg = N_("Insert the next keystroke verbatim");
    const char *nano_tab_msg = N_("Insert a tab at the cursor position");
    const char *nano_enter_msg = N_("Insert a newline at the cursor position");
    const char *nano_delete_msg = N_("Delete the character under the cursor");
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
604
605
    const char *nano_backspace_msg =
	N_("Delete the character to the left of the cursor");
606
#ifndef NANO_TINY
607
608
609
610
    const char *nano_cut_word_left_msg =
	N_("Cut backward from cursor to word start");
    const char *nano_cut_word_right_msg =
	N_("Cut forward from cursor to next word start");
611
    const char *nano_cut_till_eof_msg =
612
613
	N_("Cut from the cursor position to the end of the file");
#endif
614
#ifndef DISABLE_JUSTIFY
615
    const char *nano_justify_msg = N_("Justify the current paragraph");
616
    const char *nano_fulljustify_msg = N_("Justify the entire file");
617
#endif
618
#ifndef NANO_TINY
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
619
620
    const char *nano_wordcount_msg =
	N_("Count the number of words, lines, and characters");
621
#endif
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
622
623
    const char *nano_refresh_msg =
	N_("Refresh (redraw) the current screen");
624
    const char *nano_suspend_msg =
625
	N_("Suspend the editor (if suspension is enabled)");
626
627
628
#ifdef ENABLE_WORDCOMPLETION
    const char *nano_completion_msg = N_("Try and complete the current word");
#endif
629
630
631
632
#ifdef ENABLE_COMMENT
    const char *nano_comment_msg =
	N_("Comment/uncomment the current line or marked lines");
#endif
633
#ifndef NANO_TINY
634
    const char *nano_savefile_msg = N_("Save file without prompting");
635
636
    const char *nano_findprev_msg = N_("Search next occurrence backward");
    const char *nano_findnext_msg = N_("Search next occurrence forward");
637
638
    const char *nano_recordmacro_msg = N_("Start/stop recording a macro");
    const char *nano_runmacro_msg = N_("Run the last recorded macro");
639
#endif
640
    const char *nano_case_msg =
641
	N_("Toggle the case sensitivity of the search");
642
    const char *nano_reverse_msg =
643
644
645
	N_("Reverse the direction of the search");
    const char *nano_regexp_msg =
	N_("Toggle the use of regular expressions");
646
#ifndef DISABLE_HISTORIES
647
    const char *nano_prev_history_msg =
648
	N_("Recall the previous search/replace string");
649
    const char *nano_next_history_msg =
650
	N_("Recall the next search/replace string");
651
#endif
652
#ifndef NANO_TINY
653
654
655
656
    const char *nano_dos_msg = N_("Toggle the use of DOS format");
    const char *nano_mac_msg = N_("Toggle the use of Mac format");
    const char *nano_append_msg = N_("Toggle appending");
    const char *nano_prepend_msg = N_("Toggle prepending");
657
    const char *nano_backup_msg = N_("Toggle backing up of the original file");
658
    const char *nano_execute_msg = N_("Execute external command");
659
#endif
660
#ifdef ENABLE_MULTIBUFFER
661
662
663
    const char *nano_newbuffer_msg = N_("Toggle the use of a new buffer");
#endif
    const char *nano_discard_buffer_msg = N_("Close buffer without saving it");
664
#ifdef ENABLE_BROWSER
665
    const char *nano_tofiles_msg = N_("Go to file browser");
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
666
    const char *nano_exitbrowser_msg = N_("Exit from the file browser");
667
668
    const char *nano_firstfile_msg = N_("Go to the first file in the list");
    const char *nano_lastfile_msg = N_("Go to the last file in the list");
669
    const char *nano_backfile_msg = N_("Go to the previous file in the list");
670
    const char *nano_forwardfile_msg = N_("Go to the next file in the list");
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
671
    const char *nano_gotodir_msg = N_("Go to directory");
Chris Allegretta's avatar
Chris Allegretta committed
672
#endif
673
#ifndef DISABLE_COLOR
674
    const char *nano_lint_msg = N_("Invoke the linter, if available");
675
676
    const char *nano_prevlint_msg = N_("Go to previous linter msg");
    const char *nano_nextlint_msg = N_("Go to next linter msg");
677
#ifndef DISABLE_SPELLER
678
    const char *nano_formatter_msg = N_("Invoke formatter, if available");
679
#endif
680
#endif
681
#endif /* ENABLE_HELP */
Chris Allegretta's avatar
Chris Allegretta committed
682

683
#ifdef ENABLE_HELP
684
#define IFSCHELP(help) help
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
685
#else
686
#define IFSCHELP(help) ""
687
#endif
688

Benno Schulenberg's avatar
Benno Schulenberg committed
689
690
    /* Start populating the different menus with functions. */

691
    add_to_funcs(do_help_void, MMOST,
692
	/* TRANSLATORS: Try to keep the following strings at most 10 characters. */
693
	N_("Get Help"), IFSCHELP(nano_help_msg), TOGETHER, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
694

695
    add_to_funcs(do_cancel, ((MMOST & ~MMAIN & ~MBROWSER) | MYESNO),
696
	N_("Cancel"), IFSCHELP(nano_cancel_msg), BLANKAFTER, VIEW);
697

698
    add_to_funcs(do_exit, MMAIN,
699
	exit_tag, IFSCHELP(nano_exit_msg), TOGETHER, VIEW);
700
701
    /* Remember the entry for Exit, to be able to replace it with Close. */
    exitfunc = tailfunc;
Chris Allegretta's avatar
Chris Allegretta committed
702

703
#ifdef ENABLE_BROWSER
704
    add_to_funcs(do_exit, MBROWSER,
705
	exit_tag, IFSCHELP(nano_exitbrowser_msg), TOGETHER, VIEW);
706
#endif
Chris Allegretta's avatar
Chris Allegretta committed
707

708
    add_to_funcs(do_writeout_void, MMAIN,
709
	N_("Write Out"), IFSCHELP(nano_writeout_msg), TOGETHER, NOVIEW);
710

711
712
713
714
715
716
717
#ifndef DISABLE_JUSTIFY
    if (!ISSET(RESTRICTED)) {
#else
    /* If we can't replace Insert with Justify, show Insert anyway, to
     * keep the help items nicely paired also in restricted mode.  */
    if (TRUE) {
#endif
718
719
	add_to_funcs(do_insertfile_void, MMAIN,
		read_file_tag, IFSCHELP(nano_insert_msg), BLANKAFTER,
720
721
		/* We allow inserting files in view mode if multibuffer mode
		 * is switched on, so that we can view multiple files. */
722
#ifdef ENABLE_MULTIBUFFER
723
		VIEW);
724
#else
725
		NOVIEW);
726
#endif
727
728
    } else {
#ifndef DISABLE_JUSTIFY
729
	add_to_funcs(do_justify_void, MMAIN,
730
		justify_tag, IFSCHELP(nano_justify_msg), BLANKAFTER, NOVIEW);
731
732
#endif
    }
Chris Allegretta's avatar
Chris Allegretta committed
733

734
    add_to_funcs(do_search_forward, MMAIN,
735
	whereis_tag, IFSCHELP(nano_whereis_msg), TOGETHER, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
736

737
    add_to_funcs(do_replace, MMAIN,
738
	replace_tag, IFSCHELP(nano_replace_msg), TOGETHER, NOVIEW);
739

740
#ifdef ENABLE_BROWSER
741
    add_to_funcs(do_search, MBROWSER,
742
	whereis_tag, IFSCHELP(nano_browser_whereis_msg), TOGETHER, VIEW);
743

744
745
746
    add_to_funcs(do_research, MBROWSER,
	whereis_next_tag, IFSCHELP(nano_whereis_next_msg), BLANKAFTER, VIEW);

747
    add_to_funcs(goto_dir_void, MBROWSER,
748
749
750
751
	N_("Go To Dir"), IFSCHELP(nano_gotodir_msg), TOGETHER, VIEW);

    add_to_funcs(total_refresh, MBROWSER,
	refresh_tag, IFSCHELP(nano_browser_refresh_msg), BLANKAFTER, VIEW);
752
753
#endif

754
#ifdef ENABLE_HELP
755
756
    /* The description ("x") and blank_after (0) are irrelevant,
     * because the help viewer does not have a help text. */
757
    add_to_funcs(total_refresh, MHELP, refresh_tag, "x", 0, VIEW);
758
    add_to_funcs(do_exit, MHELP, close_tag, "x", 0, VIEW);
759

760
761
    add_to_funcs(do_search, MHELP, whereis_tag, "x", 0, VIEW);
    add_to_funcs(do_research, MHELP, whereis_next_tag, "x", 0, VIEW);
762
763
#endif

764
    add_to_funcs(do_cut_text_void, MMAIN,
765
	N_("Cut Text"), IFSCHELP(nano_cut_msg), TOGETHER, NOVIEW);
Chris Allegretta's avatar
Chris Allegretta committed
766

767
    add_to_funcs(do_uncut_text, MMAIN,
768
	uncut_tag, IFSCHELP(nano_uncut_msg), BLANKAFTER, NOVIEW);
769
    /* Remember the entry for Uncut, to be able to replace it with Unjustify. */
770
    uncutfunc = tailfunc;
Chris Allegretta's avatar
Chris Allegretta committed
771

772
    if (!ISSET(RESTRICTED)) {
773
#ifndef DISABLE_JUSTIFY
774
	add_to_funcs(do_justify_void, MMAIN,
775
		justify_tag, IFSCHELP(nano_justify_msg), TOGETHER, NOVIEW);
Chris Allegretta's avatar
Chris Allegretta committed
776
#endif
Chris Allegretta's avatar
Chris Allegretta committed
777

778
#ifndef DISABLE_SPELLER
779
780
	add_to_funcs(do_spell, MMAIN,
		N_("To Spell"), IFSCHELP(nano_spell_msg), TOGETHER, NOVIEW);
781
#endif
782
#ifndef DISABLE_COLOR
783
784
	add_to_funcs(do_linter, MMAIN,
		N_("To Linter"), IFSCHELP(nano_lint_msg), TOGETHER, NOVIEW);
785
#ifndef DISABLE_SPELLER
786
787
	add_to_funcs(do_formatter, MMAIN,
		N_("Formatter"), IFSCHELP(nano_formatter_msg), BLANKAFTER, NOVIEW);
788
#endif
789
#endif
790
    }
791

792
793
794
795
796
797
798
799
800
801
802
    add_to_funcs(do_cursorpos_void, MMAIN,
	N_("Cur Pos"), IFSCHELP(nano_cursorpos_msg), TOGETHER, VIEW);

#if (!defined(DISABLE_JUSTIFY) && (!defined(DISABLE_SPELLER) || !defined(DISABLE_COLOR)) || \
	defined(DISABLE_JUSTIFY) && defined(DISABLE_SPELLER) && defined(DISABLE_COLOR))
    /* Conditionally placing this one here or further on, to keep the
     * help items nicely paired in most conditions. */
    add_to_funcs(do_gotolinecolumn_void, MMAIN,
	gotoline_tag, IFSCHELP(nano_gotoline_msg), BLANKAFTER, VIEW);
#endif

803
804
805
806
807
808
809
810
811
812
813
814
#ifndef NANO_TINY
    add_to_funcs(do_undo, MMAIN,
	N_("Undo"), IFSCHELP(nano_undo_msg), TOGETHER, NOVIEW);
    add_to_funcs(do_redo, MMAIN,
	N_("Redo"), IFSCHELP(nano_redo_msg), BLANKAFTER, NOVIEW);

    add_to_funcs(do_mark, MMAIN,
	N_("Mark Text"), IFSCHELP(nano_mark_msg), TOGETHER, VIEW);
    add_to_funcs(do_copy_text, MMAIN,
	N_("Copy Text"), IFSCHELP(nano_copy_msg), BLANKAFTER, NOVIEW);
#endif

815
    add_to_funcs(case_sens_void, MWHEREIS|MREPLACE,
816
	N_("Case Sens"), IFSCHELP(nano_case_msg), TOGETHER, VIEW);
817
    add_to_funcs(regexp_void, MWHEREIS|MREPLACE,
818
	N_("Regexp"), IFSCHELP(nano_regexp_msg), TOGETHER, VIEW);
819
    add_to_funcs(backwards_void, MWHEREIS|MREPLACE,
820
	N_("Backwards"), IFSCHELP(nano_reverse_msg), TOGETHER, VIEW);
821

822
    add_to_funcs(flip_replace, MWHEREIS,
823
	replace_tag, IFSCHELP(nano_replace_msg), BLANKAFTER, VIEW);
824

825
    add_to_funcs(flip_replace, MREPLACE,
826
	N_("No Replace"), IFSCHELP(nano_whereis_msg), BLANKAFTER, VIEW);
827
828

#ifndef DISABLE_JUSTIFY
829
    add_to_funcs(do_full_justify, MWHEREIS,
830
	fulljustify_tag, IFSCHELP(nano_fulljustify_msg), TOGETHER, NOVIEW);
831

832
    add_to_funcs(do_gotolinecolumn_void, MWHEREIS,
833
	gotoline_tag, IFSCHELP(nano_gotoline_msg), BLANKAFTER, VIEW);
834
#endif
835

836
#ifndef NANO_TINY
837
838
839
    add_to_funcs(do_find_bracket, MMAIN,
	N_("To Bracket"), IFSCHELP(nano_bracket_msg), BLANKAFTER, VIEW);

840
    add_to_funcs(do_research, MMAIN,
841
	whereis_next_tag, IFSCHELP(nano_whereis_next_msg), TOGETHER, VIEW);
842

843
844
845
846
    add_to_funcs(do_findprevious, MMAIN,
	N_("Previous"), IFSCHELP(nano_findprev_msg), TOGETHER, VIEW);
    add_to_funcs(do_findnext, MMAIN,
	N_("Next"), IFSCHELP(nano_findnext_msg), BLANKAFTER, VIEW);
847
#endif /* !NANO_TINY */
848

849
    add_to_funcs(do_left, MMAIN,
850
	N_("Back"), IFSCHELP(nano_back_msg), TOGETHER, VIEW);
851
    add_to_funcs(do_right, MMAIN,
852
	N_("Forward"), IFSCHELP(nano_forward_msg), TOGETHER, VIEW);
853
#ifdef ENABLE_BROWSER
854
    add_to_funcs(do_left, MBROWSER,
855
	N_("Back"), IFSCHELP(nano_backfile_msg), TOGETHER, VIEW);
856
    add_to_funcs(do_right, MBROWSER,
857
	N_("Forward"), IFSCHELP(nano_forwardfile_msg), TOGETHER, VIEW);
858
859
#endif

860
    add_to_funcs(do_prev_word_void, MMAIN,
861
	N_("Prev Word"), IFSCHELP(nano_prevword_msg), TOGETHER, VIEW);
862
    add_to_funcs(do_next_word_void, MMAIN,
863
	N_("Next Word"), IFSCHELP(nano_nextword_msg), TOGETHER, VIEW);
864

865
    add_to_funcs(do_home, MMAIN,
866
	N_("Home"), IFSCHELP(nano_home_msg), TOGETHER, VIEW);
867
    add_to_funcs(do_end, MMAIN,
868
	N_("End"), IFSCHELP(nano_end_msg), BLANKAFTER, VIEW);
869

870
    add_to_funcs(do_up_void, MMAIN|MHELP|MBROWSER,
871
	prev_line_tag, IFSCHELP(nano_prevline_msg), TOGETHER, VIEW);
872
    add_to_funcs(do_down_void, MMAIN|MHELP|MBROWSER,
873
874
875
876
877
878
879
	next_line_tag, IFSCHELP(nano_nextline_msg), TOGETHER, VIEW);
#ifndef NANO_TINY
    add_to_funcs(do_scroll_up, MMAIN,
	N_("Scroll Up"), IFSCHELP(nano_scrollup_msg), TOGETHER, VIEW);
    add_to_funcs(do_scroll_down, MMAIN,
	N_("Scroll Down"), IFSCHELP(nano_scrolldown_msg), BLANKAFTER, VIEW);
#endif
880

881
882
883
884
    add_to_funcs(do_prev_block, MMAIN,
	N_("Prev Block"), IFSCHELP(nano_prevblock_msg), TOGETHER, VIEW);
    add_to_funcs(do_next_block, MMAIN,
	N_("Next Block"), IFSCHELP(nano_nextblock_msg), TOGETHER, VIEW);
885
#ifndef DISABLE_JUSTIFY
886
    add_to_funcs(do_para_begin_void, MMAIN|MWHEREIS,
887
	N_("Beg of Par"), IFSCHELP(nano_parabegin_msg), TOGETHER, VIEW);
888
    add_to_funcs(do_para_end_void, MMAIN|MWHEREIS,
889
	N_("End of Par"), IFSCHELP(nano_paraend_msg), BLANKAFTER, VIEW);
890
#endif
891

892
893
894
895
896
897
898
899
900
    add_to_funcs(do_page_up, MMAIN|MHELP,
	prev_page_tag, IFSCHELP(nano_prevpage_msg), TOGETHER, VIEW);
    add_to_funcs(do_page_down, MMAIN|MHELP,
	next_page_tag, IFSCHELP(nano_nextpage_msg), TOGETHER, VIEW);

    add_to_funcs(do_first_line, MMAIN|MHELP|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE,
	N_("First Line"), IFSCHELP(nano_firstline_msg), TOGETHER, VIEW);
    add_to_funcs(do_last_line, MMAIN|MHELP|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE,
	N_("Last Line"), IFSCHELP(nano_lastline_msg), BLANKAFTER, VIEW);
901

902
#ifdef ENABLE_MULTIBUFFER
903
    add_to_funcs(switch_to_prev_buffer, MMAIN,
904
	N_("Prev File"), IFSCHELP(nano_prevfile_msg), TOGETHER, VIEW);
905
    add_to_funcs(switch_to_next_buffer, MMAIN,
906
	N_("Next File"), IFSCHELP(nano_nextfile_msg), BLANKAFTER, VIEW);
907
908
#endif

909
910
#if (defined(DISABLE_JUSTIFY) && (!defined(DISABLE_SPELLER) || !defined(DISABLE_COLOR)) || \
	!defined(DISABLE_JUSTIFY) && defined(DISABLE_SPELLER) && defined(DISABLE_COLOR))
911
    add_to_funcs(do_gotolinecolumn_void, MMAIN,
912
	gotoline_tag, IFSCHELP(nano_gotoline_msg), BLANKAFTER, VIEW);
913
914
#endif

915
916
917
918
919
920
#ifdef NANO_TINY
    /* Place this one here only in the tiny version; otherwise further up. */
    add_to_funcs(do_research, MMAIN,
	whereis_next_tag, IFSCHELP(nano_whereis_next_msg), TOGETHER, VIEW);
#endif

921
    add_to_funcs(do_tab, MMAIN,
922
	N_("Tab"), IFSCHELP(nano_tab_msg), TOGETHER, NOVIEW);
923
    add_to_funcs(do_enter, MMAIN,
924
925
	N_("Enter"), IFSCHELP(nano_enter_msg), BLANKAFTER, NOVIEW);

926
    add_to_funcs(do_delete, MMAIN,
927
	N_("Delete"), IFSCHELP(nano_delete_msg), TOGETHER, NOVIEW);
928
929
    add_to_funcs(do_backspace, MMAIN,
	N_("Backspace"), IFSCHELP(nano_backspace_msg),
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
930
#ifndef NANO_TINY
931
	TOGETHER,
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
932
#else
933
	BLANKAFTER,
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
934
#endif
935
936
	NOVIEW);

937
#ifndef NANO_TINY
938
    add_to_funcs(do_cut_prev_word, MMAIN,
939
	/* TRANSLATORS: The next two strings refer to cutting words. */
940
941
942
	N_("Cut Left"), IFSCHELP(nano_cut_word_left_msg), TOGETHER, NOVIEW);
    add_to_funcs(do_cut_next_word, MMAIN,
	N_("Cut Right"), IFSCHELP(nano_cut_word_right_msg), TOGETHER, NOVIEW);
943
    add_to_funcs(do_cut_till_eof, MMAIN,
944
	N_("CutTillEnd"), IFSCHELP(nano_cut_till_eof_msg), BLANKAFTER, NOVIEW);
945
#endif
Chris Allegretta's avatar
Chris Allegretta committed
946

947
#ifndef DISABLE_JUSTIFY
948
    add_to_funcs(do_full_justify, MMAIN,
949
	fulljustify_tag, IFSCHELP(nano_fulljustify_msg), TOGETHER, NOVIEW);
950
951
#endif

952
#ifndef NANO_TINY
953
    add_to_funcs(do_wordlinechar_count, MMAIN,
954
	N_("Word Count"), IFSCHELP(nano_wordcount_msg), TOGETHER, VIEW);
955
#endif
956

957
958
959
    add_to_funcs(do_verbatim_input, MMAIN,
	N_("Verbatim"), IFSCHELP(nano_verbatim_msg), BLANKAFTER, NOVIEW);

960
    add_to_funcs(total_refresh, MMAIN,
961
	refresh_tag, IFSCHELP(nano_refresh_msg), TOGETHER, VIEW);
962

963
    add_to_funcs(do_suspend_void, MMAIN,
964
	N_("Suspend"), IFSCHELP(nano_suspend_msg), BLANKAFTER, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
965

966
#ifndef NANO_TINY
967
    add_to_funcs(do_indent, MMAIN,
968
	N_("Indent Text"), IFSCHELP(nano_indent_msg), TOGETHER, NOVIEW);
969
    add_to_funcs(do_unindent, MMAIN,
970
971
	N_("Unindent Text"), IFSCHELP(nano_unindent_msg), BLANKAFTER, NOVIEW);
#endif
972
973
974
975
#ifdef ENABLE_WORDCOMPLETION
    add_to_funcs(complete_a_word, MMAIN,
	N_("Complete"), IFSCHELP(nano_completion_msg), TOGETHER, NOVIEW);
#endif
976
977
978
979
#ifdef ENABLE_COMMENT
    add_to_funcs(do_comment, MMAIN,
	N_("Comment Lines"), IFSCHELP(nano_comment_msg), BLANKAFTER, NOVIEW);
#endif
980
#ifndef NANO_TINY
981
982
983
984
985
    add_to_funcs(record_macro, MMAIN,
	N_("Record"), IFSCHELP(nano_recordmacro_msg), TOGETHER, VIEW);
    add_to_funcs(run_macro, MMAIN,
	N_("Run Macro"), IFSCHELP(nano_runmacro_msg), BLANKAFTER, VIEW);

986
987
988
    add_to_funcs(do_search_backward, MMAIN,
	N_("Where Was"), IFSCHELP(N_(nano_wherewas_msg)), BLANKAFTER, VIEW);

989
990
991
992
    add_to_funcs(do_savefile, MMAIN,
	N_("Save"), IFSCHELP(nano_savefile_msg), BLANKAFTER, NOVIEW);
#endif

993
#ifndef DISABLE_HISTORIES
994
    add_to_funcs(get_history_older_void,
995
	(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE),
996
	N_("PrevHstory"), IFSCHELP(nano_prev_history_msg), TOGETHER, VIEW);
997
    add_to_funcs(get_history_newer_void,
998
	(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE),
999
1000
1001
	N_("NextHstory"), IFSCHELP(nano_next_history_msg), BLANKAFTER, VIEW);
#endif

1002
#ifdef DISABLE_JUSTIFY
1003
1004
    add_to_funcs(do_gotolinecolumn_void, MWHEREIS,
	gotoline_tag, IFSCHELP(nano_gotoline_msg), BLANKAFTER, VIEW);
1005
#endif
1006

1007
    add_to_funcs(gototext_void, MGOTOLINE,
1008
	N_("Go To Text"), IFSCHELP(nano_whereis_msg), BLANKAFTER, VIEW);
1009

1010
#ifndef NANO_TINY
1011
    add_to_funcs(dos_format_void, MWRITEFILE,
1012
	N_("DOS Format"), IFSCHELP(nano_dos_msg), TOGETHER, NOVIEW);
1013
    add_to_funcs(mac_format_void, MWRITEFILE,
1014
1015
1016
1017
1018
1019
	N_("Mac Format"), IFSCHELP(nano_mac_msg), TOGETHER, NOVIEW);

    /* If we're using restricted mode, the Append, Prepend, and Backup toggles
     * are disabled.  The first and second are not useful as they only allow
     * reduplicating the current file, and the third is not allowed as it
     * would write to a file not specified on the command line. */
1020
    if (!ISSET(RESTRICTED)) {
1021
1022
1023
1024
	add_to_funcs(append_void, MWRITEFILE,
	    N_("Append"), IFSCHELP(nano_append_msg), TOGETHER, NOVIEW);
	add_to_funcs(prepend_void, MWRITEFILE,
	    N_("Prepend"), IFSCHELP(nano_prepend_msg), TOGETHER, NOVIEW);
1025

1026
	add_to_funcs(backup_file_void, MWRITEFILE,
1027
	    N_("Backup File"), IFSCHELP(nano_backup_msg), BLANKAFTER, NOVIEW);
1028
    }
1029

1030
1031
1032
    /* If we're using restricted mode, file insertion is disabled, and
     * thus command execution and the multibuffer toggle have no place. */
    if (!ISSET(RESTRICTED)) {
1033
	add_to_funcs(flip_execute, MINSERTFILE,
1034
	    N_("Execute Command"), IFSCHELP(nano_execute_msg), TOGETHER, NOVIEW);
1035

1036
	add_to_funcs(flip_execute, MEXTCMD,
1037
	    read_file_tag, IFSCHELP(nano_insert_msg), TOGETHER, NOVIEW);
1038
1039
    }
#endif /* !NANO_TINY */
1040
#ifdef ENABLE_MULTIBUFFER
1041
    if (!ISSET(RESTRICTED))
1042
	add_to_funcs(flip_newbuffer, MINSERTFILE|MEXTCMD,
1043
	    N_("New Buffer"), IFSCHELP(nano_newbuffer_msg), TOGETHER, NOVIEW);
1044
#endif
1045

1046
#ifdef ENABLE_BROWSER
1047
1048
    if (!ISSET(RESTRICTED))
	add_to_funcs(to_files_void, MWRITEFILE|MINSERTFILE,
1049
	    N_("To Files"), IFSCHELP(nano_tofiles_msg), TOGETHER, VIEW);
1050

1051
1052
1053
1054
1055
    add_to_funcs(do_page_up, MBROWSER,
	prev_page_tag, IFSCHELP(nano_prevpage_msg), TOGETHER, VIEW);
    add_to_funcs(do_page_down, MBROWSER,
	next_page_tag, IFSCHELP(nano_nextpage_msg), TOGETHER, VIEW);

Benno Schulenberg's avatar
Benno Schulenberg committed
1056
    add_to_funcs(do_first_file, (MBROWSER|MWHEREISFILE),
1057
	N_("First File"), IFSCHELP(nano_firstfile_msg), TOGETHER, VIEW);
Benno Schulenberg's avatar
Benno Schulenberg committed
1058
    add_to_funcs(do_last_file, (MBROWSER|MWHEREISFILE),
1059
	N_("Last File"), IFSCHELP(nano_lastfile_msg), BLANKAFTER, VIEW);
1060
#ifndef NANO_TINY
1061
1062
1063
    add_to_funcs(do_prev_word_void, MBROWSER,
	N_("Left Column"), IFSCHELP(nano_browser_lefthand_msg), TOGETHER, VIEW);
    add_to_funcs(do_next_word_void, MBROWSER,
1064
1065
1066
1067
1068
	N_("Right Column"), IFSCHELP(nano_browser_righthand_msg), TOGETHER, VIEW);
    add_to_funcs(do_prev_block, MBROWSER,
	N_("Top Row"), IFSCHELP(nano_browser_toprow_msg), TOGETHER, VIEW);
    add_to_funcs(do_next_block, MBROWSER,
	N_("Bottom Row"), IFSCHELP(nano_browser_bottomrow_msg), BLANKAFTER, VIEW);
1069
#endif
1070
1071
1072
1073
#endif /* ENABLE_BROWSER */

    add_to_funcs(discard_buffer, MWRITEFILE,
	N_("Discard buffer"), IFSCHELP(nano_discard_buffer_msg), BLANKAFTER, NOVIEW);
1074
1075
1076

#ifndef DISABLE_COLOR
    add_to_funcs(do_page_up, MLINTER,
1077
	/* TRANSLATORS: Try to keep the next two strings at most 20 characters. */
1078
	N_("Prev Lint Msg"), IFSCHELP(nano_prevlint_msg), TOGETHER, VIEW);
1079
    add_to_funcs(do_page_down, MLINTER,
1080
	N_("Next Lint Msg"), IFSCHELP(nano_nextlint_msg), TOGETHER, VIEW);
1081
1082
#endif

Benno Schulenberg's avatar
Benno Schulenberg committed
1083
1084
    /* Start associating key combos with functions in specific menus. */

1085
1086
    add_to_sclist(MMOST & ~MFINDINHELP, "^G", 0, do_help_void, 0);
    add_to_sclist(MMOST & ~MFINDINHELP, "F1", 0, do_help_void, 0);
1087
1088
    add_to_sclist(MMAIN|MHELP|MBROWSER, "^X", 0, do_exit, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "F2", 0, do_exit, 0);
1089
    add_to_sclist(MMAIN, "^S", 0, do_savefile, 0);
1090
1091
1092
1093
1094
    add_to_sclist(MMAIN, "^O", 0, do_writeout_void, 0);
    add_to_sclist(MMAIN, "F3", 0, do_writeout_void, 0);
    add_to_sclist(MMAIN, "^R", 0, do_insertfile_void, 0);
    add_to_sclist(MMAIN, "F5", 0, do_insertfile_void, 0);
    add_to_sclist(MMAIN, "Ins", 0, do_insertfile_void, 0);
1095
    add_to_sclist(MMAIN, "^Q", 0, do_search_backward, 0);
1096
1097
    add_to_sclist(MMAIN, "^W", 0, do_search_forward, 0);
    add_to_sclist(MMAIN, "F6", 0, do_search_forward, 0);
1098
1099
1100
1101
1102
    add_to_sclist(MMAIN, "^\\", 0, do_replace, 0);
    add_to_sclist(MMAIN, "M-R", 0, do_replace, 0);
    add_to_sclist(MMAIN, "F14", 0, do_replace, 0);
    add_to_sclist(MMOST, "^K", 0, do_cut_text_void, 0);
    add_to_sclist(MMOST, "F9", 0, do_cut_text_void, 0);
1103
1104
    add_to_sclist(MMOST, "^U", 0, do_uncut_text, 0);
    add_to_sclist(MMOST, "F10", 0, do_uncut_text, 0);
1105
#ifndef DISABLE_JUSTIFY
1106
1107
    add_to_sclist(MMAIN, "^J", 0, do_justify_void, 0);
    add_to_sclist(MMAIN, "F4", 0, do_justify_void, 0);
1108
#endif
1109
#ifndef DISABLE_SPELLER
1110
1111
    add_to_sclist(MMAIN, "^T", 0, do_spell, 0);
    add_to_sclist(MMAIN, "F12", 0, do_spell, 0);
1112
1113
#else
#ifndef DISABLE_COLOR
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
    add_to_sclist(MMAIN, "^T", 0, do_linter, 0);
    add_to_sclist(MMAIN, "F12", 0, do_linter, 0);
#endif
#endif
    add_to_sclist(MMAIN, "^C", 0, do_cursorpos_void, 0);
    add_to_sclist(MMAIN, "F11", 0, do_cursorpos_void, 0);
    add_to_sclist(MMAIN, "^_", 0, do_gotolinecolumn_void, 0);
    add_to_sclist(MMAIN, "M-G", 0, do_gotolinecolumn_void, 0);
    add_to_sclist(MMAIN, "F13", 0, do_gotolinecolumn_void, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "^Y", 0, do_page_up, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "F7", 0, do_page_up, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "PgUp", KEY_PPAGE, do_page_up, 0);
1126
    add_to_sclist(MHELP|MBROWSER, "Bsp", KEY_BACKSPACE, do_page_up, 0);
1127
1128
1129
1130
    add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "^V", 0, do_page_down, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "F8", 0, do_page_down, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "PgDn", KEY_NPAGE, do_page_down, 0);
    add_to_sclist(MMAIN|MHELP, "M-\\", 0, do_first_line, 0);
1131
    add_to_sclist(MMAIN|MHELP, "^Home", CONTROL_HOME, do_first_line, 0);
1132
1133
    add_to_sclist(MMAIN|MHELP, "M-|", 0, do_first_line, 0);
    add_to_sclist(MMAIN|MHELP, "M-/", 0, do_last_line, 0);
1134
    add_to_sclist(MMAIN|MHELP, "^End", CONTROL_END, do_last_line, 0);
1135
    add_to_sclist(MMAIN|MHELP, "M-?", 0, do_last_line, 0);
1136
1137
    add_to_sclist(MHELP|MBROWSER, "^W", 0, do_search, 0);
    add_to_sclist(MHELP|MBROWSER, "F6", 0, do_search, 0);
1138
1139
    add_to_sclist(MMAIN|MHELP|MBROWSER, "M-W", 0, do_research, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "F16", 0, do_research, 0);
1140
#ifndef NANO_TINY
1141
1142
    add_to_sclist(MMAIN, "M-]", 0, do_find_bracket, 0);
    add_to_sclist(MMAIN, "M-A", 0, do_mark, 0);
1143
    add_to_sclist(MMAIN, "^6", 0, do_mark, 0);
1144
    add_to_sclist(MMAIN, "^^", 0, do_mark, 0);
1145
    add_to_sclist(MMAIN, "F15", 0, do_mark, 0);
1146
    add_to_sclist(MMAIN, "M-6", 0, do_copy_text, 0);
1147
    add_to_sclist(MMAIN, "M-^", 0, do_copy_text, 0);
1148
1149
    add_to_sclist(MMAIN, "M-}", 0, do_indent, 0);
    add_to_sclist(MMAIN, "M-{", 0, do_unindent, 0);
1150
1151
    add_to_sclist(MMAIN, "M-:", 0, record_macro, 0);
    add_to_sclist(MMAIN, "M-;", 0, run_macro, 0);
1152
1153
    add_to_sclist(MMAIN, "M-U", 0, do_undo, 0);
    add_to_sclist(MMAIN, "M-E", 0, do_redo, 0);
1154
1155
#endif
#ifdef ENABLE_WORDCOMPLETION
1156
    add_to_sclist(MMAIN, "^]", 0, complete_a_word, 0);
1157
1158
#endif
#ifdef ENABLE_COMMENT
1159
    add_to_sclist(MMAIN, "M-3", 0, do_comment, 0);
1160
#endif
1161
1162
    add_to_sclist(MMOST, "^B", 0, do_left, 0);
    add_to_sclist(MMOST, "^F", 0, do_right, 0);
1163
#ifdef ENABLE_UTF8
1164
    if (using_utf8()) {
1165
1166
	add_to_sclist(MMOST, "\xE2\x86\x90", KEY_LEFT, do_left, 0);
	add_to_sclist(MMOST, "\xE2\x86\x92", KEY_RIGHT, do_right, 0);
1167
1168
	add_to_sclist(MSOME, "^\xE2\x86\x90", CONTROL_LEFT, do_prev_word_void, 0);
	add_to_sclist(MSOME, "^\xE2\x86\x92", CONTROL_RIGHT, do_next_word_void, 0);
1169
#ifdef ENABLE_MULTIBUFFER
1170
1171
	add_to_sclist(MMAIN, "M-\xE2\x86\x90", ALT_LEFT, switch_to_prev_buffer, 0);
	add_to_sclist(MMAIN, "M-\xE2\x86\x92", ALT_RIGHT, switch_to_next_buffer, 0);
1172
#endif
1173
#ifndef NANO_TINY
1174
1175
	add_to_sclist(MMAIN|MHELP|MBROWSER, "M-\xE2\x86\x91", ALT_UP, do_findprevious, 0);
	add_to_sclist(MMAIN|MHELP|MBROWSER, "M-\xE2\x86\x93", ALT_DOWN, do_findnext, 0);
1176
#endif
1177
1178
1179
    } else
#endif
    {
1180
1181
	add_to_sclist(MMOST, "Left", KEY_LEFT, do_left, 0);
	add_to_sclist(MMOST, "Right", KEY_RIGHT, do_right, 0);
1182
1183
	add_to_sclist(MSOME, "^Left", CONTROL_LEFT, do_prev_word_void, 0);
	add_to_sclist(MSOME, "^Right", CONTROL_RIGHT, do_next_word_void, 0);
1184
    }
1185
1186
    add_to_sclist(MMOST, "M-Space", 0, do_prev_word_void, 0);
    add_to_sclist(MMOST, "^Space", 0, do_next_word_void, 0);
1187
1188
1189
1190
    add_to_sclist((MMOST & ~MBROWSER), "^A", 0, do_home, 0);
    add_to_sclist((MMOST & ~MBROWSER), "Home", KEY_HOME, do_home, 0);
    add_to_sclist((MMOST & ~MBROWSER), "^E", 0, do_end, 0);
    add_to_sclist((MMOST & ~MBROWSER), "End", KEY_END, do_end, 0);
1191
1192
    add_to_sclist(MMAIN|MHELP|MBROWSER, "^P", 0, do_up_void, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", 0, do_down_void, 0);
1193
#ifdef ENABLE_UTF8
1194
    if (using_utf8()) {
1195
1196
	add_to_sclist(MMAIN|MHELP|MBROWSER, "\xE2\x86\x91", KEY_UP, do_up_void, 0);
	add_to_sclist(MMAIN|MHELP|MBROWSER, "\xE2\x86\x93", KEY_DOWN, do_down_void, 0);
1197
1198
	add_to_sclist(MMAIN|MBROWSER, "^\xE2\x86\x91", CONTROL_UP, do_prev_block, 0);
	add_to_sclist(MMAIN|MBROWSER, "^\xE2\x86\x93", CONTROL_DOWN, do_next_block, 0);
1199
1200
1201
    } else
#endif
    {
1202
1203
	add_to_sclist(MMAIN|MHELP|MBROWSER, "Up", KEY_UP, do_up_void, 0);
	add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", KEY_DOWN, do_down_void, 0);
1204
1205
	add_to_sclist(MMAIN|MBROWSER, "^Up", CONTROL_UP, do_prev_block, 0);
	add_to_sclist(MMAIN|MBROWSER, "^Down", CONTROL_DOWN, do_next_block, 0);
1206
    }
1207
1208
    add_to_sclist(MMAIN, "M-7", 0, do_prev_block, 0);
    add_to_sclist(MMAIN, "M-8", 0, do_next_block, 0);
1209
#ifndef DISABLE_JUSTIFY
1210
1211
1212
1213
    add_to_sclist(MMAIN, "M-(", 0, do_para_begin_void, 0);
    add_to_sclist(MMAIN, "M-9", 0, do_para_begin_void, 0);
    add_to_sclist(MMAIN, "M-)", 0, do_para_end_void, 0);
    add_to_sclist(MMAIN, "M-0", 0, do_para_end_void, 0);
Benno Schulenberg's avatar
Benno Schulenberg committed
1214
#endif
1215
#ifndef NANO_TINY
1216
1217
1218
1219
    add_to_sclist(MMAIN, "M--", 0, do_scroll_up, 0);
    add_to_sclist(MMAIN, "M-_", 0, do_scroll_up, 0);
    add_to_sclist(MMAIN, "M-+", 0, do_scroll_down, 0);
    add_to_sclist(MMAIN, "M-=", 0, do_scroll_down, 0);
1220
#endif
1221
#ifdef ENABLE_MULTIBUFFER
1222
1223
1224
1225
    add_to_sclist(MMAIN, "M-<", 0, switch_to_prev_buffer, 0);
    add_to_sclist(MMAIN, "M-,", 0, switch_to_prev_buffer, 0);
    add_to_sclist(MMAIN, "M->", 0, switch_to_next_buffer, 0);
    add_to_sclist(MMAIN, "M-.", 0, switch_to_next_buffer, 0);
1226
#endif
1227
    add_to_sclist(MMOST, "M-V", 0, do_verbatim_input, 0);
1228
#ifndef NANO_TINY
1229
1230
    add_to_sclist(MMAIN, "M-T", 0, do_cut_till_eof, 0);
    add_to_sclist(MMAIN, "M-D", 0, do_wordlinechar_count, 0);
1231
#endif
1232
#ifndef DISABLE_JUSTIFY
1233
    add_to_sclist(MMAIN|MWHEREIS, "M-J", 0, do_full_justify, 0);
1234
#endif
1235
1236
    add_to_sclist(MMAIN|MHELP, "^L", 0, total_refresh, 0);
    add_to_sclist(MMAIN, "^Z", 0, do_suspend_void, 0);
1237

1238
#ifndef NANO_TINY
1239
    /* Group of "Appearance" toggles. */
1240
    add_to_sclist(MMAIN, "M-X", 0, do_toggle_void, NO_HELP);
1241
    add_to_sclist(MMAIN, "M-C", 0, do_toggle_void, CONSTANT_SHOW);
1242
1243
1244
    add_to_sclist(MMAIN, "M-O", 0, do_toggle_void, MORE_SPACE);
    add_to_sclist(MMAIN, "M-S", 0, do_toggle_void, SMOOTH_SCROLL);
    add_to_sclist(MMAIN, "M-$", 0, do_toggle_void, SOFTWRAP);
1245
1246
1247
#ifdef ENABLE_LINENUMBERS
    add_to_sclist(MMAIN, "M-#", 0, do_toggle_void, LINE_NUMBERS);
#endif
1248
    add_to_sclist(MMAIN, "M-P", 0, do_toggle_void, WHITESPACE_DISPLAY);
1249
#ifndef DISABLE_COLOR
1250
    add_to_sclist(MMAIN, "M-Y", 0, do_toggle_void, NO_COLOR_SYNTAX);
1251
#endif
1252

1253
    /* Group of "Editing-behavior" toggles. */
1254
1255
    add_to_sclist(MMAIN, "M-H", 0, do_toggle_void, SMART_HOME);
    add_to_sclist(MMAIN, "M-I", 0, do_toggle_void, AUTOINDENT);
1256
    add_to_sclist(MMAIN, "M-K", 0, do_toggle_void, CUT_FROM_CURSOR);
1257
#ifndef DISABLE_WRAPPING
1258
    add_to_sclist(MMAIN, "M-L", 0, do_toggle_void, NO_WRAP);
1259
#endif
1260
    add_to_sclist(MMAIN, "M-Q", 0, do_toggle_void, TABS_TO_SPACES);
1261

1262
    /* Group of "Peripheral-feature" toggles. */
1263
    add_to_sclist(MMAIN, "M-B", 0, do_toggle_void, BACKUP_FILE);
1264
#ifdef ENABLE_MULTIBUFFER
1265
    add_to_sclist(MMAIN, "M-F", 0, do_toggle_void, MULTIBUFFER);
1266
#endif
1267
#ifdef ENABLE_MOUSE
1268
    add_to_sclist(MMAIN, "M-M", 0, do_toggle_void, USE_MOUSE);
1269
#endif
1270
1271
    add_to_sclist(MMAIN, "M-N", 0, do_toggle_void, NO_CONVERT);
    add_to_sclist(MMAIN, "M-Z", 0, do_toggle_void, SUSPEND);
1272
#endif /* !NANO_TINY */
Benno Schulenberg's avatar
Benno Schulenberg committed
1273

1274
    add_to_sclist(((MMOST & ~MMAIN & ~MBROWSER) | MYESNO), "^C", 0, do_cancel, 0);
1275

1276
1277
1278
    add_to_sclist(MWHEREIS|MREPLACE, "M-C", 0, case_sens_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE, "M-R", 0, regexp_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE, "M-B", 0, backwards_void, 0);
1279
    add_to_sclist(MWHEREIS|MREPLACE, "^R", 0, flip_replace, 0);
1280
1281
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE, "^Y", 0, do_first_line, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE, "^V", 0, do_last_line, 0);
1282
#ifndef DISABLE_JUSTIFY
1283
1284
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^W", 0, do_para_begin_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^O", 0, do_para_end_void, 0);
1285
#endif
1286
1287
    add_to_sclist(MWHEREIS, "^T", 0, do_gotolinecolumn_void, 0);
    add_to_sclist(MGOTOLINE, "^T", 0, gototext_void, 0);
1288
#ifndef DISABLE_HISTORIES
1289
1290
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXTCMD, "^P", 0, get_history_older_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXTCMD, "^N", 0, get_history_newer_void, 0);
1291
1292
#ifdef ENABLE_UTF8
    if (using_utf8()) {
1293
1294
	add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXTCMD, "\xE2\x86\x91", KEY_UP, get_history_older_void, 0);
	add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXTCMD, "\xE2\x86\x93", KEY_DOWN, get_history_newer_void, 0);
1295
1296
1297
    } else
#endif
    {
1298
1299
	add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXTCMD, "Up", KEY_UP, get_history_older_void, 0);
	add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE|MFINDINHELP|MEXTCMD, "Down", KEY_DOWN, get_history_newer_void, 0);
1300
    }
1301
#endif
1302
#ifdef ENABLE_BROWSER
1303
1304
1305
1306
1307
1308
    add_to_sclist(MWHEREISFILE, "^Y", 0, do_first_file, 0);
    add_to_sclist(MWHEREISFILE, "^V", 0, do_last_file, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-\\", 0, do_first_file, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-/", 0, do_last_file, 0);
    add_to_sclist(MBROWSER, "Home", KEY_HOME, do_first_file, 0);
    add_to_sclist(MBROWSER, "End", KEY_END, do_last_file, 0);
1309
1310
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-|", 0, do_first_file, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-?", 0, do_last_file, 0);
1311
    add_to_sclist(MBROWSER, "^Home", CONTROL_HOME, do_first_file, 0);
1312
    add_to_sclist(MBROWSER, "^End", CONTROL_END, do_last_file, 0);
1313
1314
1315
1316
    add_to_sclist(MBROWSER, "^_", 0, goto_dir_void, 0);
    add_to_sclist(MBROWSER, "M-G", 0, goto_dir_void, 0);
    add_to_sclist(MBROWSER, "F13", 0, goto_dir_void, 0);
    add_to_sclist(MBROWSER, "^L", 0, total_refresh, 0);
1317
#endif
1318
    if (ISSET(TEMP_FILE))
1319
	add_to_sclist(MWRITEFILE, "^Q", 0, discard_buffer, 0);
1320
#ifndef NANO_TINY
1321
1322
    add_to_sclist(MWRITEFILE, "M-D", 0, dos_format_void, 0);
    add_to_sclist(MWRITEFILE, "M-M", 0, mac_format_void, 0);
1323
1324
    /* In restricted mode, don't allow Appending, Prepending, nor making
     * backups, nor executing a command, nor opening a new buffer. */
1325
    if (!ISSET(RESTRICTED)) {
1326
1327
1328
	add_to_sclist(MWRITEFILE, "M-A", 0, append_void, 0);
	add_to_sclist(MWRITEFILE, "M-P", 0, prepend_void, 0);
	add_to_sclist(MWRITEFILE, "M-B", 0, backup_file_void, 0);
1329
	add_to_sclist(MINSERTFILE|MEXTCMD, "^X", 0, flip_execute, 0);
1330
    }
1331
#endif
1332
1333
#ifdef ENABLE_MULTIBUFFER
    if (!ISSET(RESTRICTED))
1334
	add_to_sclist(MINSERTFILE|MEXTCMD, "M-F", 0, flip_newbuffer, 0);
1335
#endif
1336
#ifdef ENABLE_BROWSER
1337
1338
1339
1340
    /* In restricted mode, don't allow entering the file browser. */
    if (!ISSET(RESTRICTED))
	add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", 0, to_files_void, 0);
#endif
1341
    add_to_sclist(MHELP|MBROWSER, "^C", 0, do_exit, 0);
1342
1343
    /* Allow exiting from the file browser and the help viewer with
     * the same key as they were entered. */
1344
#ifdef ENABLE_BROWSER
1345
    add_to_sclist(MBROWSER, "^T", 0, do_exit, 0);
1346
#endif
1347
#ifdef ENABLE_HELP
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
    add_to_sclist(MHELP, "^G", 0, do_exit, 0);
    add_to_sclist(MHELP, "Home", KEY_HOME, do_first_line, 0);
    add_to_sclist(MHELP, "End", KEY_END, do_last_line, 0);
#endif
    add_to_sclist(MMOST, "^I", 0, do_tab, 0);
    add_to_sclist(MMOST, "Tab", TAB_CODE, do_tab, 0);
    add_to_sclist(MMOST, "^M", 0, do_enter, 0);
    add_to_sclist(MMOST, "Enter", KEY_ENTER, do_enter, 0);
    add_to_sclist(MMOST, "^D", 0, do_delete, 0);
    add_to_sclist(MMOST, "Del", 0, do_delete, 0);
    add_to_sclist(MMOST, "^H", 0, do_backspace, 0);
    add_to_sclist(MMOST, "Bsp", KEY_BACKSPACE, do_backspace, 0);
Chris Allegretta's avatar
Chris Allegretta committed
1360

1361
1362
#ifdef DEBUG
    print_sclist();
Chris Allegretta's avatar
Chris Allegretta committed
1363
#endif
1364
}
1365

1366
#ifndef DISABLE_COLOR
1367
void set_lint_or_format_shortcuts(void)
1368
1369
{
#ifndef DISABLE_SPELLER
1370
1371
1372
1373
1374
1375
1376
    if (openfile->syntax->formatter) {
	replace_scs_for(do_spell, do_formatter);
	replace_scs_for(do_linter, do_formatter);
    } else {
	replace_scs_for(do_spell, do_linter);
	replace_scs_for(do_formatter, do_linter);
    }
1377
1378
1379
1380
1381
1382
#endif
}

void set_spell_shortcuts(void)
{
#ifndef DISABLE_SPELLER
1383
1384
	replace_scs_for(do_formatter, do_spell);
	replace_scs_for(do_linter, do_spell);
1385
1386
#endif
}
1387
#endif /* !DISABLE_COLOR */
1388

1389
const subnfunc *sctofunc(const sc *s)
1390
{
1391
    subnfunc *f = allfuncs;
1392

1393
1394
    while (f != NULL && f->scfunc != s->scfunc)
	f = f->next;
1395

1396
    return f;
1397
1398
}

1399
#ifndef NANO_TINY
1400
1401
/* Now let's come up with a single (hopefully) function to get a string
 * for each flag. */
1402
const char *flagtostr(int flag)
1403
{
1404
    switch (flag) {
1405
1406
1407
1408
	case NO_HELP:
	    /* TRANSLATORS: The next seventeen strings are toggle descriptions;
	     * they are best kept shorter than 40 characters, but may be longer. */
	    return N_("Help mode");
1409
	case CONSTANT_SHOW:
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
	    return N_("Constant cursor position display");
	case MORE_SPACE:
	    return N_("Use of one more line for editing");
	case SMOOTH_SCROLL:
	    return N_("Smooth scrolling");
	case SOFTWRAP:
	    return N_("Soft wrapping of overlong lines");
	case WHITESPACE_DISPLAY:
	    return N_("Whitespace display");
	case NO_COLOR_SYNTAX:
	    return N_("Color syntax highlighting");
	case SMART_HOME:
	    return N_("Smart home key");
	case AUTOINDENT:
	    return N_("Auto indent");
1425
	case CUT_FROM_CURSOR:
1426
1427
1428
1429
1430
1431
1432
1433
	    return N_("Cut to end");
	case NO_WRAP:
	    return N_("Hard wrapping of overlong lines");
	case TABS_TO_SPACES:
	    return N_("Conversion of typed tabs to spaces");
	case BACKUP_FILE:
	    return N_("Backup files");
	case MULTIBUFFER:
1434
	    return N_("Reading file into separate buffer");
1435
1436
1437
1438
1439
1440
	case USE_MOUSE:
	    return N_("Mouse support");
	case NO_CONVERT:
	    return N_("No conversion from DOS/Mac format");
	case SUSPEND:
	    return N_("Suspension");
1441
1442
	case LINE_NUMBERS:
	    return N_("Line numbering");
1443
1444
	default:
	    return "?????";
1445
1446
    }
}
1447
#endif /* !NANO_TINY */
1448

1449
#ifdef ENABLE_NANORC
1450
/* Interpret a function string given in the rc file, and return a
1451
 * shortcut struct with the corresponding function filled in. */
1452
sc *strtosc(const char *input)
1453
{
1454
    sc *s = nmalloc(sizeof(sc));
1455

1456
#ifndef NANO_TINY
1457
    s->toggle = 0;
1458
#endif
1459

1460
#ifdef ENABLE_HELP
1461
    if (!strcasecmp(input, "help"))
1462
1463
	s->scfunc = do_help_void;
    else
Chris Allegretta's avatar
Chris Allegretta committed
1464
#endif
1465
    if (!strcasecmp(input, "cancel"))
1466
	s->scfunc = do_cancel;
1467
    else if (!strcasecmp(input, "exit"))
1468
	s->scfunc = do_exit;
1469
1470
    else if (!strcasecmp(input, "discardbuffer"))
	s->scfunc = discard_buffer;
1471
    else if (!strcasecmp(input, "writeout"))
1472
	s->scfunc = do_writeout_void;
1473
1474
1475
1476
#ifndef NANO_TINY
    else if (!strcasecmp(input, "savefile"))
	s->scfunc = do_savefile;
#endif
1477
    else if (!strcasecmp(input, "insert"))
1478
	s->scfunc = do_insertfile_void;
1479
    else if (!strcasecmp(input, "whereis"))
1480
1481
1482
	s->scfunc = do_search_forward;
    else if (!strcasecmp(input, "wherewas"))
	s->scfunc = do_search_backward;
1483
    else if (!strcasecmp(input, "searchagain") ||
1484
	     !strcasecmp(input, "research"))  /* Deprecated.  Remove in 2018. */
1485
	s->scfunc = do_research;
1486
#ifndef NANO_TINY
1487
1488
1489
1490
    else if (!strcasecmp(input, "findprevious"))
	s->scfunc = do_findprevious;
    else if (!strcasecmp(input, "findnext"))
	s->scfunc = do_findnext;
1491
#endif
1492
1493
    else if (!strcasecmp(input, "replace"))
	s->scfunc = do_replace;
1494
    else if (!strcasecmp(input, "cut"))
1495
	s->scfunc = do_cut_text_void;
1496
    else if (!strcasecmp(input, "uncut"))
1497
	s->scfunc = do_uncut_text;
1498
#ifndef NANO_TINY
1499
    else if (!strcasecmp(input, "cutrestoffile"))
1500
	s->scfunc = do_cut_till_eof;
1501
1502
    else if (!strcasecmp(input, "copytext"))
	s->scfunc = do_copy_text;
1503
1504
    else if (!strcasecmp(input, "mark"))
	s->scfunc = do_mark;
1505
1506
#endif
#ifndef DISABLE_SPELLER
1507
1508
1509
    else if (!strcasecmp(input, "tospell") ||
	     !strcasecmp(input, "speller"))
	s->scfunc = do_spell;
1510
#endif
1511
#ifndef DISABLE_COLOR
1512
1513
    else if (!strcasecmp(input, "linter"))
	s->scfunc = do_linter;
1514
#endif
1515
    else if (!strcasecmp(input, "curpos") ||
1516
	     !strcasecmp(input, "cursorpos"))  /* Deprecated.  Remove in 2018. */
1517
	s->scfunc = do_cursorpos_void;
1518
    else if (!strcasecmp(input, "gotoline"))
1519
	s->scfunc = do_gotolinecolumn_void;
1520
#ifndef DISABLE_JUSTIFY
Chris Allegretta's avatar
Chris Allegretta committed
1521
    else if (!strcasecmp(input, "justify"))
1522
	s->scfunc = do_justify_void;
1523
1524
    else if (!strcasecmp(input, "fulljustify"))
	s->scfunc = do_full_justify;
1525
    else if (!strcasecmp(input, "beginpara"))
1526
	s->scfunc = do_para_begin_void;
1527
    else if (!strcasecmp(input, "endpara"))
1528
	s->scfunc = do_para_end_void;
1529
#endif
1530
1531
1532
1533
#ifdef ENABLE_COMMENT
    else if (!strcasecmp(input, "comment"))
	s->scfunc = do_comment;
#endif
1534
1535
1536
1537
#ifdef ENABLE_WORDCOMPLETION
    else if (!strcasecmp(input, "complete"))
	s->scfunc = complete_a_word;
#endif
1538
#ifndef NANO_TINY
1539
    else if (!strcasecmp(input, "indent"))
1540
	s->scfunc = do_indent;
1541
    else if (!strcasecmp(input, "unindent"))
1542
	s->scfunc = do_unindent;
Chris Allegretta's avatar
Chris Allegretta committed
1543
    else if (!strcasecmp(input, "scrollup"))
1544
	s->scfunc = do_scroll_up;
Chris Allegretta's avatar
Chris Allegretta committed
1545
    else if (!strcasecmp(input, "scrolldown"))
1546
	s->scfunc = do_scroll_down;
1547
1548
1549
1550
    else if (!strcasecmp(input, "cutwordleft"))
	s->scfunc = do_cut_prev_word;
    else if (!strcasecmp(input, "cutwordright"))
	s->scfunc = do_cut_next_word;
1551
    else if (!strcasecmp(input, "findbracket"))
1552
	s->scfunc = do_find_bracket;
1553
    else if (!strcasecmp(input, "wordcount"))
1554
	s->scfunc = do_wordlinechar_count;
1555
1556
1557
1558
    else if (!strcasecmp(input, "recordmacro"))
	s->scfunc = record_macro;
    else if (!strcasecmp(input, "runmacro"))
	s->scfunc = run_macro;
1559
    else if (!strcasecmp(input, "undo"))
1560
	s->scfunc = do_undo;
1561
    else if (!strcasecmp(input, "redo"))
1562
	s->scfunc = do_redo;
1563
#endif
Chris Allegretta's avatar
Chris Allegretta committed
1564
    else if (!strcasecmp(input, "left") ||
1565
	     !strcasecmp(input, "back"))
1566
	s->scfunc = do_left;
1567
1568
1569
    else if (!strcasecmp(input, "right") ||
	     !strcasecmp(input, "forward"))
	s->scfunc = do_right;
Chris Allegretta's avatar
Chris Allegretta committed
1570
    else if (!strcasecmp(input, "up") ||
1571
	     !strcasecmp(input, "prevline"))
1572
	s->scfunc = do_up_void;
Chris Allegretta's avatar
Chris Allegretta committed
1573
    else if (!strcasecmp(input, "down") ||
1574
	     !strcasecmp(input, "nextline"))
1575
	s->scfunc = do_down_void;
1576
1577
1578
1579
    else if (!strcasecmp(input, "prevword"))
	s->scfunc = do_prev_word_void;
    else if (!strcasecmp(input, "nextword"))
	s->scfunc = do_next_word_void;
Chris Allegretta's avatar
Chris Allegretta committed
1580
    else if (!strcasecmp(input, "home"))
1581
	s->scfunc = do_home;
Chris Allegretta's avatar
Chris Allegretta committed
1582
    else if (!strcasecmp(input, "end"))
1583
	s->scfunc = do_end;
1584
1585
1586
1587
    else if (!strcasecmp(input, "prevblock"))
	s->scfunc = do_prev_block;
    else if (!strcasecmp(input, "nextblock"))
	s->scfunc = do_next_block;
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
    else if (!strcasecmp(input, "pageup") ||
	     !strcasecmp(input, "prevpage"))
	s->scfunc = do_page_up;
    else if (!strcasecmp(input, "pagedown") ||
	     !strcasecmp(input, "nextpage"))
	s->scfunc = do_page_down;
    else if (!strcasecmp(input, "firstline"))
	s->scfunc = do_first_line;
    else if (!strcasecmp(input, "lastline"))
	s->scfunc = do_last_line;
1598
#ifdef ENABLE_MULTIBUFFER
Chris Allegretta's avatar
Chris Allegretta committed
1599
    else if (!strcasecmp(input, "prevbuf"))
1600
	s->scfunc = switch_to_prev_buffer;
Chris Allegretta's avatar
Chris Allegretta committed
1601
    else if (!strcasecmp(input, "nextbuf"))
1602
	s->scfunc = switch_to_next_buffer;
Chris Allegretta's avatar
Chris Allegretta committed
1603
1604
#endif
    else if (!strcasecmp(input, "verbatim"))
1605
	s->scfunc = do_verbatim_input;
Chris Allegretta's avatar
Chris Allegretta committed
1606
    else if (!strcasecmp(input, "tab"))
1607
	s->scfunc = do_tab;
Chris Allegretta's avatar
Chris Allegretta committed
1608
    else if (!strcasecmp(input, "enter"))
1609
	s->scfunc = do_enter;
Chris Allegretta's avatar
Chris Allegretta committed
1610
    else if (!strcasecmp(input, "delete"))
1611
	s->scfunc = do_delete;
1612
    else if (!strcasecmp(input, "backspace"))
1613
	s->scfunc = do_backspace;
Chris Allegretta's avatar
Chris Allegretta committed
1614
    else if (!strcasecmp(input, "refresh"))
1615
	s->scfunc = total_refresh;
1616
1617
    else if (!strcasecmp(input, "suspend"))
	s->scfunc = do_suspend_void;
1618
    else if (!strcasecmp(input, "casesens"))
1619
	s->scfunc = case_sens_void;
1620
    else if (!strcasecmp(input, "regexp") ||
1621
	     !strcasecmp(input, "regex"))  /* Deprecated.  Remove in 2018. */
1622
	s->scfunc = regexp_void;
1623
    else if (!strcasecmp(input, "backwards"))
1624
	s->scfunc = backwards_void;
1625
    else if (!strcasecmp(input, "flipreplace") ||
1626
	     !strcasecmp(input, "dontreplace"))  /* Deprecated.  Remove in 2018. */
1627
	s->scfunc = flip_replace;
1628
    else if (!strcasecmp(input, "gototext"))
1629
	s->scfunc = gototext_void;
1630
1631
1632
1633
1634
1635
#ifndef DISABLE_HISTORIES
    else if (!strcasecmp(input, "prevhistory"))
	s->scfunc = get_history_older_void;
    else if (!strcasecmp(input, "nexthistory"))
	s->scfunc = get_history_newer_void;
#endif
1636
#ifndef NANO_TINY
1637
    else if (!strcasecmp(input, "dosformat"))
1638
	s->scfunc = dos_format_void;
1639
    else if (!strcasecmp(input, "macformat"))
1640
	s->scfunc = mac_format_void;
1641
    else if (!strcasecmp(input, "append"))
1642
	s->scfunc = append_void;
1643
    else if (!strcasecmp(input, "prepend"))
1644
	s->scfunc = prepend_void;
1645
    else if (!strcasecmp(input, "backup"))
1646
	s->scfunc = backup_file_void;
1647
    else if (!strcasecmp(input, "flipexecute"))
1648
	s->scfunc = flip_execute;
1649
#endif
1650
#ifdef ENABLE_MULTIBUFFER
1651
    else if (!strcasecmp(input, "flipnewbuffer") ||
1652
	     !strcasecmp(input, "newbuffer"))  /* Deprecated.  Remove in 2018. */
1653
	s->scfunc = flip_newbuffer;
Chris Allegretta's avatar
Chris Allegretta committed
1654
#endif
1655
#ifdef ENABLE_BROWSER
1656
1657
    else if (!strcasecmp(input, "tofiles") ||
	     !strcasecmp(input, "browser"))
1658
	s->scfunc = to_files_void;
1659
    else if (!strcasecmp(input, "gotodir"))
1660
	s->scfunc = goto_dir_void;
1661
    else if (!strcasecmp(input, "firstfile"))
1662
	s->scfunc = do_first_file;
1663
    else if (!strcasecmp(input, "lastfile"))
1664
1665
	s->scfunc = do_last_file;
#endif
1666
    else {
1667
#ifndef NANO_TINY
1668
	s->scfunc = do_toggle_void;
1669
	if (!strcasecmp(input, "nohelp"))
1670
	    s->toggle = NO_HELP;
1671
	else if (!strcasecmp(input, "constupdate"))
1672
	    s->toggle = CONSTANT_SHOW;
1673
	else if (!strcasecmp(input, "morespace"))
1674
	    s->toggle = MORE_SPACE;
1675
	else if (!strcasecmp(input, "smoothscroll"))
1676
	    s->toggle = SMOOTH_SCROLL;
1677
	else if (!strcasecmp(input, "softwrap"))
1678
	    s->toggle = SOFTWRAP;
1679
	else if (!strcasecmp(input, "whitespacedisplay"))
1680
	    s->toggle = WHITESPACE_DISPLAY;
1681
#ifndef DISABLE_COLOR
1682
	else if (!strcasecmp(input, "nosyntax"))
1683
1684
	    s->toggle = NO_COLOR_SYNTAX;
#endif
1685
	else if (!strcasecmp(input, "smarthome"))
1686
	    s->toggle = SMART_HOME;
1687
	else if (!strcasecmp(input, "autoindent"))
1688
	    s->toggle = AUTOINDENT;
1689
	else if (!strcasecmp(input, "cuttoend"))
1690
	    s->toggle = CUT_FROM_CURSOR;
1691
#ifndef DISABLE_WRAPPING
1692
	else if (!strcasecmp(input, "nowrap"))
1693
	    s->toggle = NO_WRAP;
1694
#endif
1695
	else if (!strcasecmp(input, "tabstospaces"))
1696
	    s->toggle = TABS_TO_SPACES;
1697
	else if (!strcasecmp(input, "backupfile"))
1698
	    s->toggle = BACKUP_FILE;
1699
#ifdef ENABLE_MULTIBUFFER
1700
	else if (!strcasecmp(input, "multibuffer"))
1701
	    s->toggle = MULTIBUFFER;
1702
#endif
1703
#ifdef ENABLE_MOUSE
1704
	else if (!strcasecmp(input, "mouse"))
1705
	    s->toggle = USE_MOUSE;
1706
#endif
1707
	else if (!strcasecmp(input, "noconvert"))
1708
	    s->toggle = NO_CONVERT;
1709
	else if (!strcasecmp(input, "suspendenable"))
1710
	    s->toggle = SUSPEND;
1711
	else
1712
#endif /* !NANO_TINY */
1713
	{
1714
1715
1716
	    free(s);
	    return NULL;
	}
1717
1718
1719
    }
    return s;
}
1720

1721
/* Interpret a menu name and return the corresponding menu flag. */
1722
int strtomenu(const char *input)
1723
1724
{
    if (!strcasecmp(input, "all"))
1725
	return (MMOST|MHELP|MYESNO);
1726
1727
1728
1729
1730
1731
    else if (!strcasecmp(input, "main"))
	return MMAIN;
    else if (!strcasecmp(input, "search"))
	return MWHEREIS;
    else if (!strcasecmp(input, "replace"))
	return MREPLACE;
1732
    else if (!strcasecmp(input, "replace2") ||  /* Deprecated.  Remove in 2018. */
Benno Schulenberg's avatar
Benno Schulenberg committed
1733
	     !strcasecmp(input, "replacewith"))
1734
	return MREPLACEWITH;
1735
1736
1737
1738
1739
1740
1741
    else if (!strcasecmp(input, "gotoline"))
	return MGOTOLINE;
    else if (!strcasecmp(input, "writeout"))
	return MWRITEFILE;
    else if (!strcasecmp(input, "insert"))
	return MINSERTFILE;
    else if (!strcasecmp(input, "externalcmd") ||
Benno Schulenberg's avatar
Benno Schulenberg committed
1742
	     !strcasecmp(input, "extcmd"))
1743
	return MEXTCMD;
1744
#ifdef ENABLE_HELP
1745
1746
    else if (!strcasecmp(input, "help"))
	return MHELP;
1747
1748
#endif
#ifndef DISABLE_SPELLER
1749
    else if (!strcasecmp(input, "spell"))
1750
	return MSPELL;
1751
#endif
1752
1753
    else if (!strcasecmp(input, "linter"))
	return MLINTER;
1754
#ifdef ENABLE_BROWSER
1755
1756
1757
1758
1759
1760
    else if (!strcasecmp(input, "browser"))
	return MBROWSER;
    else if (!strcasecmp(input, "whereisfile"))
	return MWHEREISFILE;
    else if (!strcasecmp(input, "gotodir"))
	return MGOTODIR;
1761
#endif
1762
1763
    return -1;
}
1764
#endif /* ENABLE_NANORC */
1765

Chris Allegretta's avatar
Chris Allegretta committed
1766

1767
1768
1769
#ifdef DEBUG
/* This function is used to gracefully return all the memory we've used.
 * It should be called just before calling exit().  Practically, the
1770
1771
 * only effect is to cause a segmentation fault if the various data
 * structures got bolloxed earlier.  Thus, we don't bother having this
Chris Allegretta's avatar
Chris Allegretta committed
1772
1773
 * function unless debugging is turned on. */
void thanks_for_all_the_fish(void)
1774
{
1775
1776
    if (topwin != NULL)
	delwin(topwin);
1777
1778
1779
    delwin(edit);
    delwin(bottomwin);

1780
    free(word_chars);
Chris Allegretta's avatar
Chris Allegretta committed
1781
#ifndef DISABLE_JUSTIFY
1782
    free(quotestr);
1783
    regfree(&quotereg);
1784
    free(quoteerr);
1785
#endif
1786
#ifndef NANO_TINY
1787
    free(backup_dir);
1788
#endif
Chris Allegretta's avatar
Chris Allegretta committed
1789
#ifndef DISABLE_OPERATINGDIR
1790
    free(operating_dir);
1791
#endif
1792
    free(answer);
1793
    free(last_search);
1794
    free(present_path);
1795
#ifndef DISABLE_SPELLER
1796
    free(alt_speller);
1797
#endif
1798
    free_filestruct(cutbuffer);
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
1799
    /* Free the memory associated with each open file buffer. */
1800
1801
1802
1803
1804
    while (openfile != openfile->next) {
	openfile = openfile->next;
	delete_opennode(openfile->prev);
    }
    delete_opennode(openfile);
1805
#ifndef DISABLE_COLOR
1806
    free(syntaxstr);
Chris Allegretta's avatar
Chris Allegretta committed
1807
    while (syntaxes != NULL) {
1808
1809
	syntaxtype *sint = syntaxes;
	syntaxes = syntaxes->next;
Chris Allegretta's avatar
Chris Allegretta committed
1810

1811
1812
1813
	free(sint->name);
	free(sint->linter);
	free(sint->formatter);
1814

1815
1816
1817
1818
1819
	while (sint->extensions != NULL) {
	    regexlisttype *item = sint->extensions;
	    sint->extensions = sint->extensions->next;
	    free(item->full_regex);
	    free(item);
Chris Allegretta's avatar
Chris Allegretta committed
1820
	}
1821
1822
1823
1824
1825
	while (sint->headers != NULL) {
	    regexlisttype *item = sint->headers;
	    sint->headers = sint->headers->next;
	    free(item->full_regex);
	    free(item);
1826
	}
1827
1828
1829
1830
1831
	while (sint->magics != NULL) {
	    regexlisttype *item = sint->magics;
	    sint->magics = sint->magics->next;
	    free(item->full_regex);
	    free(item);
1832
	}
1833

1834
1835
1836
1837
1838
1839
1840
	while (sint->color != NULL) {
	    colortype *ink = sint->color;
	    sint->color = sint->color->next;
	    free(ink->start_regex);
	    if (ink->start != NULL) {
		regfree(ink->start);
		free(ink->start);
1841
	    }
1842
1843
1844
1845
	    free(ink->end_regex);
	    if (ink->end != NULL) {
		regfree(ink->end);
		free(ink->end);
1846
	    }
1847
	    free(ink);
Chris Allegretta's avatar
Chris Allegretta committed
1848
	}
1849
1850

	free(sint);
Chris Allegretta's avatar
Chris Allegretta committed
1851
    }
1852
#endif /* !DISABLE_COLOR */
1853
#ifndef DISABLE_HISTORIES
1854
    /* Free the search and replace history lists. */
1855
1856
    free_filestruct(searchtop);
    free_filestruct(replacetop);
1857
#endif
1858
    /* Free the list of functions. */
1859
    while (allfuncs != NULL) {
1860
1861
1862
	subnfunc *f = allfuncs;
	allfuncs = allfuncs->next;
	free(f);
1863
    }
1864
    /* Free the list of shortcuts. */
1865
    while (sclist != NULL) {
1866
1867
1868
	sc *s = sclist;
	sclist = sclist->next;
	free(s);
1869
    }
1870
#ifdef ENABLE_NANORC
1871
    free(homedir);
1872
#endif
1873
}
1874
#endif /* DEBUG */