global.c 54.3 KB
Newer Older
1
/* $Id$ */
Chris Allegretta's avatar
Chris Allegretta committed
2
3
4
/**************************************************************************
 *   global.c                                                             *
 *                                                                        *
5
 *   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,  *
6
 *   2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc.    *
Chris Allegretta's avatar
Chris Allegretta committed
7
8
 *   This program is free software; you can redistribute it and/or modify *
 *   it under the terms of the GNU General Public License as published by *
9
 *   the Free Software Foundation; either version 3, or (at your option)  *
Chris Allegretta's avatar
Chris Allegretta committed
10
11
 *   any later version.                                                   *
 *                                                                        *
12
13
14
15
 *   This program is distributed in the hope that it will be useful, but  *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    *
 *   General Public License for more details.                             *
Chris Allegretta's avatar
Chris Allegretta committed
16
17
18
 *                                                                        *
 *   You should have received a copy of the GNU General Public License    *
 *   along with this program; if not, write to the Free Software          *
19
20
 *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA            *
 *   02110-1301, USA.                                                     *
Chris Allegretta's avatar
Chris Allegretta committed
21
22
23
 *                                                                        *
 **************************************************************************/

24
25
#include "proto.h"

26
#include <ctype.h>
27
#include <string.h>
28
29
#include <strings.h>
#include "assert.h"
Chris Allegretta's avatar
Chris Allegretta committed
30

31
32
/* Global variables. */
#ifndef NANO_TINY
33
sigjmp_buf jump_buf;
34
	/* Used to return to either main() or the unjustify routine in
35
	 * do_justify() after a SIGWINCH. */
36
37
38
bool jump_buf_main = FALSE;
	/* Have we set jump_buf so that we return to main() after a
	 * SIGWINCH? */
39
40
#endif

41
#ifndef DISABLE_WRAPJUSTIFY
42
43
ssize_t fill = 0;
	/* The column where we will wrap lines. */
44
ssize_t wrap_at = -CHARS_FROM_EOL;
45
46
47
48
49
50
51
52
53
54
	/* 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. */
char *last_replace = NULL;
	/* The last replacement string we searched for. */

55
unsigned flags[4] = {0, 0, 0, 0};
56
57
58
59
60
61
	/* Our flag containing the states of all global options. */
WINDOW *topwin;
	/* 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. */
WINDOW *edit;
62
	/* The middle portion of the window, i.e. the edit window, where
63
64
65
66
67
68
	 * we display the current file we're editing. */
WINDOW *bottomwin;
	/* 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? */
69
int maxrows = 0;
70
	/* How many usable lines there are (due to soft wrapping). */
71
72
73

filestruct *cutbuffer = NULL;
	/* The buffer where we store cut text. */
74
filestruct *cutbottom = NULL;
75
#ifndef DISABLE_JUSTIFY
76
77
filestruct *jusbuffer = NULL;
	/* The buffer where we store unjustified text. */
78
#endif
79
80
81
partition *filepart = NULL;
	/* The partition where we store a portion of the current
	 * file. */
82
openfilestruct *openfile = NULL;
83
	/* The list of all open file buffers. */
84

85
86
87
88
89
90
#ifndef NANO_TINY
char *matchbrackets = NULL;
	/* The opening and closing brackets that can be found by bracket
	 * searches. */
#endif

91
#if !defined(NANO_TINY) && !defined(DISABLE_NANORC)
92
93
94
95
96
char *whitespace = NULL;
	/* The characters used when displaying the first characters of
	 * tabs and spaces. */
int whitespace_len[2];
	/* The length of these characters. */
97
98
#endif

99
#ifndef DISABLE_JUSTIFY
100
101
102
103
104
105
106
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(). */
107
#ifdef HAVE_REGEX_H
108
109
110
regex_t quotereg;
	/* The compiled regular expression from the quoting string. */
int quoterc;
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
111
	/* Whether it was compiled successfully. */
112
113
char *quoteerr = NULL;
	/* The error message, if it didn't. */
114
#else
115
116
size_t quotelen;
	/* The length of the quoting string in bytes. */
Chris Allegretta's avatar
Chris Allegretta committed
117
#endif
118
119
#endif

120
bool nodelay_mode = FALSE;
121
	/* Are we checking for a cancel wile doing something? */
122

123
char *answer = NULL;
124
	/* The answer string used by the statusbar prompt. */
Chris Allegretta's avatar
Chris Allegretta committed
125

126
127
128
ssize_t tabsize = -1;
	/* The width of a tab in spaces.  The default value is set in
	 * main(). */
129

130
131
132
#ifndef NANO_TINY
char *backup_dir = NULL;
	/* The directory where we store backup files. */
133

134
const char *locking_prefix = ".";
135
        /* Prefix of how to store the vim-style lock file. */
136
const char *locking_suffix = ".swp";
137
        /* Suffix of the vim-style lock file. */
138
#endif
139
#ifndef DISABLE_OPERATINGDIR
140
141
142
143
144
char *operating_dir = NULL;
	/* The relative path to the operating directory, which we can't
	 * move outside of. */
char *full_operating_dir = NULL;
	/* The full path to it. */
145
146
#endif

147
#ifndef DISABLE_SPELLER
148
149
char *alt_speller = NULL;
	/* The command to use for the alternate spell checker. */
150
151
#endif

152
#ifndef DISABLE_COLOR
153
syntaxtype *syntaxes = NULL;
154
	/* The global list of color syntaxes. */
155
char *syntaxstr = NULL;
156
	/* The color syntax name specified on the command line. */
157
158
#endif

159
bool edit_refresh_needed = FALSE;
160
	/* Did a command mangle enough of the buffer refresh that we
161
	 * should repaint the screen? */
162

163
int currmenu;
164
	/* The currently loaded menu. */
165
sc *sclist = NULL;
166
	/* Pointer to the start of the shortcuts list. */
167
subnfunc *allfuncs = NULL;
168
169
170
	/* Pointer to the start of the functions list. */
subnfunc *tailfunc;
	/* Pointer to the last function in the list. */
171
172
subnfunc *exitfunc;
	/* Pointer to the special Exit/Close item. */
173
174
subnfunc *uncutfunc;
	/* Pointer to the special Uncut/Unjustify item. */
175

176
#ifndef DISABLE_HISTORIES
177
filestruct *search_history = NULL;
178
	/* The search string history list. */
179
filestruct *searchage = NULL;
180
	/* The top of the search string history list. */
181
filestruct *searchbot = NULL;
182
	/* The bottom of the search string history list. */
183
filestruct *replace_history = NULL;
184
	/* The replace string history list. */
185
filestruct *replaceage = NULL;
186
	/* The top of the replace string history list. */
187
filestruct *replacebot = NULL;
188
	/* The bottom of the replace string history list. */
189
poshiststruct *poshistory;
190
	/* The cursor position history list. */
191
192
#endif

193
/* Regular expressions. */
194
#ifdef HAVE_REGEX_H
195
196
197
198
199
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. */
Chris Allegretta's avatar
Chris Allegretta committed
200
#endif
201

202
int hilite_attribute = A_REVERSE;
203
	/* The curses attribute we use for reverse video. */
204
205
206
207
#ifndef DISABLE_COLOR
char* specified_color_combo[] = {};
	/* The color combinations as specified in the rcfile. */
#endif
208
color_pair interface_color_pair[] = {};
209
	/* The processed color pairs for the interface elements. */
210

211
char *homedir = NULL;
212
	/* The user's home directory, from $HOME or /etc/passwd. */
213

214
/* Return the number of entries in the shortcut list for a given menu. */
215
size_t length_of_list(int menu)
216
{
217
    subnfunc *f;
218
    size_t i = 0;
219

220
    for (f = allfuncs; f != NULL; f = f->next)
221
222
223
224
225
        if ((f->menus & menu) != 0
#ifndef DISABLE_HELP
	    && strlen(f->help) > 0
#endif
	                          ) {
226
227
	    i++;
	}
228
229
230
    return i;
}

231
/* Just throw this here. */
232
233
234
235
236
237
void case_sens_void(void)
{
}
void regexp_void(void)
{
}
238
239
240
void backwards_void(void)
{
}
241
242
243
void gototext_void(void)
{
}
244
#ifndef DISABLE_BROWSER
245
246
247
void to_files_void(void)
{
}
248
249
250
251
void goto_dir_void(void)
{
}
#endif
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
void dos_format_void(void)
{
}
void mac_format_void(void)
{
}
void append_void(void)
{
}
void prepend_void(void)
{
}
void backup_file_void(void)
{
}
void new_buffer_void(void)
{
}
270
void flip_replace_void(void)
271
272
{
}
273
void flip_execute_void(void)
274
275
276
{
}

277
278
/* Set the type of command key based on the string. */
key_type strtokeytype(const char *str)
279
{
280
    if (str[0] == '^')
281
        return CONTROL;
282
283
284
    else if (str[0] == 'M')
        return META;
    else if (str[0] == 'F')
285
        return FKEY;
286
    else
287
	return RAWINPUT;
288
289
}

290
/* Add a string to the function list struct.
291
 * Does not allow updates, not yet anyway. */
292
void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *help,
293
294
    bool blank_after, bool viewok)
{
295
    subnfunc *f = (subnfunc *)nmalloc(sizeof(subnfunc));
296
297
298
299
300
301

    if (allfuncs == NULL)
	allfuncs = f;
    else
	tailfunc->next = f;
    tailfunc = f;
302
303
304
305
306
307

    f->next = NULL;
    f->scfunc = func;
    f->menus = menus;
    f->desc = desc;
    f->viewok = viewok;
308
#ifndef DISABLE_HELP
309
310
311
312
313
    f->help = help;
    f->blank_after = blank_after;
#endif

#ifdef DEBUG
314
    fprintf(stderr, "Added func %ld (%s) for menus %x\n", (long)func, f->desc, menus);
315
#endif
316
317
}

