global.c 53.5 KB
Newer Older
1
/* $Id$ */
Chris Allegretta's avatar
Chris Allegretta committed
2
3
4
/**************************************************************************
 *   global.c                                                             *
 *                                                                        *
5
6
 *   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,  *
 *   2008, 2009 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
121
122
bool nodelay_mode = FALSE;
	/* Are we in nodelay mode (checking for a cancel wile doing something */

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 = 0;
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
207
int reverse_attr = A_REVERSE;
	/* The curses attribute we use for reverse video. */
208

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

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

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

229
/* Just throw this here. */
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
void case_sens_void(void)
{
}
void regexp_void(void)
{
}
void gototext_void(void)
{
}
void to_files_void(void)
{
}
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 backwards_void(void)
{
}
void goto_dir_void(void)
{
}
void no_replace_void(void)
{
}
void ext_cmd_void(void)
{
}

273
/* Set type of function based on the string. */
274
function_type strtokeytype(const char *str)
275
{
276
    if (str[0] == '^')
277
        return CONTROL;
278
279
280
    else if (str[0] == 'M')
        return META;
    else if (str[0] == 'F')
281
        return FKEY;
282
    else
283
	return RAWINPUT;
284
285
}

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

    if (allfuncs == NULL)
	allfuncs = f;
    else
	tailfunc->next = f;
    tailfunc = f;
298
299
300
301
302
303

    f->next = NULL;
    f->scfunc = func;
    f->menus = menus;
    f->desc = desc;
    f->viewok = viewok;
304
#ifndef DISABLE_HELP
305
306
307
308
309
    f->help = help;
    f->blank_after = blank_after;
#endif

#ifdef DEBUG
310
    fprintf(stderr, "Added func %ld (%s) for menus %x\n", (long)func, f->desc, menus);
311
#endif
312
313
}

314
315
/* Return the first shortcut in the list of shortcuts that
 * matches the given func in the given menu. */
316
317
const sc *first_sc_for(int menu, void (*func)(void))
{
318
319
    const sc *s;

320
321
322
    for (s = sclist; s != NULL; s = s->next)
	if ((s->menu & menu) && s->scfunc == func)
	    return s;
323

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


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

338
    if (sclist == NULL) {
339
	sclist = (sc *) nmalloc(sizeof(sc));
340
341
	s = sclist;
        s->next = NULL;
342
    } else {
343
344
345
346
347
348
349
350
351
352
353
354
	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;
        }
355
356
    }

357
358
359
    s->type = strtokeytype(scstring);
    s->menu = menu;
    s->toggle = toggle;
360
    s->keystr = (char *) scstring;
361
362
363
364
365
    s->scfunc = func;
    s->execute = execute;
    assign_keyinfo(s);

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

370
/* Assign one menu's shortcuts to another function. */
371
372
373
374
375
376
377
378
379
380
381
382
383
void replace_scs_for(void (*oldfunc)(void), void (*newfunc)(void))
{
    sc *s;

    if (sclist == NULL)
	return;

    for (s = sclist; s->next != NULL; s = s->next)
	if (s->scfunc == oldfunc) {
	    s->scfunc = newfunc;
	}
}

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

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

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

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

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

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

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

