global.c 55.8 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
159
#endif

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

164
165
const shortcut *currshortcut;
	/* The current shortcut list we're using. */
166
int currmenu;
167
	/* The currently loaded menu. */
168
169

sc *sclist = NULL;
170
	/* Pointer to the start of the shortcuts list. */
171
subnfunc *allfuncs = NULL;
172
173
174
	/* Pointer to the start of the functions list. */
subnfunc *tailfunc;
	/* Pointer to the last function in the list. */
175
176
subnfunc *exitfunc;
	/* Pointer to the special Exit/Close item. */
177
178
subnfunc *uncutfunc;
	/* Pointer to the special Uncut/Unjustify item. */
179

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

197
/* Regular expressions. */
198
#ifdef HAVE_REGEX_H
199
200
201
202
203
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
204
#endif
205

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

215
char *homedir = NULL;
216
	/* The user's home directory, from $HOME or /etc/passwd. */
217

218
/* Return the number of entries in the shortcut list for a given menu. */
219
size_t length_of_list(int menu)
220
{
221
    subnfunc *f;
222
    size_t i = 0;
223

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

235
/* Just throw this here. */
236
237
238
239
240
241
void case_sens_void(void)
{
}
void regexp_void(void)
{
}
242
243
244
void backwards_void(void)
{
}
245
246
247
void gototext_void(void)
{
}
248
#ifndef DISABLE_BROWSER
249
250
251
void to_files_void(void)
{
}
252
253
254
255
void goto_dir_void(void)
{
}
#endif
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
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)
{
}
void no_replace_void(void)
{
}
void ext_cmd_void(void)
{
}

281
/* Set type of function based on the string. */
282
function_type strtokeytype(const char *str)
283
{
284
    if (str[0] == '^')
285
        return CONTROL;
286
287
288
    else if (str[0] == 'M')
        return META;
    else if (str[0] == 'F')
289
        return FKEY;
290
    else
291
	return RAWINPUT;
292
293
}

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

    if (allfuncs == NULL)
	allfuncs = f;
    else
	tailfunc->next = f;
    tailfunc = f;
306
307
308
309
310
311

    f->next = NULL;
    f->scfunc = func;
    f->menus = menus;
    f->desc = desc;
    f->viewok = viewok;
312
#ifndef DISABLE_HELP
313
314
315
316
317
    f->help = help;
    f->blank_after = blank_after;
#endif

#ifdef DEBUG
318
    fprintf(stderr, "Added func %ld (%s) for menus %x\n", (long)func, f->desc, menus);
319
#endif
320
321
}

322
323
/* Return the first shortcut in the list of shortcuts that
 * matches the given func in the given menu. */
324
325
const sc *first_sc_for(int menu, void (*func)(void))
{
326
327
    const sc *s;

328
329
330
    for (s = sclist; s != NULL; s = s->next)
	if ((s->menu & menu) && s->scfunc == func)
	    return s;
331

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


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

346
    if (sclist == NULL) {
347
	sclist = (sc *)nmalloc(sizeof(sc));
348
349
	s = sclist;
        s->next = NULL;
350
    } else {
351
352
353
354
355
356
357
358
359
360
361
362
	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;
        }
363
364
    }

365
366
367
    s->type = strtokeytype(scstring);
    s->menu = menu;
    s->toggle = toggle;
368
    s->keystr = (char *) scstring;
369
370
371
372
373
    s->scfunc = func;
    s->execute = execute;
    assign_keyinfo(s);

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

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

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

Chris Allegretta's avatar
Chris Allegretta committed
389
/* Return the given menu's first shortcut sequence, or the default value
390
 * (2nd arg).  Assumes currmenu for the menu to check. */
391
int sc_seq_or (void (*func)(void), int defaultval)
Chris Allegretta's avatar
Chris Allegretta committed
392
393
394
395
396
397
398
399
400
{
    const sc *s = first_sc_for(currmenu, func);

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

401
402
/* Assign the info to the shortcut struct.
 * Assumes keystr is already assigned, naturally. */
403
404
405
406
407
408
409
410
411
412
413
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]);
414
    } else /* RAWINPUT */
415
        s->seq = (int) s->keystr[0];
416

417
    /* Override some keys which don't bind as easily as we'd like. */
418
419
420
421
    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) ' ';