318
319
/* Return the first shortcut in the list of shortcuts that
 * matches the given func in the given menu. */
320
321
const sc *first_sc_for(int menu, void (*func)(void))
{
322
323
    const sc *s;

324
325
326
    for (s = sclist; s != NULL; s = s->next)
	if ((s->menu & menu) && s->scfunc == func)
	    return s;
327

328
#ifdef DEBUG
329
    fprintf(stderr, "Whoops, returning null given func %ld in menu %x\n", (long)func, menu);
330
331
332
333
334
335
#endif
    /* Otherwise... */
    return NULL;
}


336
/* Add a string to the shortcut list.
337
 * Allows updates to existing entries in the list. */
338
void add_to_sclist(int menu, const char *scstring, void (*func)(void), int toggle)
Chris Allegretta's avatar
Chris Allegretta committed
339
{
340
    sc *s;
341

342
    if (sclist == NULL) {
343
	sclist = (sc *)nmalloc(sizeof(sc));
344
345
	s = sclist;
        s->next = NULL;
346
    } else {
347
348
349
350
351
352
353
354
355
356
357
358
	for (s = sclist; s->next != NULL; s = s->next)
            if (s->menu == menu && s->keystr == scstring)
		break;

        if (s->menu != menu || s->keystr != scstring) { /* i.e. this is not a replace... */
#ifdef DEBUG
            fprintf(stderr, "No match found...\n");
#endif
	    s->next = (sc *)nmalloc(sizeof(sc));
	    s = s->next;
            s->next = NULL;
        }
359
360
    }

361
362
363
    s->type = strtokeytype(scstring);
    s->menu = menu;
    s->toggle = toggle;
364
    s->keystr = (char *) scstring;
365
366
367
368
    s->scfunc = func;
    assign_keyinfo(s);

#ifdef DEBUG
369
    fprintf(stderr, "Setting sequence to %d for shortcut \"%s\" in menu %x\n", s->seq, scstring, (int)s->menu);
370
#endif
Chris Allegretta's avatar
Chris Allegretta committed
371
372
}

373
/* Assign one function's shortcuts to another function. */
374
375
376
377
void replace_scs_for(void (*oldfunc)(void), void (*newfunc)(void))
{
    sc *s;

378
    for (s = sclist; s != NULL; s = s->next)
379
	if (s->scfunc == oldfunc)
380
381
382
	    s->scfunc = newfunc;
}

Chris Allegretta's avatar
Chris Allegretta committed
383
/* Return the given menu's first shortcut sequence, or the default value
384
 * (2nd arg).  Assumes currmenu for the menu to check. */
385
int sc_seq_or(void (*func)(void), int defaultval)
Chris Allegretta's avatar
Chris Allegretta committed
386
387
388
389
390
391
392
393
394
{
    const sc *s = first_sc_for(currmenu, func);

    if (s)
        return s->seq;
    /* else */
    return defaultval;
}

395
396
/* Assign the info to the shortcut struct.
 * Assumes keystr is already assigned, naturally. */
397
398
399
400
401
402
403
404
405
406
407
void assign_keyinfo(sc *s)
{
    if (s->type == CONTROL) {
        assert(strlen(s->keystr) > 1);
        s->seq = s->keystr[1] - 64;
    } else if (s->type == META) {
        assert(strlen(s->keystr) > 2);
        s->seq = tolower((int) s->keystr[2]);
    } else if (s->type == FKEY) {
        assert(strlen(s->keystr) > 1);
        s->seq = KEY_F0 + atoi(&s->keystr[1]);
408
    } else /* RAWINPUT */
409
        s->seq = (int) s->keystr[0];
410

411
    /* Override some keys which don't bind as easily as we'd like. */
412
413
414
415
    if (s->type == CONTROL && (!strcasecmp(&s->keystr[1], "space")))
	s->seq = 0;
    else if (s->type == META && (!strcasecmp(&s->keystr[2], "space")))
	s->seq = (int) ' ';
416
    else if (s->type == RAWINPUT) {
417
	if (!strcasecmp(s->keystr, "Up"))
418
	    s->seq = KEY_UP;
419
	else if (!strcasecmp(s->keystr, "Down"))
420
	    s->seq = KEY_DOWN;
421
	else if (!strcasecmp(s->keystr, "Left"))
422
	    s->seq = KEY_LEFT;
423
	else if (!strcasecmp(s->keystr, "Right"))
424
	    s->seq = KEY_RIGHT;
425
	else if (!strcasecmp(s->keystr, "Ins"))
426
	    s->seq = KEY_IC;
427
	else if (!strcasecmp(s->keystr, "Del"))
428
	    s->seq = KEY_DC;
429
	else if (!strcasecmp(s->keystr, "Bsp"))
430
	    s->seq = KEY_BACKSPACE;
431
	else if (!strcasecmp(s->keystr, "Enter"))
432
	    s->seq = KEY_ENTER;
433
	else if (!strcasecmp(s->keystr, "PgUp"))
434
	    s->seq = KEY_PPAGE;
435
	else if (!strcasecmp(s->keystr, "PgDn"))
436
	    s->seq = KEY_NPAGE;
437
#ifdef KEY_HOME
438
	else if (!strcasecmp(s->keystr, "Home"))
439
	    s->seq = KEY_HOME;
440
441
#endif
#ifdef KEY_END
442
	else if (!strcasecmp(s->keystr, "End"))
443
	    s->seq = KEY_END;
444
#endif
445
    }
446
447
448
449
450
451
452
453
}

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

454
    for (s = sclist; s != NULL; s = s->next) {
455
	f = sctofunc(s);
456
	if (f)
457
	    fprintf(stderr, "Shortcut \"%s\", function: %s, menus %x\n", s->keystr, f->desc, f->menus);
458
	else
459
	    fprintf(stderr, "Hmm, didn't find a func for \"%s\"\n", s->keystr);
460
461
462
463
    }
}
#endif

464
465
466
/* TRANSLATORS: Try to keep the next four strings at most 10 characters. */
const char *exit_tag = N_("Exit");
const char *close_tag = N_("Close");
467
468
469
470
const char *uncut_tag = N_("Uncut Text");
#ifndef DISABLE_JUSITIFY
const char *unjust_tag = N_("Unjustify");
#endif
471
#ifndef NANO_TINY
472
/* TRANSLATORS: Try to keep this at most 12 characters. */
473
const char *whereis_next_tag = N_("WhereIs Next");
474
#endif
475