477
478
/* Initialize the list of functions and the list of shortcuts. */
void shortcut_init(void)
479
{
480
    /* TRANSLATORS: Try to keep the next six strings at most 10 characters. */
481
    const char *whereis_tag = N_("Where Is");
482
483
    const char *prev_line_tag = N_("Prev Line");
    const char *next_line_tag = N_("Next Line");
484
    const char *refresh_tag = N_("Refresh");
485
#ifndef DISABLE_SPELLER
486
    const char *spell_tag = N_("To Spell");
487
#endif
488
#ifndef DISABLE_COLOR
489
    const char *lint_tag = N_("To Linter");
490
    /* TRANSLATORS: Try to keep the next two strings at most 14 characters. */
491
492
    const char *prev_lint_tag = N_("Prev Lint Msg");
    const char *next_lint_tag = N_("Next Lint Msg");
493
#endif
494

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

David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
650
#ifndef DISABLE_HELP
651
#define IFSCHELP(help) help
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
652
#else
653
#define IFSCHELP(help) ""
654
#endif
655

656
657
658
659
660
    while (allfuncs != NULL) {
        subnfunc *f = allfuncs;
        allfuncs = (allfuncs)->next;
        free(f);
    }
661

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

664
    add_to_funcs(do_help_void, MMOST,
665
666
	/* 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
667

668
    add_to_funcs(do_cancel, ((MMOST & ~MMAIN & ~MBROWSER) | MYESNO),
669
	N_("Cancel"), IFSCHELP(nano_cancel_msg), FALSE, VIEW);
670

671
    add_to_funcs(do_exit, MMAIN,
672
	exit_tag, IFSCHELP(nano_exit_msg), FALSE, VIEW);
673
674
    /* Remember the entry for Exit, to be able to replace it with Close. */
    exitfunc = tailfunc;
Chris Allegretta's avatar
Chris Allegretta committed
675

676
#ifndef DISABLE_BROWSER
677
    add_to_funcs(do_exit, MBROWSER, exit_tag, IFSCHELP(nano_exitbrowser_msg), FALSE, VIEW);
678
#endif
Chris Allegretta's avatar
Chris Allegretta committed
679

680
    add_to_funcs(do_writeout_void, MMAIN, N_("Write Out"),
681
	IFSCHELP(nano_writeout_msg), FALSE, NOVIEW);
682

683
    /* We allow inserting files in view mode if multibuffers are
684
685
686
687
     * 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. */
688
    add_to_funcs(do_insertfile_void,
689
	MMAIN, N_("Read File"), IFSCHELP(nano_insert_msg), FALSE,
690
#ifndef DISABLE_MULTIBUFFER
691
	VIEW);
692
#else
693
	NOVIEW);
694
#endif
Chris Allegretta's avatar
Chris Allegretta committed
695

696
    add_to_funcs(do_search, MMAIN, whereis_tag,
697
	IFSCHELP(nano_whereis_msg), FALSE, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
698

699
    add_to_funcs(do_search, MBROWSER, whereis_tag,
700
701
	IFSCHELP(nano_browser_whereis_msg), FALSE, VIEW);

702
#ifndef NANO_TINY
703
    add_to_funcs(do_research, MBROWSER, whereis_next_tag,
704
	IFSCHELP(nano_whereis_next_msg), TRUE, VIEW);
705
#endif
706
707
708
709
710
711

#ifndef DISABLE_JUSTIFY
    add_to_funcs(do_justify_void, MMAIN, N_("Justify"),
	nano_justify_msg, TRUE, NOVIEW);
#endif

712
#ifndef DISABLE_HELP
713
714
    /* The description ("x") and blank_after (0) are irrelevant,
     * because the help viewer does not have a help text. */
715
    add_to_funcs(do_exit, MHELP, exit_tag, "x", 0, VIEW);
716

717
    add_to_funcs(total_refresh, MHELP, refresh_tag, "x", 0, VIEW);
718
719
720

    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);
721
722
#endif

723
    add_to_funcs(do_page_up, MMAIN|MHELP|MBROWSER,
724
	N_("Prev Page"), IFSCHELP(nano_prevpage_msg), FALSE, VIEW);
725
    add_to_funcs(do_page_down, MMAIN|MHELP|MBROWSER,
726
	N_("Next Page"), IFSCHELP(nano_nextpage_msg), TRUE, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
727

728
#ifndef DISABLE_COLOR
729
    add_to_funcs(do_page_up, MLINTER,
730
	prev_lint_tag, IFSCHELP(nano_prevlint_msg), FALSE, VIEW);
731
    add_to_funcs(do_page_down, MLINTER,
732
	next_lint_tag, IFSCHELP(nano_nextlint_msg), FALSE, VIEW);
733
#endif
734

735
    add_to_funcs(do_cut_text_void, MMAIN, N_("Cut Text"), IFSCHELP(nano_cut_msg),
736
	FALSE, NOVIEW);
Chris Allegretta's avatar
Chris Allegretta committed
737

738
739
740
    add_to_funcs(do_uncut_text, MMAIN, uncut_tag, IFSCHELP(nano_uncut_msg),
	FALSE, NOVIEW);
    /* Remember the entry for Uncut, to be able to replace it with Unjustify. */
741
    uncutfunc = tailfunc;
Chris Allegretta's avatar
Chris Allegretta committed
742

Chris Allegretta's avatar
Chris Allegretta committed
743
#ifndef NANO_TINY
744
    add_to_funcs(do_cursorpos_void, MMAIN, N_("Cur Pos"), IFSCHELP(nano_cursorpos_msg),
745
	FALSE, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
746
#endif
Chris Allegretta's avatar
Chris Allegretta committed
747

748
749
750
    /* If we're using restricted mode, spell checking is disabled
     * because it allows reading from or writing to files not specified
     * on the command line. */
751
#ifndef DISABLE_SPELLER
752
    add_to_funcs(do_spell, MMAIN, spell_tag, IFSCHELP(nano_spell_msg),
753
	TRUE, NOVIEW);
754
#endif
755

756
#ifndef DISABLE_COLOR
757
    add_to_funcs(do_linter, MMAIN, lint_tag, IFSCHELP(nano_lint_msg),
758
759
760
	TRUE, NOVIEW);
#endif

761
    add_to_funcs(do_first_line,
762
	(MMAIN|MHELP|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE),
763
	N_("First Line"), IFSCHELP(nano_firstline_msg), FALSE, VIEW);
764
    add_to_funcs(do_last_line,
765
	(MMAIN|MHELP|MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE),
766
	N_("Last Line"), IFSCHELP(nano_lastline_msg), TRUE, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
767

768
    add_to_funcs(do_gotolinecolumn_void, (MMAIN|MWHEREIS),
769
	N_("Go To Line"), IFSCHELP(nano_gotoline_msg), FALSE, VIEW);
770

Chris Allegretta's avatar
Chris Allegretta committed
771
#ifdef NANO_TINY
772
    add_to_funcs(do_cursorpos_void, MMAIN, N_("Cur Pos"), IFSCHELP(nano_cursorpos_msg),
Chris Allegretta's avatar
Chris Allegretta committed
773
774
775
	FALSE, VIEW);
#endif

776
    add_to_funcs(do_replace, (MMAIN|MWHEREIS), N_("Replace"), IFSCHELP(nano_replace_msg),
777
778
779
780
#ifndef NANO_TINY
	FALSE,
#else
	TRUE,
781
#endif
782
	NOVIEW);
783

784
#ifndef NANO_TINY
785
    add_to_funcs(do_mark, MMAIN, N_("Mark Text"),
786
	IFSCHELP(nano_mark_msg), FALSE, VIEW);
787

788
    add_to_funcs(do_research, MMAIN, whereis_next_tag,
789
	IFSCHELP(nano_whereis_next_msg), TRUE, VIEW);
790

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

794
    add_to_funcs(do_indent_void, MMAIN, N_("Indent Text"),
795
	IFSCHELP(nano_indent_msg), FALSE, NOVIEW);
796
    add_to_funcs(do_unindent, MMAIN, N_("Unindent Text"),
797
	IFSCHELP(nano_unindent_msg), FALSE, NOVIEW);
798

799
    if (ISSET(UNDOABLE)) {
800
	add_to_funcs(do_undo, MMAIN, N_("Undo"),
801
	    IFSCHELP(nano_undo_msg), FALSE, NOVIEW);
802
	add_to_funcs(do_redo, MMAIN, N_("Redo"),
803
804
	    IFSCHELP(nano_redo_msg), TRUE, NOVIEW);
    }
805
#endif /* !NANO_TINY */
806

807
    add_to_funcs(do_left, MMAIN, N_("Back"), IFSCHELP(nano_back_msg),
808
	FALSE, VIEW);
809
810
    add_to_funcs(do_right, MMAIN, N_("Forward"), IFSCHELP(nano_forward_msg),
	FALSE, VIEW);
811
812

#ifndef DISABLE_BROWSER
813
    add_to_funcs(do_left, MBROWSER, N_("Back"), IFSCHELP(nano_backfile_msg),
814
	FALSE, VIEW);
815
816
    add_to_funcs(do_right, MBROWSER, N_("Forward"), IFSCHELP(nano_forwardfile_msg),
	FALSE, VIEW);
817
818
#endif

819
#ifndef NANO_TINY
820
    add_to_funcs(do_prev_word_void, MMAIN, N_("Prev Word"),
821
	IFSCHELP(nano_prevword_msg), FALSE, VIEW);
822
823
    add_to_funcs(do_next_word_void, MMAIN, N_("Next Word"),
	IFSCHELP(nano_nextword_msg), FALSE, VIEW);
824
#endif
825

826
    add_to_funcs(do_up_void, (MMAIN|MBROWSER), prev_line_tag,
827
	IFSCHELP(nano_prevline_msg), FALSE, VIEW);
828
    add_to_funcs(do_down_void, (MMAIN|MBROWSER), next_line_tag,
829
	IFSCHELP(nano_nextline_msg), TRUE, VIEW);
830

831
    add_to_funcs(do_home, MMAIN, N_("Home"), IFSCHELP(nano_home_msg),
832
	FALSE, VIEW);
833
    add_to_funcs(do_end, MMAIN, N_("End"), IFSCHELP(nano_end_msg),
834
835
836
837
838
839
#ifndef NANO_TINY
	FALSE,
#else
	TRUE,
#endif
	VIEW);
840

841
#ifndef DISABLE_JUSTIFY
842
    add_to_funcs(do_para_begin_void, (MMAIN|MWHEREIS), N_("Beg of Par"),
843
	IFSCHELP(nano_parabegin_msg), FALSE, VIEW);
844
    add_to_funcs(do_para_end_void, (MMAIN|MWHEREIS), N_("End of Par"),
845
	IFSCHELP(nano_paraend_msg), FALSE, VIEW);
846
#endif
847

848
#ifndef NANO_TINY
849
    add_to_funcs(do_find_bracket, MMAIN, N_("To Bracket"),
850
	IFSCHELP(nano_bracket_msg), FALSE, VIEW);
851

852
    add_to_funcs(do_scroll_up, MMAIN, N_("Scroll Up"),
853
	IFSCHELP(nano_scrollup_msg), FALSE, VIEW);
854
    add_to_funcs(do_scroll_down, MMAIN, N_("Scroll Down"),
855
	IFSCHELP(nano_scrolldown_msg), FALSE, VIEW);
856
857
#endif

858
#ifndef DISABLE_MULTIBUFFER
859
    add_to_funcs(switch_to_prev_buffer_void, MMAIN, N_("Prev File"),
860
	IFSCHELP(nano_prevfile_msg), FALSE, VIEW);
861
    add_to_funcs(switch_to_next_buffer_void, MMAIN, N_("Next File"),
862
	IFSCHELP(nano_nextfile_msg), TRUE, VIEW);
863
864
#endif

865
    add_to_funcs(do_verbatim_input, MMAIN, N_("Verbatim"),
866
	IFSCHELP(nano_verbatim_msg), FALSE, NOVIEW);
867

868
    add_to_funcs(do_tab, MMAIN, N_("Tab"), IFSCHELP(nano_tab_msg),
869
	FALSE, NOVIEW);
870
    add_to_funcs(do_enter_void, MMAIN, N_("Enter"), IFSCHELP(nano_enter_msg),
871
	FALSE, NOVIEW);
872
    add_to_funcs(do_delete, MMAIN, N_("Delete"), IFSCHELP(nano_delete_msg),
873
	FALSE, NOVIEW);
874
    add_to_funcs(do_backspace, MMAIN, N_("Backspace"), IFSCHELP(nano_backspace_msg),
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
875
#ifndef NANO_TINY
876
	FALSE,
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
877
#else
878
	TRUE,
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
879
#endif
880
881
	NOVIEW);

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

887
#ifndef DISABLE_JUSTIFY
888
    add_to_funcs(do_full_justify, (MMAIN|MWHEREIS), N_("FullJstify"),
889
	IFSCHELP(nano_fulljustify_msg), FALSE, NOVIEW);
890
891
#endif

892
#ifndef NANO_TINY
893
    add_to_funcs(do_wordlinechar_count, MMAIN, N_("Word Count"),
894
	IFSCHELP(nano_wordcount_msg), FALSE, VIEW);
895
#endif
896

897
    add_to_funcs(total_refresh, MMAIN, refresh_tag,
898
899
	IFSCHELP(nano_refresh_msg), FALSE, VIEW);

900
    add_to_funcs(do_suspend_void, MMAIN, N_("Suspend"),
901
	IFSCHELP(nano_suspend_msg), TRUE, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
902

903
#ifndef NANO_TINY
Benno Schulenberg's avatar
Benno Schulenberg committed
904
    add_to_funcs(case_sens_void, (MWHEREIS|MREPLACE|MWHEREISFILE),
905
	N_("Case Sens"), IFSCHELP(nano_case_msg), FALSE, VIEW);
906

Benno Schulenberg's avatar
Benno Schulenberg committed
907
    add_to_funcs(backwards_void, (MWHEREIS|MREPLACE|MWHEREISFILE),
908
	N_("Backwards"), IFSCHELP(nano_reverse_msg), FALSE, VIEW);
909
#endif
910

911
#ifdef HAVE_REGEX_H
Benno Schulenberg's avatar
Benno Schulenberg committed
912
    add_to_funcs(regexp_void, (MWHEREIS|MREPLACE|MWHEREISFILE),
913
	N_("Regexp"), IFSCHELP(nano_regexp_msg), FALSE, VIEW);
914
#endif
915

916
#ifndef NANO_TINY
917
    add_to_funcs(get_history_older_void,
918
	(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE),
919
	N_("PrevHstory"), IFSCHELP(nano_prev_history_msg), FALSE, VIEW);
920

921
    add_to_funcs(get_history_newer_void,
922
	(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE),
923
	N_("NextHstory"), IFSCHELP(nano_next_history_msg), FALSE, VIEW);
924
#endif
925

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

929
    add_to_funcs(gototext_void, MGOTOLINE,
930
	N_("Go To Text"), IFSCHELP(nano_whereis_msg), TRUE, VIEW);
931

932
#ifndef DISABLE_BROWSER
933
    if (!ISSET(RESTRICTED))
934
	add_to_funcs(to_files_void, MINSERTFILE,
935
	    N_("To Files"), IFSCHELP(nano_tofiles_msg), FALSE, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
936
#endif
Chris Allegretta's avatar
Chris Allegretta committed
937

938
#ifndef NANO_TINY
939
940
941
942
943
944
    /* 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. */
945
    if (!ISSET(RESTRICTED)) {
946
        add_to_funcs(dos_format_void, MWRITEFILE,
947
            N_("DOS Format"), IFSCHELP(nano_dos_msg), FALSE, NOVIEW);
948

949
        add_to_funcs(mac_format_void, MWRITEFILE,
950
            N_("Mac Format"), IFSCHELP(nano_mac_msg), FALSE, NOVIEW);
951

Benno Schulenberg's avatar
Benno Schulenberg committed
952
        add_to_funcs(append_void, MWRITEFILE,
953
            N_("Append"), IFSCHELP(nano_append_msg), FALSE, NOVIEW);
Benno Schulenberg's avatar
Benno Schulenberg committed
954
        add_to_funcs(prepend_void, MWRITEFILE,
955
            N_("Prepend"), IFSCHELP(nano_prepend_msg), FALSE, NOVIEW);
956

Benno Schulenberg's avatar
Benno Schulenberg committed
957
        add_to_funcs(backup_file_void, MWRITEFILE,
958
            N_("Backup File"), IFSCHELP(nano_backup_msg), FALSE, NOVIEW);
959
    }
960

961
962
963
    /* 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
964
        add_to_funcs(ext_cmd_void, MINSERTFILE,
965
	    N_("Execute Command"), IFSCHELP(nano_execute_msg), FALSE, NOVIEW);
966

967
#ifndef DISABLE_MULTIBUFFER
968
	add_to_funcs(new_buffer_void, MINSERTFILE|MEXTCMD,
969
	    N_("New Buffer"), IFSCHELP(nano_multibuffer_msg), FALSE, NOVIEW);
970
#endif
971
    }
972
#endif /* !NANO_TINY */
973

974
#ifndef DISABLE_BROWSER
Benno Schulenberg's avatar
Benno Schulenberg committed
975
    add_to_funcs(do_first_file, (MBROWSER|MWHEREISFILE),
976
	N_("First File"), IFSCHELP(nano_firstfile_msg), FALSE, VIEW);
Benno Schulenberg's avatar
Benno Schulenberg committed
977
    add_to_funcs(do_last_file, (MBROWSER|MWHEREISFILE),
978
	N_("Last File"), IFSCHELP(nano_lastfile_msg), FALSE, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
979

980
    add_to_funcs(goto_dir_void, MBROWSER,
981
	N_("Go To Dir"), IFSCHELP(nano_gotodir_msg), FALSE, VIEW);
982
983
#endif

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

986
987
    add_to_sclist(MMOST, "^G", do_help_void, 0, TRUE);
    add_to_sclist(MMOST, "F1", do_help_void, 0, TRUE);
988
989
990
991
    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, "^_", do_gotolinecolumn_void, 0, TRUE);
    add_to_sclist(MMAIN, "M-G", do_gotolinecolumn_void, 0, TRUE);
992
    add_to_sclist(MMAIN, "F13", do_gotolinecolumn_void, 0, TRUE);
993
994
    add_to_sclist(MMAIN, "^O", do_writeout_void, 0, TRUE);
    add_to_sclist(MMAIN, "F3", do_writeout_void, 0, TRUE);
995
#ifndef DISABLE_JUSTIFY
996
997
998
999
1000
    add_to_sclist(MMAIN, "^J", do_justify_void, 0, TRUE);
    add_to_sclist(MMAIN, "F4", do_justify_void, 0, TRUE);
#endif
    add_to_sclist(MMAIN, "^R", do_insertfile_void, 0, TRUE);
    add_to_sclist(MMAIN, "F5", do_insertfile_void, 0, TRUE);
1001
    add_to_sclist(MMAIN, "Ins", do_insertfile_void, 0, TRUE);
1002
1003
    add_to_sclist(MMAIN|MBROWSER, "^W", do_search, 0, TRUE);
    add_to_sclist(MMAIN|MBROWSER, "F6", do_search, 0, TRUE);
1004
1005
    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);
1006
    add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE|MLINTER, "PgUp", do_page_up, 0, TRUE);
1007
1008
    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);
1009
    add_to_sclist(MMAIN|MBROWSER|MHELP|MWHEREISFILE|MLINTER, "PgDn", do_page_down, 0, TRUE);
1010
1011
1012
1013
1014
1015
    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);
    add_to_sclist(MMAIN, "^C", do_cursorpos_void, 0, TRUE);
    add_to_sclist(MMAIN, "F11", do_cursorpos_void, 0, TRUE);
1016
#ifndef DISABLE_SPELLER
1017
1018
1019
1020
1021
    add_to_sclist(MMAIN, "^T", do_spell, 0, TRUE);
    add_to_sclist(MMAIN, "F12", do_spell, 0, TRUE);
#endif
    add_to_sclist(MMAIN, "^\\", do_replace, 0, TRUE);
    add_to_sclist(MMAIN, "M-R", do_replace, 0, TRUE);
1022
    add_to_sclist(MMAIN, "F14", do_replace, 0, TRUE);
1023
1024
1025
    add_to_sclist(MWHEREIS, "^R", do_replace, 0, FALSE);
    add_to_sclist(MREPLACE, "^R", no_replace_void, 0, FALSE);
    add_to_sclist(MWHEREIS, "^T", do_gotolinecolumn_void, 0, FALSE);
1026
#ifndef NANO_TINY
1027
1028
    add_to_sclist(MMAIN, "^^", do_mark, 0, TRUE);
    add_to_sclist(MMAIN, "M-A", do_mark, 0, TRUE);
1029
    add_to_sclist(MMAIN, "F15", do_mark, 0, TRUE);
1030
1031
1032
1033
1034
1035
    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_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);
1036
    if (ISSET(UNDOABLE)) {
1037
	add_to_sclist(MMAIN, "M-U", do_undo, 0, TRUE);
1038
	add_to_sclist(MMAIN, "M-E", do_redo, 0, TRUE);
1039
    }
1040
#endif
1041
    add_to_sclist(MMOST, "^B", do_left, 0, TRUE);
1042
    add_to_sclist(MMOST, "^F", do_right, 0, TRUE);
1043
    add_to_sclist(MMOST, "Left", do_left, 0, TRUE);
1044
    add_to_sclist(MMOST, "Right", do_right, 0, TRUE);
1045
#ifndef NANO_TINY
1046
1047
1048
1049
1050
1051
    add_to_sclist(MMAIN, "^Space", do_next_word_void, 0, TRUE);
    add_to_sclist(MMAIN, "M-Space", do_prev_word_void, 0, TRUE);
#endif
    add_to_sclist(MMAIN, "^Q", xon_complaint, 0, TRUE);
    add_to_sclist(MMAIN, "^S", xoff_complaint, 0, TRUE);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "^P", do_up_void, 0, TRUE);