422
    else if (s->type == RAWINPUT) {
423
	if (!strcasecmp(s->keystr, "Up"))
424
	    s->seq = KEY_UP;
425
	else if (!strcasecmp(s->keystr, "Down"))
426
	    s->seq = KEY_DOWN;
427
	else if (!strcasecmp(s->keystr, "Left"))
428
	    s->seq = KEY_LEFT;
429
	else if (!strcasecmp(s->keystr, "Right"))
430
	    s->seq = KEY_RIGHT;
431
	else if (!strcasecmp(s->keystr, "Ins"))
432
	    s->seq = KEY_IC;
433
	else if (!strcasecmp(s->keystr, "Del"))
434
	    s->seq = KEY_DC;
435
	else if (!strcasecmp(s->keystr, "Bsp"))
436
	    s->seq = KEY_BACKSPACE;
437
	else if (!strcasecmp(s->keystr, "Enter"))
438
	    s->seq = KEY_ENTER;
439
	else if (!strcasecmp(s->keystr, "PgUp"))
440
	    s->seq = KEY_PPAGE;
441
	else if (!strcasecmp(s->keystr, "PgDn"))
442
	    s->seq = KEY_NPAGE;
443
#ifdef KEY_HOME
444
	else if (!strcasecmp(s->keystr, "Home"))
445
	    s->seq = KEY_HOME;
446
447
#endif
#ifdef KEY_END
448
	else if (!strcasecmp(s->keystr, "End"))
449
	    s->seq = KEY_END;
450
#endif
451
    }
452
453
454
455
456
457
458
459
}

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

460
    for (s = sclist; s != NULL; s = s->next) {
461
	f = sctofunc(s);
462
	if (f)
463
	    fprintf(stderr, "Shortcut \"%s\", function: %s, menus %x\n", s->keystr, f->desc, f->menus);
464
	else
465
	    fprintf(stderr, "Hmm, didn't find a func for \"%s\"\n", s->keystr);
466
467
468
469
    }
}
#endif

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

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

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

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
639
#ifndef DISABLE_HELP
640
#define IFSCHELP(help) help
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
641
#else
642
#define IFSCHELP(help) ""
643
#endif
644

645
646
    while (allfuncs != NULL) {
        subnfunc *f = allfuncs;
647
        allfuncs = allfuncs->next;
648
649
        free(f);
    }
650

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

653
    add_to_funcs(do_help_void, MMOST,
654
655
	/* 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
656

657
    add_to_funcs(do_cancel, ((MMOST & ~MMAIN & ~MBROWSER) | MYESNO),
658
	N_("Cancel"), IFSCHELP(nano_cancel_msg), FALSE, VIEW);
659

660
    add_to_funcs(do_exit, MMAIN,
661
	exit_tag, IFSCHELP(nano_exit_msg), FALSE, VIEW);
662
663
    /* Remember the entry for Exit, to be able to replace it with Close. */
    exitfunc = tailfunc;
Chris Allegretta's avatar
Chris Allegretta committed
664

665
#ifndef DISABLE_BROWSER
666
667
    add_to_funcs(do_exit, MBROWSER,
	exit_tag, IFSCHELP(nano_exitbrowser_msg), FALSE, VIEW);
668
#endif
Chris Allegretta's avatar
Chris Allegretta committed
669

670
671
    add_to_funcs(do_writeout_void, MMAIN,
	N_("Write Out"), IFSCHELP(nano_writeout_msg), FALSE, NOVIEW);
672

673
    /* We allow inserting files in view mode if multibuffers are
674
675
676
677
     * 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. */
678
679
    add_to_funcs(do_insertfile_void, MMAIN,
	read_file_tag, IFSCHELP(nano_insert_msg), TRUE,
680
#ifndef DISABLE_MULTIBUFFER
681
	VIEW);
682
#else
683
	NOVIEW);
684
#endif
Chris Allegretta's avatar
Chris Allegretta committed
685