476
477
/* Initialize the list of functions and the list of shortcuts. */
void shortcut_init(void)
478
{
479
    /* TRANSLATORS: Try to keep the next eight strings at most 10 characters. */
480
    const char *whereis_tag = N_("Where Is");
481
482
    const char *replace_tag = N_("Replace");
    const char *gotoline_tag = N_("Go To Line");
483
484
    const char *prev_line_tag = N_("Prev Line");
    const char *next_line_tag = N_("Next Line");
485
    const char *read_file_tag = N_("Read File");
486
#ifndef DISABLE_JUSTIFY
487
    const char *fulljustify_tag = N_("FullJstify");
488
#endif
489
    const char *refresh_tag = N_("Refresh");
490

491
#ifndef DISABLE_HELP
492
#ifndef DISABLE_JUSTIFY
493
494
    /* TRANSLATORS: The next long series of strings are shortcut descriptions;
     * they are best kept shorter than 56 characters, but may be longer. */
495
496
    const char *nano_justify_msg = N_("Justify the current paragraph");
#endif
497
    const char *nano_cancel_msg = N_("Cancel the current function");
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
498
    const char *nano_help_msg = N_("Display this help text");
499
    const char *nano_exit_msg =
500
#ifndef DISABLE_MULTIBUFFER
501
	N_("Close the current file buffer / Exit from nano")
502
#else
503
	N_("Exit from nano")
504
505
#endif
	;
506
507
    const char *nano_writeout_msg =
	N_("Write the current file to disk");
508
509
    const char *nano_insert_msg =
	N_("Insert another file into the current one");
510
    const char *nano_whereis_msg =
511
	N_("Search for a string or a regular expression");
512
#ifndef DISABLE_BROWSER
513
514
    const char *nano_browser_whereis_msg =
	N_("Search for a string");
515
#endif
516
517
    const char *nano_prevpage_msg = N_("Go one screenful up");
    const char *nano_nextpage_msg = N_("Go one screenful down");
518
519
520
521
    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");
522
    const char *nano_cursorpos_msg = N_("Display the position of the cursor");
523
#ifndef DISABLE_SPELLER
524
    const char *nano_spell_msg = N_("Invoke the spell checker, if available");
525
#endif
526
    const char *nano_replace_msg = N_("Replace a string or a regular expression");
Benno Schulenberg's avatar
Benno Schulenberg committed
527
    const char *nano_gotoline_msg = N_("Go to line and column number");
528
#ifndef NANO_TINY
529
530
    const char *nano_mark_msg = N_("Mark text starting from the cursor position");
    const char *nano_whereis_next_msg = N_("Repeat the last search");
531
532
    const char *nano_copy_msg =
	N_("Copy the current line and store it in the cutbuffer");
533
534
    const char *nano_indent_msg = N_("Indent the current line");
    const char *nano_unindent_msg = N_("Unindent the current line");
535
536
    const char *nano_undo_msg = N_("Undo the last operation");
    const char *nano_redo_msg = N_("Redo the last undone operation");
537
#endif
538
539
    const char *nano_forward_msg = N_("Go forward one character");
    const char *nano_back_msg = N_("Go back one character");
540
#ifndef NANO_TINY
541
542
    const char *nano_nextword_msg = N_("Go forward one word");
    const char *nano_prevword_msg = N_("Go back one word");
543
#endif
544
545
546
547
    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");
548
549
#ifndef DISABLE_JUSTIFY
    const char *nano_parabegin_msg =
550
	N_("Go to beginning of paragraph; then of previous paragraph");
551
    const char *nano_paraend_msg =
552
	N_("Go just beyond end of paragraph; then of next paragraph");
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
553
#endif
554
555
    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
556
#ifndef NANO_TINY
557
    const char *nano_bracket_msg = N_("Go to the matching bracket");
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
558
559
560
561
    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");
562
#endif
563
#ifndef DISABLE_MULTIBUFFER
564
565
566
567
568
569
570
    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
571
572
    const char *nano_backspace_msg =
	N_("Delete the character to the left of the cursor");
573
#ifndef NANO_TINY
574
575
576
    const char *nano_cut_till_end_msg =
	N_("Cut from the cursor position to the end of the file");
#endif
577
578
#ifndef DISABLE_JUSTIFY
    const char *nano_fulljustify_msg = N_("Justify the entire file");
579
#endif
580
#ifndef NANO_TINY
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
581
582
    const char *nano_wordcount_msg =
	N_("Count the number of words, lines, and characters");
583
#endif
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
584
585
    const char *nano_refresh_msg =
	N_("Refresh (redraw) the current screen");
586
587
    const char *nano_suspend_msg =
	N_("Suspend the editor (if suspend is enabled)");
588
#ifndef NANO_TINY
589
    const char *nano_case_msg =
590
	N_("Toggle the case sensitivity of the search");
591
    const char *nano_reverse_msg =
592
	N_("Reverse the direction of the search");
593
#endif
594
#ifdef HAVE_REGEX_H
595
596
    const char *nano_regexp_msg =
	N_("Toggle the use of regular expressions");
597
#endif
598
#ifndef DISABLE_HISTORIES
599
    const char *nano_prev_history_msg =
600
	N_("Recall the previous search/replace string");
601
    const char *nano_next_history_msg =
602
	N_("Recall the next search/replace string");
603
#endif
604
605
#ifndef DISABLE_BROWSER
    const char *nano_tofiles_msg = N_("Go to file browser");
Chris Allegretta's avatar
Chris Allegretta committed
606
#endif
607
#ifndef NANO_TINY
608
609
610
611
    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");
612
    const char *nano_backup_msg = N_("Toggle backing up of the original file");
613
    const char *nano_execute_msg = N_("Execute external command");
614
#endif
615
#ifndef DISABLE_MULTIBUFFER
616
    const char *nano_multibuffer_msg = N_("Toggle the use of a new buffer");
617
618
#endif
#ifndef DISABLE_BROWSER
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
619
    const char *nano_exitbrowser_msg = N_("Exit from the file browser");
620
621
    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");
622
    const char *nano_backfile_msg = N_("Go to the previous file in the list");
623
    const char *nano_forwardfile_msg = N_("Go to the next file in the list");
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
624
    const char *nano_gotodir_msg = N_("Go to directory");
Chris Allegretta's avatar
Chris Allegretta committed
625
#endif
626
#ifndef DISABLE_COLOR
627
    const char *nano_lint_msg = N_("Invoke the linter, if available");
628
629
630
    const char *nano_prevlint_msg = N_("Go to previous linter msg");
    const char *nano_nextlint_msg = N_("Go to next linter msg");
#endif
631
#endif /* !DISABLE_HELP */
Chris Allegretta's avatar
Chris Allegretta committed
632

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
633
#ifndef DISABLE_HELP
634
#define IFSCHELP(help) help
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
635
#else
636
#define IFSCHELP(help) ""
637
#endif
638

639
640
    while (allfuncs != NULL) {
        subnfunc *f = allfuncs;
641
        allfuncs = allfuncs->next;
642
643
        free(f);
    }
644

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

647
    add_to_funcs(do_help_void, MMOST,
648
649
	/* TRANSLATORS: Try to keep the following strings at most 10 characters. */
	N_("Get Help"), IFSCHELP(nano_help_msg), FALSE, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
650

651
    add_to_funcs(do_cancel, ((MMOST & ~MMAIN & ~MBROWSER) | MYESNO),
652
	N_("Cancel"), IFSCHELP(nano_cancel_msg), FALSE, VIEW);
653

654
    add_to_funcs(do_exit, MMAIN,
655
	exit_tag, IFSCHELP(nano_exit_msg), FALSE, VIEW);
656
657
    /* Remember the entry for Exit, to be able to replace it with Close. */
    exitfunc = tailfunc;
Chris Allegretta's avatar
Chris Allegretta committed
658

659
#ifndef DISABLE_BROWSER
660
661
    add_to_funcs(do_exit, MBROWSER,
	exit_tag, IFSCHELP(nano_exitbrowser_msg), FALSE, VIEW);
662
#endif
Chris Allegretta's avatar
Chris Allegretta committed
663

664
665
    add_to_funcs(do_writeout_void, MMAIN,
	N_("Write Out"), IFSCHELP(nano_writeout_msg), FALSE, NOVIEW);
666

667
    /* We allow inserting files in view mode if multibuffers are
668
669
670
671
     * available, so that we can view multiple files.  If we're using
     * restricted mode, inserting files is disabled, since it allows
     * reading from or writing to files not specified on the command
     * line. */
672
673
    add_to_funcs(do_insertfile_void, MMAIN,
	read_file_tag, IFSCHELP(nano_insert_msg), TRUE,
674
#ifndef DISABLE_MULTIBUFFER
675
	VIEW);
676
#else
677
	NOVIEW);
678
#endif
Chris Allegretta's avatar
Chris Allegretta committed
679

680
681
    add_to_funcs(do_search, MMAIN,
	whereis_tag, IFSCHELP(nano_whereis_msg), FALSE, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
682

683
684
    add_to_funcs(do_replace, MMAIN,
	replace_tag, IFSCHELP(nano_replace_msg), FALSE, NOVIEW);
685
686

#ifndef DISABLE_BROWSER
687
688
    add_to_funcs(do_search, MBROWSER,
	whereis_tag, IFSCHELP(nano_browser_whereis_msg), FALSE, VIEW);
689

690
691
    add_to_funcs(goto_dir_void, MBROWSER,
	N_("Go To Dir"), IFSCHELP(nano_gotodir_msg), TRUE, VIEW);
692
693
#endif

694
#ifndef DISABLE_HELP
695
696
    /* The description ("x") and blank_after (0) are irrelevant,
     * because the help viewer does not have a help text. */
697
    add_to_funcs(do_exit, MHELP, exit_tag, "x", 0, VIEW);
698

699
    add_to_funcs(total_refresh, MHELP, refresh_tag, "x", 0, VIEW);
700
701
702

    add_to_funcs(do_up_void, MHELP, prev_line_tag, "x", 0, VIEW);
    add_to_funcs(do_down_void, MHELP, next_line_tag, "x" , 0, VIEW);
703
704
#endif

705
706
    add_to_funcs(do_cut_text_void, MMAIN,
	N_("Cut Text"), IFSCHELP(nano_cut_msg), FALSE, NOVIEW);
Chris Allegretta's avatar
Chris Allegretta committed
707

708
709
    add_to_funcs(do_uncut_text, MMAIN,
	uncut_tag, IFSCHELP(nano_uncut_msg), TRUE, NOVIEW);
710
    /* Remember the entry for Uncut, to be able to replace it with Unjustify. */
711
    uncutfunc = tailfunc;
Chris Allegretta's avatar
Chris Allegretta committed
712

713
#ifndef DISABLE_JUSTIFY
714
715
    add_to_funcs(do_justify_void, MMAIN,
	N_("Justify"), IFSCHELP(nano_justify_msg), FALSE, NOVIEW);
Chris Allegretta's avatar
Chris Allegretta committed
716
#endif
Chris Allegretta's avatar
Chris Allegretta committed
717

718
#ifndef DISABLE_SPELLER
719
720
    add_to_funcs(do_spell, MMAIN,
	N_("To Spell"), IFSCHELP(nano_spell_msg), FALSE, NOVIEW);
721
#endif
722

723
#ifndef DISABLE_COLOR
724
725
    add_to_funcs(do_linter, MMAIN,
	N_("To Linter"), IFSCHELP(nano_lint_msg), TRUE, NOVIEW);
726
727
#endif

728
#ifndef NANO_TINY
729
    add_to_funcs(case_sens_void, MWHEREIS|MREPLACE,
730
731
732
733
	N_("Case Sens"), IFSCHELP(nano_case_msg), FALSE, VIEW);
#endif

#ifdef HAVE_REGEX_H
734
    add_to_funcs(regexp_void, MWHEREIS|MREPLACE,
735
736
737
738
	N_("Regexp"), IFSCHELP(nano_regexp_msg), FALSE, VIEW);
#endif

#ifndef NANO_TINY
739
    add_to_funcs(backwards_void, MWHEREIS|MREPLACE,
740
741
742
	N_("Backwards"), IFSCHELP(nano_reverse_msg), FALSE, VIEW);
#endif

743
    add_to_funcs(flip_replace_void, MWHEREIS,
744
745
	replace_tag, IFSCHELP(nano_replace_msg), FALSE, VIEW);

746
    add_to_funcs(flip_replace_void, MREPLACE,
747
748
749
	N_("No Replace"), IFSCHELP(nano_whereis_msg), FALSE, VIEW);

#ifndef DISABLE_JUSTIFY
750
751
    add_to_funcs(do_full_justify, MWHEREIS,
	fulljustify_tag, IFSCHELP(nano_fulljustify_msg), FALSE, NOVIEW);
752
753
#endif

754
755
    add_to_funcs(do_cursorpos_void, MMAIN,
	N_("Cur Pos"), IFSCHELP(nano_cursorpos_msg), FALSE, VIEW);
756

757
758
759
#if !defined(NANO_TINY) || defined(DISABLE_COLOR)
    /* Conditionally placing this one here or further on, to keep the
     * help items nicely paired in most conditions. */
760
761
    add_to_funcs(do_gotolinecolumn_void, MMAIN|MWHEREIS,
	gotoline_tag, IFSCHELP(nano_gotoline_msg), TRUE, VIEW);
762
#endif
763
764
765
766
767

    add_to_funcs(do_page_up, MMAIN|MHELP|MBROWSER,
	N_("Prev Page"), IFSCHELP(nano_prevpage_msg), FALSE, VIEW);
    add_to_funcs(do_page_down, MMAIN|MHELP|MBROWSER,
	N_("Next Page"), IFSCHELP(nano_nextpage_msg), FALSE, VIEW);
768

769
    add_to_funcs(do_first_line, MMAIN|MHELP|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE,
770
	N_("First Line"), IFSCHELP(nano_firstline_msg), FALSE, VIEW);
771
    add_to_funcs(do_last_line, MMAIN|MHELP|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE,
772
	N_("Last Line"), IFSCHELP(nano_lastline_msg), TRUE, VIEW);
773

774
#ifndef NANO_TINY
775
776
    add_to_funcs(do_research, MMAIN,
	whereis_next_tag, IFSCHELP(nano_whereis_next_msg), FALSE, VIEW);
777

778
779
    add_to_funcs(do_find_bracket, MMAIN,
	N_("To Bracket"), IFSCHELP(nano_bracket_msg), FALSE, VIEW);
780

781
782
    add_to_funcs(do_mark, MMAIN,
	N_("Mark Text"), IFSCHELP(nano_mark_msg), FALSE, VIEW);
783

784
785
    add_to_funcs(do_copy_text, MMAIN,
	N_("Copy Text"), IFSCHELP(nano_copy_msg), TRUE, NOVIEW);
786

787
788
789
790
    add_to_funcs(do_indent_void, MMAIN,
	N_("Indent Text"), IFSCHELP(nano_indent_msg), FALSE, NOVIEW);
    add_to_funcs(do_unindent, MMAIN,
	N_("Unindent Text"), IFSCHELP(nano_unindent_msg), TRUE, NOVIEW);
791

792
793
794
795
    add_to_funcs(do_undo, MMAIN,
	N_("Undo"), IFSCHELP(nano_undo_msg), FALSE, NOVIEW);
    add_to_funcs(do_redo, MMAIN,
	N_("Redo"), IFSCHELP(nano_redo_msg), TRUE, NOVIEW);
796
#endif /* !NANO_TINY */
797

798
799
800
801
    add_to_funcs(do_left, MMAIN,
	N_("Back"), IFSCHELP(nano_back_msg), FALSE, VIEW);
    add_to_funcs(do_right, MMAIN,
	N_("Forward"), IFSCHELP(nano_forward_msg), FALSE, VIEW);
802
803

#ifndef DISABLE_BROWSER
804
805
806
807
    add_to_funcs(do_left, MBROWSER,
	N_("Back"), IFSCHELP(nano_backfile_msg), FALSE, VIEW);
    add_to_funcs(do_right, MBROWSER,
	N_("Forward"), IFSCHELP(nano_forwardfile_msg), FALSE, VIEW);
808
809
#endif

810
#ifndef NANO_TINY
811
812
813
814
    add_to_funcs(do_prev_word_void, MMAIN,
	N_("Prev Word"), IFSCHELP(nano_prevword_msg), FALSE, VIEW);
    add_to_funcs(do_next_word_void, MMAIN,
	N_("Next Word"), IFSCHELP(nano_nextword_msg), FALSE, VIEW);
815
#endif
816

817
818
819
820
    add_to_funcs(do_home, MMAIN,
	N_("Home"), IFSCHELP(nano_home_msg), FALSE, VIEW);
    add_to_funcs(do_end, MMAIN,
	N_("End"), IFSCHELP(nano_end_msg), FALSE, VIEW);
821

822
823
824
825
    add_to_funcs(do_up_void, MMAIN|MBROWSER,
	prev_line_tag, IFSCHELP(nano_prevline_msg), FALSE, VIEW);
    add_to_funcs(do_down_void, MMAIN|MBROWSER,
	next_line_tag, IFSCHELP(nano_nextline_msg), TRUE, VIEW);
826

827
#ifndef DISABLE_JUSTIFY
828
829
830
831
    add_to_funcs(do_para_begin_void, MMAIN|MWHEREIS,
	N_("Beg of Par"), IFSCHELP(nano_parabegin_msg), FALSE, VIEW);
    add_to_funcs(do_para_end_void, MMAIN|MWHEREIS,
	N_("End of Par"), IFSCHELP(nano_paraend_msg), FALSE, VIEW);
832
#endif
833

834
#ifndef NANO_TINY
835
836
837
838
    add_to_funcs(do_scroll_up, MMAIN,
	N_("Scroll Up"), IFSCHELP(nano_scrollup_msg), FALSE, VIEW);
    add_to_funcs(do_scroll_down, MMAIN,
	N_("Scroll Down"), IFSCHELP(nano_scrolldown_msg), TRUE, VIEW);
839
840
#endif

841
#ifndef DISABLE_MULTIBUFFER
842
843
844
845
    add_to_funcs(switch_to_prev_buffer_void, MMAIN,
	N_("Prev File"), IFSCHELP(nano_prevfile_msg), FALSE, VIEW);
    add_to_funcs(switch_to_next_buffer_void, MMAIN,
	N_("Next File"), IFSCHELP(nano_nextfile_msg), TRUE, VIEW);
846
847
#endif

848
849
850
851
852
#if defined(NANO_TINY) && !defined(DISABLE_COLOR)
    add_to_funcs(do_gotolinecolumn_void, MMAIN|MWHEREIS,
	gotoline_tag, IFSCHELP(nano_gotoline_msg), TRUE, VIEW);
#endif

853
854
    add_to_funcs(do_verbatim_input, MMAIN,
	N_("Verbatim"), IFSCHELP(nano_verbatim_msg), FALSE, NOVIEW);
855

856
857
858
859
860
861
862
863
    add_to_funcs(do_tab, MMAIN,
	N_("Tab"), IFSCHELP(nano_tab_msg), FALSE, NOVIEW);
    add_to_funcs(do_enter_void, MMAIN,
	N_("Enter"), IFSCHELP(nano_enter_msg), FALSE, NOVIEW);
    add_to_funcs(do_delete, MMAIN,
	N_("Delete"), IFSCHELP(nano_delete_msg), FALSE, NOVIEW);
    add_to_funcs(do_backspace, MMAIN,
	N_("Backspace"), IFSCHELP(nano_backspace_msg),
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
864
#ifndef NANO_TINY
865
	FALSE,
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
866
#else
867
	TRUE,
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
868
#endif
869
870
	NOVIEW);

871
#ifndef NANO_TINY
872
873
    add_to_funcs(do_cut_till_end, MMAIN,
	N_("CutTillEnd"), IFSCHELP(nano_cut_till_end_msg), TRUE, NOVIEW);
874
#endif
Chris Allegretta's avatar
Chris Allegretta committed
875

876
#ifndef DISABLE_JUSTIFY
877
878
    add_to_funcs(do_full_justify, MMAIN,
	fulljustify_tag, IFSCHELP(nano_fulljustify_msg), FALSE, NOVIEW);
879
880
#endif

881
#ifndef NANO_TINY
882
883
    add_to_funcs(do_wordlinechar_count, MMAIN,
	N_("Word Count"), IFSCHELP(nano_wordcount_msg), FALSE, VIEW);
884
#endif
885

886
887
    add_to_funcs(total_refresh, MMAIN,
	refresh_tag, IFSCHELP(nano_refresh_msg), FALSE, VIEW);
888

889
890
    add_to_funcs(do_suspend_void, MMAIN,
	N_("Suspend"), IFSCHELP(nano_suspend_msg), TRUE, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
891

892
#ifndef DISABLE_HISTORIES
893
    add_to_funcs(get_history_older_void,
894
	(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE),
895
	N_("PrevHstory"), IFSCHELP(nano_prev_history_msg), FALSE, VIEW);
896
    add_to_funcs(get_history_newer_void,
897
	(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE),
898
	N_("NextHstory"), IFSCHELP(nano_next_history_msg), FALSE, VIEW);
899
#endif
900

901
    add_to_funcs(gototext_void, MGOTOLINE,
902
	N_("Go To Text"), IFSCHELP(nano_whereis_msg), TRUE, VIEW);
903

904
#ifndef NANO_TINY
905
906
907
908
909
910
    /* If we're using restricted mode, the DOS format, Mac format,
     * append, prepend, and backup toggles are disabled.  The first and
     * second are useless since inserting files is disabled, the third
     * and fourth are disabled because they allow writing to files not
     * specified on the command line, and the fifth is useless since
     * backups are disabled. */
911
    if (!ISSET(RESTRICTED)) {
912
        add_to_funcs(dos_format_void, MWRITEFILE,
913
            N_("DOS Format"), IFSCHELP(nano_dos_msg), FALSE, NOVIEW);
914

915
        add_to_funcs(mac_format_void, MWRITEFILE,
916
            N_("Mac Format"), IFSCHELP(nano_mac_msg), FALSE, NOVIEW);
917

Benno Schulenberg's avatar
Benno Schulenberg committed
918
        add_to_funcs(append_void, MWRITEFILE,
919
            N_("Append"), IFSCHELP(nano_append_msg), FALSE, NOVIEW);
Benno Schulenberg's avatar
Benno Schulenberg committed
920
        add_to_funcs(prepend_void, MWRITEFILE,
921
            N_("Prepend"), IFSCHELP(nano_prepend_msg), FALSE, NOVIEW);
922

Benno Schulenberg's avatar
Benno Schulenberg committed
923
        add_to_funcs(backup_file_void, MWRITEFILE,
924
            N_("Backup File"), IFSCHELP(nano_backup_msg), FALSE, NOVIEW);
925
    }
926

927
928
929
    /* If we're using restricted mode, file insertion is disabled, and
     * thus command execution and the multibuffer toggle have no place. */
    if (!ISSET(RESTRICTED)) {
930
        add_to_funcs(flip_execute_void, MINSERTFILE,
931
	    N_("Execute Command"), IFSCHELP(nano_execute_msg), FALSE, NOVIEW);
932

933
        add_to_funcs(flip_execute_void, MEXTCMD,
934
935
	    read_file_tag, IFSCHELP(nano_insert_msg), FALSE, NOVIEW);

936
#ifndef DISABLE_MULTIBUFFER
937
	add_to_funcs(new_buffer_void, MINSERTFILE|MEXTCMD,
938
	    N_("New Buffer"), IFSCHELP(nano_multibuffer_msg), FALSE, NOVIEW);
939
#endif
940
    }
941
#endif /* !NANO_TINY */
942

943
#ifndef DISABLE_BROWSER
944
945
946
947
    if (!ISSET(RESTRICTED))
	add_to_funcs(to_files_void, MWRITEFILE|MINSERTFILE,
	    N_("To Files"), IFSCHELP(nano_tofiles_msg), FALSE, VIEW);

Benno Schulenberg's avatar
Benno Schulenberg committed
948
    add_to_funcs(do_first_file, (MBROWSER|MWHEREISFILE),
949
	N_("First File"), IFSCHELP(nano_firstfile_msg), FALSE, VIEW);
Benno Schulenberg's avatar
Benno Schulenberg committed
950
    add_to_funcs(do_last_file, (MBROWSER|MWHEREISFILE),
951
	N_("Last File"), IFSCHELP(nano_lastfile_msg), FALSE, VIEW);
952
#endif
Chris Allegretta's avatar
Chris Allegretta committed
953

954
#if !defined(NANO_TINY) && !defined(DISABLE_BROWSER)
955
956
    add_to_funcs(do_research, MBROWSER,
	whereis_next_tag, IFSCHELP(nano_whereis_next_msg), FALSE, VIEW);
957
958
959
#endif

#ifndef DISABLE_COLOR
960
    /* TRANSLATORS: Try to keep the next two strings at most 20 characters. */
961
    add_to_funcs(do_page_up, MLINTER,
962
	N_("Prev Lint Msg"), IFSCHELP(nano_prevlint_msg), FALSE, VIEW);
963
    add_to_funcs(do_page_down, MLINTER,
964
	N_("Next Lint Msg"), IFSCHELP(nano_nextlint_msg), FALSE, VIEW);
965
966
#endif

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

969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
    add_to_sclist(MMOST, "^G", do_help_void, 0);
    add_to_sclist(MMOST, "F1", do_help_void, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "^X", do_exit, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "F2", do_exit, 0);
    add_to_sclist(MMAIN, "^O", do_writeout_void, 0);
    add_to_sclist(MMAIN, "F3", do_writeout_void, 0);
    add_to_sclist(MMAIN, "^R", do_insertfile_void, 0);
    add_to_sclist(MMAIN, "F5", do_insertfile_void, 0);
    add_to_sclist(MMAIN, "Ins", do_insertfile_void, 0);
    add_to_sclist(MMAIN|MBROWSER, "^W", do_search, 0);
    add_to_sclist(MMAIN|MBROWSER, "F6", do_search, 0);
    add_to_sclist(MMAIN, "^\\", do_replace, 0);
    add_to_sclist(MMAIN, "M-R", do_replace, 0);
    add_to_sclist(MMAIN, "F14", do_replace, 0);
    add_to_sclist(MMOST, "^K", do_cut_text_void, 0);
    add_to_sclist(MMOST, "F9", do_cut_text_void, 0);
    add_to_sclist(MMAIN, "^U", do_uncut_text, 0);
    add_to_sclist(MMAIN, "F10", do_uncut_text, 0);
987
#ifndef DISABLE_JUSTIFY
988
989
    add_to_sclist(MMAIN, "^J", do_justify_void, 0);
    add_to_sclist(MMAIN, "F4", do_justify_void, 0);
990
#endif
991
#ifndef DISABLE_SPELLER
992
993
    add_to_sclist(MMAIN, "^T", do_spell, 0);
    add_to_sclist(MMAIN, "F12", do_spell, 0);
994
995
#else
#ifndef DISABLE_COLOR
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
    add_to_sclist(MMAIN, "^T", do_linter, 0);
    add_to_sclist(MMAIN, "F12", do_linter, 0);
#endif
#endif
    add_to_sclist(MMAIN, "^C", do_cursorpos_void, 0);
    add_to_sclist(MMAIN, "F11", do_cursorpos_void, 0);
    add_to_sclist(MMAIN, "^_", do_gotolinecolumn_void, 0);
    add_to_sclist(MMAIN, "M-G", do_gotolinecolumn_void, 0);
    add_to_sclist(MMAIN, "F13", do_gotolinecolumn_void, 0);
    add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE|MLINTER, "^Y", do_page_up, 0);
    add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE|MLINTER, "F7", do_page_up, 0);
    add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE|MLINTER, "PgUp", do_page_up, 0);
    add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE|MLINTER, "^V", do_page_down, 0);
    add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE|MLINTER, "F8", do_page_down, 0);
    add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE|MLINTER, "PgDn", do_page_down, 0);
    add_to_sclist(MMAIN|MHELP, "M-\\", do_first_line, 0);
    add_to_sclist(MMAIN|MHELP, "M-|", do_first_line, 0);
    add_to_sclist(MMAIN|MHELP, "M-/", do_last_line, 0);
    add_to_sclist(MMAIN|MHELP, "M-?", do_last_line, 0);