1052
    add_to_sclist(MMAIN|MHELP|MBROWSER, "Up", do_up_void, 0, TRUE);
1053
    add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", do_down_void, 0, TRUE);
1054
    add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", do_down_void, 0, TRUE);
1055
    add_to_sclist(MMOST, "^A", do_home, 0, TRUE);
1056
    add_to_sclist(MMOST, "Home", do_home, 0, TRUE);
1057
    add_to_sclist(MMOST, "^E", do_end, 0, TRUE);
1058
    add_to_sclist(MMOST, "End", do_end, 0, TRUE);
1059
#ifndef NANO_TINY
1060
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "^P", get_history_older_void, 0, FALSE);
1061
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "Up", get_history_older_void, 0, FALSE);
1062
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "^N", get_history_newer_void, 0, FALSE);
1063
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "Down", get_history_newer_void, 0, FALSE);
1064
#endif
1065
#ifndef DISABLE_JUSTIFY
1066
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH,
1067
	"^W", do_para_begin_void, 0, TRUE);
1068
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH,
1069
	"^O", do_para_end_void, 0, TRUE);
1070
1071
1072
1073
    add_to_sclist(MMOST, "M-(", do_para_begin_void, 0, TRUE);
    add_to_sclist(MMOST, "M-9", do_para_begin_void, 0, TRUE);
    add_to_sclist(MMOST, "M-)", do_para_end_void, 0, TRUE);
    add_to_sclist(MMOST, "M-0", do_para_end_void, 0, TRUE);