686
687
    add_to_funcs(do_search, MMAIN,
	whereis_tag, IFSCHELP(nano_whereis_msg), FALSE, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
688

689
690
    add_to_funcs(do_replace, MMAIN,
	replace_tag, IFSCHELP(nano_replace_msg), FALSE, NOVIEW);
691
692

#ifndef DISABLE_BROWSER
693
694
    add_to_funcs(do_search, MBROWSER,
	whereis_tag, IFSCHELP(nano_browser_whereis_msg), FALSE, VIEW);
695

696
697
    add_to_funcs(goto_dir_void, MBROWSER,
	N_("Go To Dir"), IFSCHELP(nano_gotodir_msg), TRUE, VIEW);
698
699
#endif

700
#ifndef DISABLE_HELP
701
702
    /* The description ("x") and blank_after (0) are irrelevant,
     * because the help viewer does not have a help text. */
703
    add_to_funcs(do_exit, MHELP, exit_tag, "x", 0, VIEW);
704

705
    add_to_funcs(total_refresh, MHELP, refresh_tag, "x", 0, VIEW);
706
707
708

    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);
709
710
#endif

711
712
    add_to_funcs(do_cut_text_void, MMAIN,
	N_("Cut Text"), IFSCHELP(nano_cut_msg), FALSE, NOVIEW);
Chris Allegretta's avatar
Chris Allegretta committed
713

714
715
    add_to_funcs(do_uncut_text, MMAIN,
	uncut_tag, IFSCHELP(nano_uncut_msg), TRUE, NOVIEW);
716
    /* Remember the entry for Uncut, to be able to replace it with Unjustify. */
717
    uncutfunc = tailfunc;
Chris Allegretta's avatar
Chris Allegretta committed
718

719
#ifndef DISABLE_JUSTIFY
720
721
    add_to_funcs(do_justify_void, MMAIN,
	N_("Justify"), IFSCHELP(nano_justify_msg), FALSE, NOVIEW);
Chris Allegretta's avatar
Chris Allegretta committed
722
#endif
Chris Allegretta's avatar
Chris Allegretta committed
723

724
#ifndef DISABLE_SPELLER
725
726
    add_to_funcs(do_spell, MMAIN,
	N_("To Spell"), IFSCHELP(nano_spell_msg), FALSE, NOVIEW);
727
#endif
728

729
#ifndef DISABLE_COLOR
730
731
    add_to_funcs(do_linter, MMAIN,
	N_("To Linter"), IFSCHELP(nano_lint_msg), TRUE, NOVIEW);
732
733
#endif

734
#ifndef NANO_TINY
735
    add_to_funcs(case_sens_void, MWHEREIS|MREPLACE,
736
737
738
739
	N_("Case Sens"), IFSCHELP(nano_case_msg), FALSE, VIEW);
#endif

#ifdef HAVE_REGEX_H
740
    add_to_funcs(regexp_void, MWHEREIS|MREPLACE,
741
742
743
744
	N_("Regexp"), IFSCHELP(nano_regexp_msg), FALSE, VIEW);
#endif

#ifndef NANO_TINY
745
    add_to_funcs(backwards_void, MWHEREIS|MREPLACE,
746
747
748
749
750
751
752
753
754
755
	N_("Backwards"), IFSCHELP(nano_reverse_msg), FALSE, VIEW);
#endif

    add_to_funcs(do_replace, MWHEREIS,
	replace_tag, IFSCHELP(nano_replace_msg), FALSE, VIEW);

    add_to_funcs(no_replace_void, MREPLACE,
	N_("No Replace"), IFSCHELP(nano_whereis_msg), FALSE, VIEW);

#ifndef DISABLE_JUSTIFY
756
757
    add_to_funcs(do_full_justify, MWHEREIS,
	fulljustify_tag, IFSCHELP(nano_fulljustify_msg), FALSE, NOVIEW);
758
759
#endif

760
761
    add_to_funcs(do_cursorpos_void, MMAIN,
	N_("Cur Pos"), IFSCHELP(nano_cursorpos_msg), FALSE, VIEW);
762

763
764
765
#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. */
766
767
    add_to_funcs(do_gotolinecolumn_void, MMAIN|MWHEREIS,
	gotoline_tag, IFSCHELP(nano_gotoline_msg), TRUE, VIEW);
768
#endif
769
770
771
772
773

    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);
774

775
    add_to_funcs(do_first_line, MMAIN|MHELP|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE,
776
	N_("First Line"), IFSCHELP(nano_firstline_msg), FALSE, VIEW);
777
    add_to_funcs(do_last_line, MMAIN|MHELP|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE,
778
	N_("Last Line"), IFSCHELP(nano_lastline_msg), TRUE, VIEW);