1015
#ifndef NANO_TINY
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
    add_to_sclist(MMAIN|MBROWSER, "M-W", do_research, 0);
    add_to_sclist(MMAIN|MBROWSER, "F16", do_research, 0);
    add_to_sclist(MMAIN, "M-]", do_find_bracket, 0);
    add_to_sclist(MMAIN, "^^", do_mark, 0);
    add_to_sclist(MMAIN, "M-A", do_mark, 0);
    add_to_sclist(MMAIN, "F15", do_mark, 0);
    add_to_sclist(MMAIN, "M-^", do_copy_text, 0);
    add_to_sclist(MMAIN, "M-6", do_copy_text, 0);
    add_to_sclist(MMAIN, "M-}", do_indent_void, 0);
    add_to_sclist(MMAIN, "M-{", do_unindent, 0);
    add_to_sclist(MMAIN, "M-U", do_undo, 0);
    add_to_sclist(MMAIN, "M-E", do_redo, 0);
#endif
    add_to_sclist(MMOST, "^B", do_left, 0);
    add_to_sclist(MMOST, "Left", do_left, 0);
    add_to_sclist(MMOST, "^F", do_right, 0);
    add_to_sclist(MMOST, "Right", do_right, 0);
1033
#ifndef NANO_TINY
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
    add_to_sclist(MMOST, "M-Space", do_prev_word_void, 0);
    add_to_sclist(MMOST, "^Space", do_next_word_void, 0);