Chris Allegretta's avatar
Chris Allegretta committed
1074
#endif
1075
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH,
1076
	"M-C", case_sens_void, 0, FALSE);
1077
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH,
1078
	"M-B", backwards_void, 0, FALSE);
1079
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH,
1080
	"M-R", regexp_void, 0, FALSE);
1081

1082
1083
1084
1085
    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);
1086
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE,
1087
	"^Y", do_first_line, 0, TRUE);
1088
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE,
1089
1090
1091
1092
1093
1094
1095
1096
1097
	"^V", do_last_line, 0, TRUE);

#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);
1098
    add_to_sclist(MBROWSER|MWHEREISFILE, "F13", goto_dir_void, 0, TRUE);
Benno Schulenberg's avatar
Benno Schulenberg committed
1099
#endif
1100
#ifndef NANO_TINY
1101
1102
1103
1104
1105
    add_to_sclist(MMAIN, "M-]", do_find_bracket, 0, TRUE);
    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);
1106
1107
#endif

1108
#ifndef DISABLE_MULTIBUFFER
1109
1110
1111
1112
    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);
1113
#endif
Benno Schulenberg's avatar
Benno Schulenberg committed
1114

1115
    add_to_sclist(MMOST, "M-V", do_verbatim_input, 0, TRUE);