779

780
#ifndef NANO_TINY
781
782
    add_to_funcs(do_research, MMAIN,
	whereis_next_tag, IFSCHELP(nano_whereis_next_msg), FALSE, VIEW);
783

784
785
    add_to_funcs(do_find_bracket, MMAIN,
	N_("To Bracket"), IFSCHELP(nano_bracket_msg), FALSE, VIEW);
786

787
788
    add_to_funcs(do_mark, MMAIN,
	N_("Mark Text"), IFSCHELP(nano_mark_msg), FALSE, VIEW);
789

790
791
    add_to_funcs(do_copy_text, MMAIN,
	N_("Copy Text"), IFSCHELP(nano_copy_msg), TRUE, NOVIEW);
792

793
794
795
796
    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);
797

798
    if (ISSET(UNDOABLE)) {
799
800
801
802
	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);
803
    }
804
#endif /* !NANO_TINY */
805

806
807
808
809
    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);
810
811

#ifndef DISABLE_BROWSER
812
813
814
815
    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);
816
817
#endif

818
#ifndef NANO_TINY
819
820
821
822
    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);
823
#endif
824

825
826
827
828
    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);
829

830
831
832
833
    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);
834

835
#ifndef DISABLE_JUSTIFY
836
837
838
839
    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);
840
#endif
841

842
#ifndef NANO_TINY
843
844
845
846
    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);
847
848
#endif

849
#ifndef DISABLE_MULTIBUFFER
850
851
852
853
    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);
854
855
#endif

856
857
858
859
860
#if defined(NANO_TINY) && !defined(DISABLE_COLOR)
    add_to_funcs(do_gotolinecolumn_void, MMAIN|MWHEREIS,
	gotoline_tag, IFSCHELP(nano_gotoline_msg), TRUE, VIEW);
#endif

861
862
    add_to_funcs(do_verbatim_input, MMAIN,
	N_("Verbatim"), IFSCHELP(nano_verbatim_msg), FALSE, NOVIEW);
863

864
865
866
867
868
869
870
871
    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
872
#ifndef NANO_TINY
873
	FALSE,
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
874
#else
875
	TRUE,
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
876
#endif
877
878
	NOVIEW);

879
#ifndef NANO_TINY
880
881
    add_to_funcs(do_cut_till_end, MMAIN,
	N_("CutTillEnd"), IFSCHELP(nano_cut_till_end_msg), TRUE, NOVIEW);
882
#endif
Chris Allegretta's avatar
Chris Allegretta committed
883

884
#ifndef DISABLE_JUSTIFY
885
886
    add_to_funcs(do_full_justify, MMAIN,
	fulljustify_tag, IFSCHELP(nano_fulljustify_msg), FALSE, NOVIEW);
887
888
#endif

889
#ifndef NANO_TINY
890
891
    add_to_funcs(do_wordlinechar_count, MMAIN,
	N_("Word Count"), IFSCHELP(nano_wordcount_msg), FALSE, VIEW);
892
#endif
893

894
895
    add_to_funcs(total_refresh, MMAIN,
	refresh_tag, IFSCHELP(nano_refresh_msg), FALSE, VIEW);
896