#endif
    add_to_sclist(MMOST, "^A", do_home, 0);
    add_to_sclist(MMOST, "Home", do_home, 0);
    add_to_sclist(MMOST, "^E", do_end, 0);
    add_to_sclist(MMOST, "End", do_end, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "^P", do_up_void, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "Up", do_up_void, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", do_down_void, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", do_down_void, 0);
1045
#ifndef DISABLE_JUSTIFY
1046
1047
1048
1049
    add_to_sclist(MMAIN, "M-(", do_para_begin_void, 0);
    add_to_sclist(MMAIN, "M-9", do_para_begin_void, 0);
    add_to_sclist(MMAIN, "M-)", do_para_end_void, 0);
    add_to_sclist(MMAIN, "M-0", do_para_end_void, 0);
Benno Schulenberg's avatar
Benno Schulenberg committed
1050
#endif
1051
#ifndef NANO_TINY
1052
1053
1054
1055
    add_to_sclist(MMAIN, "M--", do_scroll_up, 0);
    add_to_sclist(MMAIN, "M-_", do_scroll_up, 0);
    add_to_sclist(MMAIN, "M-+", do_scroll_down, 0);
    add_to_sclist(MMAIN, "M-=", do_scroll_down, 0);
1056
#endif
1057
#ifndef DISABLE_MULTIBUFFER
1058
1059
1060
1061
    add_to_sclist(MMAIN, "M-<", switch_to_prev_buffer_void, 0);
    add_to_sclist(MMAIN, "M-,", switch_to_prev_buffer_void, 0);
    add_to_sclist(MMAIN, "M->", switch_to_next_buffer_void, 0);
    add_to_sclist(MMAIN, "M-.", switch_to_next_buffer_void, 0);