1116
#ifndef NANO_TINY
1117
    add_to_sclist(MMAIN, "M-T", do_cut_till_end, 0, TRUE);
1118
#endif
1119
#ifndef DISABLE_JUSTIFY
1120
    add_to_sclist(MMAIN|MWHEREIS, "M-J", do_full_justify, 0, TRUE);
1121
#endif
1122
#ifndef NANO_TINY
1123
    add_to_sclist(MMAIN, "M-D", do_wordlinechar_count, 0, TRUE);
1124

1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
    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);
    add_to_sclist(MMAIN, "M-P", do_toggle_void, WHITESPACE_DISPLAY, TRUE);
    add_to_sclist(MMAIN, "M-Y", do_toggle_void, NO_COLOR_SYNTAX, TRUE);
    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);
    add_to_sclist(MMAIN, "M-L", do_toggle_void, NO_WRAP, TRUE);
1135
    add_to_sclist(MMAIN, "M-$", do_toggle_void, SOFTWRAP, TRUE);
1136
1137
1138
1139
1140
1141
    add_to_sclist(MMAIN, "M-Q", do_toggle_void, TABS_TO_SPACES, TRUE);
    add_to_sclist(MMAIN, "M-B", do_toggle_void, BACKUP_FILE, TRUE);
    add_to_sclist(MMAIN, "M-F", do_toggle_void, MULTIBUFFER, TRUE);
    add_to_sclist(MMAIN, "M-M", do_toggle_void, USE_MOUSE, TRUE);
    add_to_sclist(MMAIN, "M-N", do_toggle_void, NO_CONVERT, TRUE);
    add_to_sclist(MMAIN, "M-Z", do_toggle_void, SUSPEND, TRUE);