897
898
    add_to_funcs(do_suspend_void, MMAIN,
	N_("Suspend"), IFSCHELP(nano_suspend_msg), TRUE, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
899

900
#ifndef NANO_TINY
901
    add_to_funcs(get_history_older_void,
902
	(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE),
903
	N_("PrevHstory"), IFSCHELP(nano_prev_history_msg), FALSE, VIEW);
904

905
    add_to_funcs(get_history_newer_void,
906
	(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE),
907
	N_("NextHstory"), IFSCHELP(nano_next_history_msg), FALSE, VIEW);
908
#endif
909

910
    add_to_funcs(gototext_void, MGOTOLINE,
911
	N_("Go To Text"), IFSCHELP(nano_whereis_msg), TRUE, VIEW);
912

913
#ifndef NANO_TINY
914
915
916
917
918
919
    /* 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. */
920
    if (!ISSET(RESTRICTED)) {
921
        add_to_funcs(dos_format_void, MWRITEFILE,
922
            N_("DOS Format"), IFSCHELP(nano_dos_msg), FALSE, NOVIEW);
923

924
        add_to_funcs(mac_format_void, MWRITEFILE,
925
            N_("Mac Format"), IFSCHELP(nano_mac_msg), FALSE, NOVIEW);
926

Benno Schulenberg's avatar
Benno Schulenberg committed
927
        add_to_funcs(append_void, MWRITEFILE,
928
            N_("Append"), IFSCHELP(nano_append_msg), FALSE, NOVIEW);
Benno Schulenberg's avatar
Benno Schulenberg committed
929
        add_to_funcs(prepend_void, MWRITEFILE,
930
            N_("Prepend"), IFSCHELP(nano_prepend_msg), FALSE, NOVIEW);
931

Benno Schulenberg's avatar
Benno Schulenberg committed
932
        add_to_funcs(backup_file_void, MWRITEFILE,
933
            N_("Backup File"), IFSCHELP(nano_backup_msg), FALSE, NOVIEW);
934
    }
935

936
937
938
    /* If we're using restricted mode, file insertion is disabled, and
     * thus command execution and the multibuffer toggle have no place. */
    if (!ISSET(RESTRICTED)) {
Benno Schulenberg's avatar
Benno Schulenberg committed
939
        add_to_funcs(ext_cmd_void, MINSERTFILE,
940
	    N_("Execute Command"), IFSCHELP(nano_execute_msg), FALSE, NOVIEW);
941

942
943
944
        add_to_funcs(ext_cmd_void, MEXTCMD,
	    read_file_tag, IFSCHELP(nano_insert_msg), FALSE, NOVIEW);

945
#ifndef DISABLE_MULTIBUFFER
946
	add_to_funcs(new_buffer_void, MINSERTFILE|MEXTCMD,
947
	    N_("New Buffer"), IFSCHELP(nano_multibuffer_msg), FALSE, NOVIEW);
948
#endif
949
    }
950
#endif /* !NANO_TINY */
951

952
#ifndef DISABLE_BROWSER
953
954
955
956
    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
957
    add_to_funcs(do_first_file, (MBROWSER|MWHEREISFILE),
958
	N_("First File"), IFSCHELP(nano_firstfile_msg), FALSE, VIEW);
Benno Schulenberg's avatar
Benno Schulenberg committed
959
    add_to_funcs(do_last_file, (MBROWSER|MWHEREISFILE),
960
	N_("Last File"), IFSCHELP(nano_lastfile_msg), FALSE, VIEW);
961
#endif
Chris Allegretta's avatar
Chris Allegretta committed
962

963
#if !defined(NANO_TINY) && !defined(DISABLE_BROWSER)
964
965
    add_to_funcs(do_research, MBROWSER,
	whereis_next_tag, IFSCHELP(nano_whereis_next_msg), FALSE, VIEW);
966
967
968
#endif

#ifndef DISABLE_COLOR
969
    /* TRANSLATORS: Try to keep the next two strings at most 20 characters. */
970
    add_to_funcs(do_page_up, MLINTER,
971
	N_("Prev Lint Msg"), IFSCHELP(nano_prevlint_msg), FALSE, VIEW);
972
    add_to_funcs(do_page_down, MLINTER,
973
	N_("Next Lint Msg"), IFSCHELP(nano_nextlint_msg), FALSE, VIEW);
974
975
#endif

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

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

1085
#ifndef NANO_TINY
1086
    /* Group of "Appearance" toggles. */
1087
1088
1089
1090
    add_to_sclist(MMAIN, "M-X", do_toggle_void, NO_HELP, TRUE);
    add_to_sclist(MMAIN, "M-C", do_toggle_void, CONST_UPDATE, TRUE);
    add_to_sclist(MMAIN, "M-O", do_toggle_void, MORE_SPACE, TRUE);
    add_to_sclist(MMAIN, "M-S", do_toggle_void, SMOOTH_SCROLL, TRUE);
1091
    add_to_sclist(MMAIN, "M-$", do_toggle_void, SOFTWRAP, TRUE);
1092
    add_to_sclist(MMAIN, "M-P", do_toggle_void, WHITESPACE_DISPLAY, TRUE);
1093
#ifndef DISABLE_COLOR
1094
    add_to_sclist(MMAIN, "M-Y", do_toggle_void, NO_COLOR_SYNTAX, TRUE);
1095
#endif
1096

1097
    /* Group of "Editing-behavior" toggles. */
1098
1099
1100
    add_to_sclist(MMAIN, "M-H", do_toggle_void, SMART_HOME, TRUE);
    add_to_sclist(MMAIN, "M-I", do_toggle_void, AUTOINDENT, TRUE);
    add_to_sclist(MMAIN, "M-K", do_toggle_void, CUT_TO_END, TRUE);
1101
#ifndef DISABLE_WRAPPING
1102
    add_to_sclist(MMAIN, "M-L", do_toggle_void, NO_WRAP, TRUE);
1103
#endif
1104
    add_to_sclist(MMAIN, "M-Q", do_toggle_void, TABS_TO_SPACES, TRUE);
1105

1106
    /* Group of "Peripheral-feature" toggles. */
1107
    add_to_sclist(MMAIN, "M-B", do_toggle_void, BACKUP_FILE, TRUE);
1108
#ifndef DISABLE_MULTIBUFFER
1109
    add_to_sclist(MMAIN, "M-F", do_toggle_void, MULTIBUFFER, TRUE);
1110
1111
#endif
#ifndef DISABLE_MOUSE
1112
    add_to_sclist(MMAIN, "M-M", do_toggle_void, USE_MOUSE, TRUE);
1113
#endif
1114
1115
    add_to_sclist(MMAIN, "M-N", do_toggle_void, NO_CONVERT, TRUE);
    add_to_sclist(MMAIN, "M-Z", do_toggle_void, SUSPEND, TRUE);
1116
#endif /* !NANO_TINY */
Benno Schulenberg's avatar
Benno Schulenberg committed
1117

1118
1119
1120
    add_to_sclist(MMAIN, "^Q", xon_complaint, 0, TRUE);
    add_to_sclist(MMAIN, "^S", xoff_complaint, 0, TRUE);

1121
    add_to_sclist(((MMOST & ~MMAIN & ~MBROWSER) | MYESNO), "^C", do_cancel, 0, FALSE);
1122

1123
1124
#ifndef NANO_TINY
    add_to_sclist(MWHEREIS|MREPLACE, "M-B", backwards_void, 0, FALSE);
1125
    add_to_sclist(MWHEREIS|MREPLACE, "M-C", case_sens_void, 0, FALSE);
1126
#endif
1127
    add_to_sclist(MWHEREIS|MREPLACE, "M-R", regexp_void, 0, FALSE);
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
    add_to_sclist(MWHEREIS, "^R", do_replace, 0, FALSE);
    add_to_sclist(MREPLACE, "^R", no_replace_void, 0, FALSE);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE, "^Y", do_first_line, 0, TRUE);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE, "^V", do_last_line, 0, TRUE);