1062
#endif
1063
    add_to_sclist(MMOST, "M-V", do_verbatim_input, 0);
1064
#ifndef NANO_TINY
1065
1066
    add_to_sclist(MMAIN, "M-T", do_cut_till_end, 0);
    add_to_sclist(MMAIN, "M-D", do_wordlinechar_count, 0);
1067
#endif
1068
#ifndef DISABLE_JUSTIFY
1069
    add_to_sclist(MMAIN|MWHEREIS, "M-J", do_full_justify, 0);
1070
#endif
1071
1072
    add_to_sclist(MMAIN|MHELP, "^L", total_refresh, 0);
    add_to_sclist(MMAIN, "^Z", do_suspend_void, 0);
1073

1074
#ifndef NANO_TINY
1075
    /* Group of "Appearance" toggles. */
1076
1077
1078
1079
1080
1081
    add_to_sclist(MMAIN, "M-X", do_toggle_void, NO_HELP);
    add_to_sclist(MMAIN, "M-C", do_toggle_void, CONST_UPDATE);
    add_to_sclist(MMAIN, "M-O", do_toggle_void, MORE_SPACE);
    add_to_sclist(MMAIN, "M-S", do_toggle_void, SMOOTH_SCROLL);
    add_to_sclist(MMAIN, "M-$", do_toggle_void, SOFTWRAP);
    add_to_sclist(MMAIN, "M-P", do_toggle_void, WHITESPACE_DISPLAY);
1082
#ifndef DISABLE_COLOR
1083
    add_to_sclist(MMAIN, "M-Y", do_toggle_void, NO_COLOR_SYNTAX);
1084
#endif
1085

1086
    /* Group of "Editing-behavior" toggles. */
1087
1088
1089
    add_to_sclist(MMAIN, "M-H", do_toggle_void, SMART_HOME);
    add_to_sclist(MMAIN, "M-I", do_toggle_void, AUTOINDENT);
    add_to_sclist(MMAIN, "M-K", do_toggle_void, CUT_TO_END);
1090
#ifndef DISABLE_WRAPPING
1091
    add_to_sclist(MMAIN, "M-L", do_toggle_void, NO_WRAP);
1092
#endif
1093
    add_to_sclist(MMAIN, "M-Q", do_toggle_void, TABS_TO_SPACES);
1094

1095
    /* Group of "Peripheral-feature" toggles. */
1096
    add_to_sclist(MMAIN, "M-B", do_toggle_void, BACKUP_FILE);
1097
#ifndef DISABLE_MULTIBUFFER
1098
    add_to_sclist(MMAIN, "M-F", do_toggle_void, MULTIBUFFER);
1099
1100
#endif
#ifndef DISABLE_MOUSE
1101
    add_to_sclist(MMAIN, "M-M", do_toggle_void, USE_MOUSE);
1102
#endif
1103
1104
    add_to_sclist(MMAIN, "M-N", do_toggle_void, NO_CONVERT);
    add_to_sclist(MMAIN, "M-Z", do_toggle_void, SUSPEND);
1105
#endif /* !NANO_TINY */
Benno Schulenberg's avatar
Benno Schulenberg committed
1106

1107
1108
    add_to_sclist(MMAIN, "^Q", xon_complaint, 0);
    add_to_sclist(MMAIN, "^S", xoff_complaint, 0);
1109

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

1112
#ifndef NANO_TINY
1113
1114
    add_to_sclist(MWHEREIS|MREPLACE, "M-B", backwards_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE, "M-C", case_sens_void, 0);
1115
#endif
1116
1117
1118
1119
    add_to_sclist(MWHEREIS|MREPLACE, "M-R", regexp_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE, "^R", flip_replace_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE, "^Y", do_first_line, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE, "^V", do_last_line, 0);
1120
#ifndef DISABLE_JUSTIFY
1121
1122
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^W", do_para_begin_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^O", do_para_end_void, 0);
1123
#endif
1124
1125
    add_to_sclist(MWHEREIS, "^T", do_gotolinecolumn_void, 0);
    add_to_sclist(MGOTOLINE, "^T", gototext_void, 0);
1126
#ifndef DISABLE_HISTORIES
1127
1128
1129
1130
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "^P", get_history_older_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "Up", get_history_older_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "^N", get_history_newer_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "Down", get_history_newer_void, 0);
1131
1132
#endif
#ifndef DISABLE_BROWSER
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-\\", do_first_file, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-|", do_first_file, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-/", do_last_file, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-?", do_last_file, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "^_", goto_dir_void, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-G", goto_dir_void, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "F13", goto_dir_void, 0);
#endif
    add_to_sclist(MWRITEFILE, "M-D", dos_format_void, 0);
    add_to_sclist(MWRITEFILE, "M-M", mac_format_void, 0);
    add_to_sclist(MWRITEFILE, "M-A", append_void, 0);
    add_to_sclist(MWRITEFILE, "M-P", prepend_void, 0);
    add_to_sclist(MWRITEFILE, "M-B", backup_file_void, 0);
1146
#ifndef DISABLE_BROWSER
1147
    add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", to_files_void, 0);
1148
#endif
1149
1150
1151
    add_to_sclist(MINSERTFILE|MEXTCMD, "^X", flip_execute_void, 0);
    add_to_sclist(MINSERTFILE|MEXTCMD, "M-F", new_buffer_void, 0);
    add_to_sclist(MHELP|MBROWSER, "^C", do_exit, 0);
1152
#ifndef DISABLE_HELP
1153
    add_to_sclist(MHELP, "^G", do_exit, 0);
1154
#endif
1155
1156
1157
1158
1159
1160
1161
    add_to_sclist(MMOST, "^I", do_tab, 0);
    add_to_sclist(MMOST, "^M", do_enter_void, 0);
    add_to_sclist(MMOST, "Enter", do_enter_void, 0);
    add_to_sclist(MMOST, "^D", do_delete, 0);
    add_to_sclist(MMOST, "Del", do_delete, 0);
    add_to_sclist(MMOST, "^H", do_backspace, 0);
    add_to_sclist(MMOST, "Bsp", do_backspace, 0);
Chris Allegretta's avatar
Chris Allegretta committed
1162

1163
1164
#ifdef DEBUG
    print_sclist();
Chris Allegretta's avatar
Chris Allegretta committed
1165
#endif
1166
}
1167

1168
#ifndef DISABLE_COLOR
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
void set_lint_shortcuts(void)
{
#ifndef DISABLE_SPELLER
    replace_scs_for(do_spell, do_linter);
#endif
}

void set_spell_shortcuts(void)
{
#ifndef DISABLE_SPELLER
    replace_scs_for(do_linter, do_spell);
#endif
}
#endif

1184
const subnfunc *sctofunc(sc *s)
1185
{
1186
    subnfunc *f;
1187

1188
1189
    for (f = allfuncs; f != NULL && s->scfunc != f->scfunc; f = f->next)
	;
1190

1191
    return f;
1192
1193
}

1194
#ifndef NANO_TINY
1195
1196
/* Now let's come up with a single (hopefully) function to get a string
 * for each flag. */
1197
const char *flagtostr(int flag)
1198
{
1199
    switch (flag) {
1200
        case NO_HELP:
1201
1202
            /* TRANSLATORS: The next seventeen strings are toggle descriptions;
             * they are best kept shorter than 40 characters, but may be longer. */
1203
1204
1205
1206
1207
1208
1209
            return N_("Help mode");
        case CONST_UPDATE:
            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");
1210
1211
        case SOFTWRAP:
            return N_("Soft wrapping of overlong lines");
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
        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");
        case CUT_TO_END:
            return N_("Cut to end");
        case NO_WRAP:
1223
            return N_("Hard wrapping of overlong lines");
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
        case TABS_TO_SPACES:
            return N_("Conversion of typed tabs to spaces");
        case BACKUP_FILE:
            return N_("Backup files");
        case MULTIBUFFER:
            return N_("Multiple file buffers");
        case USE_MOUSE:
            return N_("Mouse support");
        case NO_CONVERT:
            return N_("No conversion from DOS/Mac format");
        case SUSPEND:
            return N_("Suspension");
        default:
            return "?????";
    }
}
1240
#endif /* !NANO_TINY */
1241

1242
#ifndef DISABLE_NANORC
1243
/* Interpret a function string given in the rc file, and return a
1244
 * shortcut struct with the corresponding function filled in. */