1142
#endif /* !NANO_TINY */
Benno Schulenberg's avatar
Benno Schulenberg committed
1143

1144
1145
    add_to_sclist(MGOTOLINE, "^T", gototext_void, 0, FALSE);
    add_to_sclist(MINSERTFILE|MEXTCMD, "M-F", new_buffer_void, 0, FALSE);
1146
    add_to_sclist(((MMOST & ~MMAIN & ~MBROWSER) | MYESNO), "^C", do_cancel, 0, FALSE);
1147
1148
1149
1150
1151
    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);
Benno Schulenberg's avatar
Benno Schulenberg committed
1152
    add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", to_files_void, 0, FALSE);
1153
    add_to_sclist(MINSERTFILE, "^X", ext_cmd_void, 0, FALSE);
1154
    add_to_sclist(MMAIN, "^Z", do_suspend_void, 0, FALSE);
1155
    add_to_sclist(MMAIN|MHELP, "^L", total_refresh, 0, FALSE);
1156
1157
    add_to_sclist(MHELP|MBROWSER, "^C", do_exit, 0, TRUE);
    add_to_sclist(MHELP, "^G", do_exit, 0, TRUE);
1158
1159
    add_to_sclist(MMOST, "^I", do_tab, 0, TRUE);
    add_to_sclist(MMOST, "^M", do_enter_void, 0, TRUE);