#ifndef DISABLE_JUSTIFY
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^W", do_para_begin_void, 0, TRUE);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^O", do_para_end_void, 0, TRUE);
#endif
    add_to_sclist(MWHEREIS, "^T", do_gotolinecolumn_void, 0, FALSE);
    add_to_sclist(MGOTOLINE, "^T", gototext_void, 0, FALSE);
#ifndef NANO_TINY
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "^P", get_history_older_void, 0, FALSE);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "Up", get_history_older_void, 0, FALSE);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "^N", get_history_newer_void, 0, FALSE);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "Down", get_history_newer_void, 0, FALSE);
#endif
#ifndef DISABLE_BROWSER
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-\\", do_first_file, 0, TRUE);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-|", do_first_file, 0, TRUE);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-/", do_last_file, 0, TRUE);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-?", do_last_file, 0, TRUE);
    add_to_sclist(MBROWSER|MWHEREISFILE, "^_", goto_dir_void, 0, TRUE);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-G", goto_dir_void, 0, TRUE);
    add_to_sclist(MBROWSER|MWHEREISFILE, "F13", goto_dir_void, 0, TRUE);
#endif
1153
1154
1155
1156
1157
    add_to_sclist(MWRITEFILE, "M-D", dos_format_void, 0, FALSE);
    add_to_sclist(MWRITEFILE, "M-M", mac_format_void, 0, FALSE);
    add_to_sclist(MWRITEFILE, "M-A", append_void, 0, FALSE);
    add_to_sclist(MWRITEFILE, "M-P", prepend_void, 0, FALSE);
    add_to_sclist(MWRITEFILE, "M-B", backup_file_void, 0, FALSE);