1245
sc *strtosc(char *input)
1246
{
1247
    sc *s;
1248
1249
1250

    s = (sc *)nmalloc(sizeof(sc));

Chris Allegretta's avatar
Chris Allegretta committed
1251
#ifndef DISABLE_HELP
1252
    if (!strcasecmp(input, "help"))
1253
1254
	s->scfunc = do_help_void;
    else
Chris Allegretta's avatar
Chris Allegretta committed
1255
1256
#endif
    if (!strcasecmp(input, "cancel")) {
1257
	s->scfunc = do_cancel;
1258
    } else if (!strcasecmp(input, "exit"))
1259
	s->scfunc = do_exit;
1260
    else if (!strcasecmp(input, "writeout"))
1261
	s->scfunc = do_writeout_void;
1262
    else if (!strcasecmp(input, "insert"))
1263
	s->scfunc = do_insertfile_void;
1264
    else if (!strcasecmp(input, "whereis"))
1265
	s->scfunc = do_search;
1266
#ifndef NANO_TINY
1267
1268
1269
    else if (!strcasecmp(input, "searchagain") ||
	     !strcasecmp(input, "research"))
	s->scfunc = do_research;
1270
#endif
1271
1272
    else if (!strcasecmp(input, "replace"))
	s->scfunc = do_replace;
1273
    else if (!strcasecmp(input, "cut"))
1274
	s->scfunc = do_cut_text_void;
1275
    else if (!strcasecmp(input, "uncut"))
1276
	s->scfunc = do_uncut_text;
1277
#ifndef NANO_TINY
1278
1279
    else if (!strcasecmp(input, "cutrestoffile"))
	s->scfunc = do_cut_till_end;
1280
1281
    else if (!strcasecmp(input, "copytext"))
	s->scfunc = do_copy_text;
1282
1283
    else if (!strcasecmp(input, "mark"))
	s->scfunc = do_mark;
1284
1285
#endif
#ifndef DISABLE_SPELLER
1286
1287
1288
    else if (!strcasecmp(input, "tospell") ||
	     !strcasecmp(input, "speller"))
	s->scfunc = do_spell;
1289
#endif
1290
    else if (!strcasecmp(input, "curpos") ||
1291
	     !strcasecmp(input, "cursorpos"))
1292
	s->scfunc = do_cursorpos_void;
1293
    else if (!strcasecmp(input, "gotoline"))
1294
	s->scfunc = do_gotolinecolumn_void;
1295
#ifndef DISABLE_JUSTIFY
Chris Allegretta's avatar
Chris Allegretta committed
1296
    else if (!strcasecmp(input, "justify"))
1297
	s->scfunc = do_justify_void;
1298
1299
    else if (!strcasecmp(input, "fulljustify"))
	s->scfunc = do_full_justify;
1300
    else if (!strcasecmp(input, "beginpara"))
1301
	s->scfunc = do_para_begin_void;
1302
    else if (!strcasecmp(input, "endpara"))
1303
	s->scfunc = do_para_end_void;
1304
1305
#endif
#ifndef NANO_TINY
1306
    else if (!strcasecmp(input, "indent"))
1307
	s->scfunc = do_indent_void;
1308
    else if (!strcasecmp(input, "unindent"))
1309
	s->scfunc = do_unindent;
Chris Allegretta's avatar
Chris Allegretta committed
1310
    else if (!strcasecmp(input, "scrollup"))
1311
	s->scfunc = do_scroll_up;
Chris Allegretta's avatar
Chris Allegretta committed
1312
    else if (!strcasecmp(input, "scrolldown"))
1313
	s->scfunc = do_scroll_down;
1314
    else if (!strcasecmp(input, "prevword"))
1315
	s->scfunc = do_prev_word_void;
1316
1317
    else if (!strcasecmp(input, "nextword"))
	s->scfunc = do_next_word_void;
1318
    else if (!strcasecmp(input, "findbracket"))
1319
	s->scfunc = do_find_bracket;
1320
    else if (!strcasecmp(input, "wordcount"))
1321
	s->scfunc = do_wordlinechar_count;
1322
    else if (!strcasecmp(input, "undo"))
1323
	s->scfunc = do_undo;
1324
    else if (!strcasecmp(input, "redo"))
1325
	s->scfunc = do_redo;
1326
#endif
1327
#ifndef DISABLE_HISTORIES
1328
    else if (!strcasecmp(input, "prevhistory")) {
1329
	s->scfunc = get_history_older_void;
1330
    } else if (!strcasecmp(input, "nexthistory")) {
1331
	s->scfunc = get_history_newer_void;
1332
    }
1333
#endif
Chris Allegretta's avatar
Chris Allegretta committed
1334
    else if (!strcasecmp(input, "left") ||
1335
	     !strcasecmp(input, "back"))
1336
	s->scfunc = do_left;
1337
1338
1339
    else if (!strcasecmp(input, "right") ||
	     !strcasecmp(input, "forward"))
	s->scfunc = do_right;
Chris Allegretta's avatar
Chris Allegretta committed
1340
    else if (!strcasecmp(input, "up") ||
1341
	     !strcasecmp(input, "prevline"))
1342
	s->scfunc = do_up_void;
Chris Allegretta's avatar
Chris Allegretta committed
1343
    else if (!strcasecmp(input, "down") ||
1344
	     !strcasecmp(input, "nextline"))
1345
	s->scfunc = do_down_void;
Chris Allegretta's avatar
Chris Allegretta committed
1346
    else if (!strcasecmp(input, "home"))
1347
	s->scfunc = do_home;
Chris Allegretta's avatar
Chris Allegretta committed
1348
    else if (!strcasecmp(input, "end"))
1349
	s->scfunc = do_end;
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
    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;
1360
#ifndef DISABLE_MULTIBUFFER
Chris Allegretta's avatar
Chris Allegretta committed
1361
    else if (!strcasecmp(input, "prevbuf"))
1362
	s->scfunc = switch_to_prev_buffer_void;
Chris Allegretta's avatar
Chris Allegretta committed
1363
    else if (!strcasecmp(input, "nextbuf"))
1364
	s->scfunc = switch_to_next_buffer_void;
Chris Allegretta's avatar
Chris Allegretta committed
1365
1366
#endif
    else if (!strcasecmp(input, "verbatim"))
1367
	s->scfunc = do_verbatim_input;
Chris Allegretta's avatar
Chris Allegretta committed
1368
    else if (!strcasecmp(input, "tab"))
1369
	s->scfunc = do_tab;
Chris Allegretta's avatar
Chris Allegretta committed
1370
    else if (!strcasecmp(input, "enter"))
1371
	s->scfunc = do_enter_void;
Chris Allegretta's avatar
Chris Allegretta committed
1372
    else if (!strcasecmp(input, "delete"))
1373
	s->scfunc = do_delete;
1374
    else if (!strcasecmp(input, "backspace"))
1375
	s->scfunc = do_backspace;
Chris Allegretta's avatar
Chris Allegretta committed
1376
    else if (!strcasecmp(input, "refresh"))
1377
	s->scfunc = total_refresh;
1378
1379
    else if (!strcasecmp(input, "suspend"))
	s->scfunc = do_suspend_void;
Chris Allegretta's avatar
Chris Allegretta committed
1380
    else if (!strcasecmp(input, "casesens")) {
1381
	s->scfunc = case_sens_void;
1382
#ifndef NANO_TINY
Chris Allegretta's avatar
Chris Allegretta committed
1383
    } else if (!strcasecmp(input, "regexp") ||
1384
	       !strcasecmp(input, "regex")) {
1385
	s->scfunc = regexp_void;
Benno Schulenberg's avatar
Oops.    
Benno Schulenberg committed
1386
    } else if (!strcasecmp(input, "backwards")) {
1387
	s->scfunc = backwards_void;
1388
#endif
1389
1390
1391
    } else if (!strcasecmp(input, "flipreplace") ||
	       !strcasecmp(input, "dontreplace")) {
	s->scfunc = flip_replace_void;
Chris Allegretta's avatar
Chris Allegretta committed
1392
    } else if (!strcasecmp(input, "gototext")) {
1393
	s->scfunc = gototext_void;
Chris Allegretta's avatar
Chris Allegretta committed
1394
    } else if (!strcasecmp(input, "dosformat")) {
1395
	s->scfunc = dos_format_void;
Chris Allegretta's avatar
Chris Allegretta committed
1396
    } else if (!strcasecmp(input, "macformat")) {
1397
	s->scfunc = mac_format_void;
Chris Allegretta's avatar
Chris Allegretta committed
1398
    } else if (!strcasecmp(input, "append")) {
1399
	s->scfunc = append_void;
Chris Allegretta's avatar
Chris Allegretta committed
1400
    } else if (!strcasecmp(input, "prepend")) {
1401
	s->scfunc = prepend_void;
Chris Allegretta's avatar
Chris Allegretta committed
1402
    } else if (!strcasecmp(input, "backup")) {
1403
	s->scfunc = backup_file_void;
1404
1405
1406
1407
#ifndef ENABLE_TINY
    } else if (!strcasecmp(input, "flipexecute")) {
	s->scfunc = flip_execute_void;
#endif
1408
#ifndef DISABLE_MULTIBUFFER
1409
1410
    } else if (!strcasecmp(input, "flipnewbuffer") ||
	       !strcasecmp(input, "newbuffer")) {
1411
	s->scfunc = new_buffer_void;
Chris Allegretta's avatar
Chris Allegretta committed
1412
#endif
1413
#ifndef DISABLE_BROWSER
1414
1415
1416
1417
1418
    } else if (!strcasecmp(input, "tofiles") ||
	       !strcasecmp(input, "browser")) {
	s->scfunc = to_files_void;
    } else if (!strcasecmp(input, "gotodir")) {
	s->scfunc = goto_dir_void;
Chris Allegretta's avatar
Chris Allegretta committed
1419
    } else if (!strcasecmp(input, "firstfile")) {
1420
	s->scfunc = do_first_file;
Chris Allegretta's avatar
Chris Allegretta committed
1421
    } else if (!strcasecmp(input, "lastfile")) {
1422
1423
	s->scfunc = do_last_file;
#endif
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
#ifndef NANO_TINY
    } else if (!strcasecmp(input, "nohelp")) {
	s->scfunc = do_toggle_void;
	s->toggle = NO_HELP;
    } else if (!strcasecmp(input, "constupdate")) {
	s->scfunc = do_toggle_void;
	s->toggle = CONST_UPDATE;
    } else if (!strcasecmp(input, "morespace")) {
	s->scfunc = do_toggle_void;
	s->toggle = MORE_SPACE;
    } else if (!strcasecmp(input, "smoothscroll")) {
	s->scfunc = do_toggle_void;
	s->toggle = SMOOTH_SCROLL;
    } else if (!strcasecmp(input, "softwrap")) {
	s->scfunc = do_toggle_void;
	s->toggle = SOFTWRAP;
    } else if (!strcasecmp(input, "whitespacedisplay")) {
	s->scfunc = do_toggle_void;
	s->toggle = WHITESPACE_DISPLAY;
#ifndef DISABLE_COLOR
    } else if (!strcasecmp(input, "nosyntax")) {
	s->scfunc = do_toggle_void;
	s->toggle = NO_COLOR_SYNTAX;
#endif
    } else if (!strcasecmp(input, "smarthome")) {
	s->scfunc = do_toggle_void;
	s->toggle = SMART_HOME;
    } else if (!strcasecmp(input, "autoindent")) {
	s->scfunc = do_toggle_void;
	s->toggle = AUTOINDENT;
    } else if (!strcasecmp(input, "cuttoend")) {
	s->scfunc = do_toggle_void;
	s->toggle = CUT_TO_END;
#ifndef DISABLE_WRAPPING
    } else if (!strcasecmp(input, "nowrap")) {
	s->scfunc = do_toggle_void;
	s->toggle = NO_WRAP;
#endif
    } else if (!strcasecmp(input, "tabstospaces")) {
	s->scfunc = do_toggle_void;
	s->toggle = TABS_TO_SPACES;
    } else if (!strcasecmp(input, "backupfile")) {
	s->scfunc = do_toggle_void;
	s->toggle = BACKUP_FILE;
#ifndef DISABLE_MULTIBUFFER
    } else if (!strcasecmp(input, "multibuffer")) {
	s->scfunc = do_toggle_void;
	s->toggle = MULTIBUFFER;
#endif
#ifndef DISABLE_MOUSE
    } else if (!strcasecmp(input, "mouse")) {
	s->scfunc = do_toggle_void;
	s->toggle = USE_MOUSE;
#endif
    } else if (!strcasecmp(input, "noconvert")) {
	s->scfunc = do_toggle_void;
	s->toggle = NO_CONVERT;
    } else if (!strcasecmp(input, "suspendenable")) {
	s->scfunc = do_toggle_void;
	s->toggle = SUSPEND;
#endif /* !NANO_TINY */
1485
1486
1487
1488
1489
1490
    } else {
	free(s);
	return NULL;
    }
    return s;
}
1491