1160
    add_to_sclist(MMOST, "Enter", do_enter_void, 0, TRUE);
1161
    add_to_sclist(MMOST, "^D", do_delete, 0, TRUE);
1162
    add_to_sclist(MMOST, "Del", do_delete, 0, TRUE);
1163
    add_to_sclist(MMOST, "^H", do_backspace, 0, TRUE);
1164
    add_to_sclist(MMOST, "Bsp", do_backspace, 0, TRUE);
Chris Allegretta's avatar
Chris Allegretta committed
1165

1166
1167
#ifdef DEBUG
    print_sclist();
Chris Allegretta's avatar
Chris Allegretta committed
1168
#endif
1169
}
1170

1171
#ifndef DISABLE_COLOR
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
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

1187
const subnfunc *sctofunc(sc *s)
1188
{
1189
    subnfunc *f;
1190

1191
1192
    for (f = allfuncs; f != NULL && s->scfunc != f->scfunc; f = f->next)
	;
1193

1194
    return f;
1195
1196
}

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

1245
1246
1247
/* 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)
1248
{
1249
    sc *s;
1250
1251

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

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

1497
#ifndef DISABLE_NANORC
1498
/* Same thing as above but for the menu. */
1499
1500
1501
int strtomenu(char *input)
{
    if (!strcasecmp(input, "all"))
1502
	return (MMOST|MHELP|MYESNO);
1503
1504
1505
1506
1507
1508
1509
    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
1510
	     !strcasecmp(input, "replacewith"))