1158
#ifndef DISABLE_BROWSER
Benno Schulenberg's avatar
Benno Schulenberg committed
1159
    add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", to_files_void, 0, FALSE);
1160
#endif
1161
    add_to_sclist(MINSERTFILE|MEXTCMD, "^X", ext_cmd_void, 0, FALSE);
1162
    add_to_sclist(MINSERTFILE|MEXTCMD, "M-F", new_buffer_void, 0, FALSE);
1163
    add_to_sclist(MHELP|MBROWSER, "^C", do_exit, 0, TRUE);
1164
#ifndef DISABLE_HELP
1165
    add_to_sclist(MHELP, "^G", do_exit, 0, TRUE);
1166
#endif
1167
1168
    add_to_sclist(MMOST, "^I", do_tab, 0, TRUE);
    add_to_sclist(MMOST, "^M", do_enter_void, 0, TRUE);
1169
    add_to_sclist(MMOST, "Enter", do_enter_void, 0, TRUE);
1170
    add_to_sclist(MMOST, "^D", do_delete, 0, TRUE);
1171
    add_to_sclist(MMOST, "Del", do_delete, 0, TRUE);
1172
    add_to_sclist(MMOST, "^H", do_backspace, 0, TRUE);
1173
    add_to_sclist(MMOST, "Bsp", do_backspace, 0, TRUE);
Chris Allegretta's avatar
Chris Allegretta committed
1174

1175
1176
#ifdef DEBUG
    print_sclist();
Chris Allegretta's avatar
Chris Allegretta committed
1177
#endif
1178
}
1179

1180
#ifndef DISABLE_COLOR
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
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

1196
const subnfunc *sctofunc(sc *s)
1197
{
1198
    subnfunc *f;
1199

1200
1201
    for (f = allfuncs; f != NULL && s->scfunc != f->scfunc; f = f->next)
	;
1202

1203
    return f;
1204
1205
}

1206
#ifndef NANO_TINY
1207
1208
/* Now let's come up with a single (hopefully) function to get a string
 * for each flag. */
1209
const char *flagtostr(int flag)
1210
{
1211
1212
   switch (flag) {
        case NO_HELP:
1213
1214
            /* TRANSLATORS: The next seventeen strings are toggle descriptions;
             * they are best kept shorter than 40 characters, but may be longer. */
1215
1216
1217
1218
1219
1220
1221
            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");
1222
1223
        case SOFTWRAP:
            return N_("Soft wrapping of overlong lines");
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
        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:
1235
            return N_("Hard wrapping of overlong lines");
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
        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 "?????";
    }
}
1252
#endif /* !NANO_TINY */
1253

1254
#ifndef DISABLE_NANORC
1255
1256
1257
/* Interpret a function string given in the rc file, and return a
 * shortcut struct, complete with the proper value for execute. */
sc *strtosc(char *input)
1258
{
1259
    sc *s;
1260
1261

    s = (sc *)nmalloc(sizeof(sc));
1262
    s->execute = TRUE; /* will be overridden as needed below */
1263

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

1529
/* Interpret a menu name and return the corresponding menu flag. */
1530
1531
1532
int strtomenu(char *input)
{
    if (!strcasecmp(input, "all"))
1533
	return (MMOST|MHELP|MYESNO);
1534
1535
1536
1537
1538
1539
1540
    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
1541
	     !strcasecmp(input, "replacewith"))
1542
	return MREPLACEWITH;
1543
1544
1545
1546
1547
1548
1549
    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
1550
	     !strcasecmp(input, "extcmd"))
1551
	return MEXTCMD;
1552
#ifndef DISABLE_HELP
1553
1554
    else if (!strcasecmp(input, "help"))
	return MHELP;
1555
1556
#endif
#ifndef DISABLE_SPELLER
1557
1558
    else if (!strcasecmp(input, "spell"))
	return MSPELL;
1559
#endif
1560
1561
    else if (!strcasecmp(input, "linter"))
	return MLINTER;
1562
#ifndef DISABLE_BROWSER
1563
1564
1565
1566
1567
1568
    else if (!strcasecmp(input, "browser"))
	return MBROWSER;
    else if (!strcasecmp(input, "whereisfile"))
	return MWHEREISFILE;
    else if (!strcasecmp(input, "gotodir"))
	return MGOTODIR;