1492
/* Interpret a menu name and return the corresponding menu flag. */
1493
1494
1495
int strtomenu(char *input)
{
    if (!strcasecmp(input, "all"))
1496
	return (MMOST|MHELP|MYESNO);
1497
1498
1499
1500
1501
1502
1503
    else if (!strcasecmp(input, "main"))
	return MMAIN;
    else if (!strcasecmp(input, "search"))
	return MWHEREIS;
    else if (!strcasecmp(input, "replace"))
	return MREPLACE;
    else if (!strcasecmp(input, "replace2") ||
Benno Schulenberg's avatar
Benno Schulenberg committed
1504
	     !strcasecmp(input, "replacewith"))
1505
	return MREPLACEWITH;
1506
1507
1508
1509
1510
1511
1512
    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
1513
	     !strcasecmp(input, "extcmd"))
1514
	return MEXTCMD;
1515
#ifndef DISABLE_HELP
1516
1517
    else if (!strcasecmp(input, "help"))
	return MHELP;
1518
1519
#endif
#ifndef DISABLE_SPELLER
1520
1521
    else if (!strcasecmp(input, "spell"))
	return MSPELL;
1522
#endif
1523
1524
    else if (!strcasecmp(input, "linter"))
	return MLINTER;
1525
#ifndef DISABLE_BROWSER
1526
1527
1528
1529
1530
1531
    else if (!strcasecmp(input, "browser"))
	return MBROWSER;
    else if (!strcasecmp(input, "whereisfile"))
	return MWHEREISFILE;
    else if (!strcasecmp(input, "gotodir"))
	return MGOTODIR;
1532
#endif
1533
1534
    return -1;
}
1535
#endif /* !DISABLE_NANORC */
1536

Chris Allegretta's avatar
Chris Allegretta committed
1537

1538
1539
1540
#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
1541
1542
 * 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
1543
1544
 * function unless debugging is turned on. */
void thanks_for_all_the_fish(void)
1545
{
1546
1547
1548
1549
    delwin(topwin);
    delwin(edit);
    delwin(bottomwin);

Chris Allegretta's avatar
Chris Allegretta committed
1550
1551
1552
#ifndef DISABLE_JUSTIFY
    if (quotestr != NULL)
	free(quotestr);
1553
1554
#ifdef HAVE_REGEX_H
    regfree(&quotereg);
1555
1556
    if (quoteerr != NULL)
	free(quoteerr);
1557
#endif
Chris Allegretta's avatar
Chris Allegretta committed
1558
#endif
1559
#ifndef NANO_TINY
1560
1561
1562
    if (backup_dir != NULL)
        free(backup_dir);
#endif
Chris Allegretta's avatar
Chris Allegretta committed
1563
#ifndef DISABLE_OPERATINGDIR
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
    if (operating_dir != NULL)
	free(operating_dir);
    if (full_operating_dir != NULL)
	free(full_operating_dir);
#endif
    if (last_search != NULL)
	free(last_search);
    if (last_replace != NULL)
	free(last_replace);
#ifndef DISABLE_SPELLER
    if (alt_speller != NULL)
	free(alt_speller);
1576
#endif
1577
1578
1579
    if (answer != NULL)
	free(answer);
    if (cutbuffer != NULL)
Chris Allegretta's avatar
Chris Allegretta committed
1580
	free_filestruct(cutbuffer);
1581
1582
1583
#ifndef DISABLE_JUSTIFY
    if (jusbuffer != NULL)
	free_filestruct(jusbuffer);
1584
#endif
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
1585
    /* Free the memory associated with each open file buffer. */
1586
    if (openfile != NULL)
1587
	free_openfilestruct(openfile);
1588
#ifndef DISABLE_COLOR
1589
1590
    if (syntaxstr != NULL)
	free(syntaxstr);
Chris Allegretta's avatar
Chris Allegretta committed
1591
1592
1593
1594
1595
    while (syntaxes != NULL) {
	syntaxtype *bill = syntaxes;

	free(syntaxes->desc);
	while (syntaxes->extensions != NULL) {
1596
	    regexlisttype *bob = syntaxes->extensions;
Chris Allegretta's avatar
Chris Allegretta committed
1597
	    syntaxes->extensions = bob->next;
1598
	    free(bob->ext_regex);
1599
1600
1601
1602
	    if (bob->ext != NULL) {
		regfree(bob->ext);
		free(bob->ext);
	    }
Chris Allegretta's avatar
Chris Allegretta committed
1603
1604
	    free(bob);
	}
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
	while (syntaxes->headers != NULL) {
	    regexlisttype *bob = syntaxes->headers;
	    syntaxes->headers = bob->next;
	    free(bob->ext_regex);
	    if (bob->ext != NULL) {
		regfree(bob->ext);
		free(bob->ext);
	    }
	    free(bob);
	}
	while (syntaxes->magics != NULL) {
	    regexlisttype *bob = syntaxes->magics;
	    syntaxes->magics = bob->next;
	    free(bob->ext_regex);
	    if (bob->ext != NULL) {
		regfree(bob->ext);
		free(bob->ext);
	    }
	    free(bob);
	}
Chris Allegretta's avatar
Chris Allegretta committed
1625
1626
1627
1628
	while (syntaxes->color != NULL) {
	    colortype *bob = syntaxes->color;

	    syntaxes->color = bob->next;
1629
	    free(bob->start_regex);
1630
1631
1632
1633
	    if (bob->start != NULL) {
		regfree(bob->start);
		free(bob->start);
	    }
1634
1635
	    if (bob->end_regex != NULL)
		free(bob->end_regex);
1636
	    if (bob->end != NULL) {
1637
		regfree(bob->end);
1638
1639
		free(bob->end);
	    }
Chris Allegretta's avatar
Chris Allegretta committed
1640
1641
1642
1643
1644
	    free(bob);
	}
	syntaxes = syntaxes->next;
	free(bill);
    }
1645
#endif /* !DISABLE_COLOR */
1646
#ifndef DISABLE_HISTORIES
1647
    /* Free the search and replace history lists. */
1648
1649
1650
1651
    if (searchage != NULL)
	free_filestruct(searchage);
    if (replaceage != NULL)
	free_filestruct(replaceage);
1652
#endif
1653
1654
1655
1656
1657
1658
1659
    /* Free the functions and shortcuts lists. */
    while (allfuncs != NULL) {
        subnfunc *f = allfuncs;
        allfuncs = allfuncs->next;
        free(f);
    }
    while (sclist != NULL) {
1660
        sc *s = sclist;
1661
        sclist = sclist->next;
1662
        free(s);
1663
    }
1664
#ifndef DISABLE_NANORC
1665
1666
    if (homedir != NULL)
	free(homedir);
1667
#endif
1668
}
1669

1670
#endif /* DEBUG */