1511
	return MREPLACEWITH;
1512
1513
1514
1515
1516
1517
1518
    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
1519
	     !strcasecmp(input, "extcmd"))
1520
1521
1522
1523
1524
	return MEXTCMD;
    else if (!strcasecmp(input, "help"))
	return MHELP;
    else if (!strcasecmp(input, "spell"))
	return MSPELL;
1525
1526
    else if (!strcasecmp(input, "linter"))
	return MLINTER;
1527
1528
1529
1530
1531
1532
1533
1534
1535
    else if (!strcasecmp(input, "browser"))
	return MBROWSER;
    else if (!strcasecmp(input, "whereisfile"))
	return MWHEREISFILE;
    else if (!strcasecmp(input, "gotodir"))
	return MGOTODIR;

    return -1;
}
1536
1537
#endif

Chris Allegretta's avatar
Chris Allegretta committed
1538

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

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

	free(syntaxes->desc);
	while (syntaxes->extensions != NULL) {
	    exttype *bob = syntaxes->extensions;

	    syntaxes->extensions = bob->next;
1600
	    free(bob->ext_regex);
1601
1602
1603
1604
	    if (bob->ext != NULL) {
		regfree(bob->ext);
		free(bob->ext);
	    }
Chris Allegretta's avatar
Chris Allegretta committed
1605
1606
1607
1608
1609
1610
	    free(bob);
	}
	while (syntaxes->color != NULL) {
	    colortype *bob = syntaxes->color;

	    syntaxes->color = bob->next;
1611
	    free(bob->start_regex);
1612
1613
1614
1615
	    if (bob->start != NULL) {
		regfree(bob->start);
		free(bob->start);
	    }
1616
1617
	    if (bob->end_regex != NULL)
		free(bob->end_regex);
1618
	    if (bob->end != NULL) {
1619
		regfree(bob->end);
1620
1621
		free(bob->end);
	    }
Chris Allegretta's avatar
Chris Allegretta committed
1622
1623
1624
1625
1626
	    free(bob);
	}
	syntaxes = syntaxes->next;
	free(bill);
    }
1627
#endif /* !DISABLE_COLOR */
1628
#ifndef NANO_TINY
1629
    /* Free the search and replace history lists. */
1630
1631
1632
1633
    if (searchage != NULL)
	free_filestruct(searchage);
    if (replaceage != NULL)
	free_filestruct(replaceage);
1634
#endif
1635
#ifndef DISABLE_NANORC
1636
1637
    if (homedir != NULL)
	free(homedir);
1638
#endif
1639
}
1640

1641
#endif /* DEBUG */