1569
#endif
1570
1571
    return -1;
}
1572
#endif /* !DISABLE_NANORC */
1573

Chris Allegretta's avatar
Chris Allegretta committed
1574

1575
1576
1577
#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
1578
1579
 * 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
1580
1581
 * function unless debugging is turned on. */
void thanks_for_all_the_fish(void)
1582
{
1583
1584
1585
1586
    delwin(topwin);
    delwin(edit);
    delwin(bottomwin);

Chris Allegretta's avatar
Chris Allegretta committed
1587
1588
1589
#ifndef DISABLE_JUSTIFY
    if (quotestr != NULL)
	free(quotestr);
1590
1591
#ifdef HAVE_REGEX_H
    regfree(&quotereg);
1592
1593
    if (quoteerr != NULL)
	free(quoteerr);
1594
#endif
Chris Allegretta's avatar
Chris Allegretta committed
1595
#endif
1596
#ifndef NANO_TINY
1597
1598
1599
    if (backup_dir != NULL)
        free(backup_dir);
#endif
Chris Allegretta's avatar
Chris Allegretta committed
1600
#ifndef DISABLE_OPERATINGDIR
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
    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);
1613
#endif
1614
1615
1616
    if (answer != NULL)
	free(answer);
    if (cutbuffer != NULL)
Chris Allegretta's avatar
Chris Allegretta committed
1617
	free_filestruct(cutbuffer);
1618
1619
1620
#ifndef DISABLE_JUSTIFY
    if (jusbuffer != NULL)
	free_filestruct(jusbuffer);
1621
#endif
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
1622
    /* Free the memory associated with each open file buffer. */
1623
    if (openfile != NULL)
1624
	free_openfilestruct(openfile);
1625
#ifndef DISABLE_COLOR
1626
1627
    if (syntaxstr != NULL)
	free(syntaxstr);
Chris Allegretta's avatar
Chris Allegretta committed
1628
1629
1630
1631
1632
    while (syntaxes != NULL) {
	syntaxtype *bill = syntaxes;

	free(syntaxes->desc);
	while (syntaxes->extensions != NULL) {
1633
	    regexlisttype *bob = syntaxes->extensions;
Chris Allegretta's avatar
Chris Allegretta committed
1634
	    syntaxes->extensions = bob->next;
1635
	    free(bob->ext_regex);
1636
1637
1638
1639
	    if (bob->ext != NULL) {
		regfree(bob->ext);
		free(bob->ext);
	    }
Chris Allegretta's avatar
Chris Allegretta committed
1640
1641
	    free(bob);
	}
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
	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
1662
1663
1664
1665
	while (syntaxes->color != NULL) {
	    colortype *bob = syntaxes->color;

	    syntaxes->color = bob->next;
1666
	    free(bob->start_regex);
1667
1668
1669
1670
	    if (bob->start != NULL) {
		regfree(bob->start);
		free(bob->start);
	    }
1671
1672
	    if (bob->end_regex != NULL)
		free(bob->end_regex);
1673
	    if (bob->end != NULL) {
1674
		regfree(bob->end);
1675
1676
		free(bob->end);
	    }
Chris Allegretta's avatar
Chris Allegretta committed
1677
1678
1679
1680
1681
	    free(bob);
	}
	syntaxes = syntaxes->next;
	free(bill);
    }
1682
#endif /* !DISABLE_COLOR */
1683
#ifndef NANO_TINY
1684
    /* Free the search and replace history lists. */
1685
1686
1687
1688
    if (searchage != NULL)
	free_filestruct(searchage);
    if (replaceage != NULL)
	free_filestruct(replaceage);
1689
#endif
1690
1691
1692
1693
1694
1695
1696
    /* Free the functions and shortcuts lists. */
    while (allfuncs != NULL) {
        subnfunc *f = allfuncs;
        allfuncs = allfuncs->next;
        free(f);
    }
    while (sclist != NULL) {
1697
        sc *s = sclist;
1698
        sclist = sclist->next;
1699
        free(s);
1700
    }
1701
#ifndef DISABLE_NANORC
1702
1703
    if (homedir != NULL)
	free(homedir);
1704
#endif
1705
}
1706

1707
#endif /* DEBUG */