global.c 60.6 KB
Newer Older
Chris Allegretta's avatar
Chris Allegretta committed
1
/**************************************************************************
2
 *   global.c  --  This file is part of GNU nano.                         *
Chris Allegretta's avatar
Chris Allegretta committed
3
 *                                                                        *
4
 *   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,  *
5
 *   2008, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc.    *
6
7
 *   Copyright (C) 2014, 2015, 2016 Benno Schulenberg                     *
 *                                                                        *
8
9
10
11
 *   GNU nano is free software: you can redistribute it and/or modify     *
 *   it under the terms of the GNU General Public License as published    *
 *   by the Free Software Foundation, either version 3 of the License,    *
 *   or (at your option) any later version.                               *
Chris Allegretta's avatar
Chris Allegretta committed
12
 *                                                                        *
13
14
15
16
 *   GNU nano is distributed in the hope that it will be useful,          *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty          *
 *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.              *
 *   See the GNU General Public License for more details.                 *
Chris Allegretta's avatar
Chris Allegretta committed
17
18
 *                                                                        *
 *   You should have received a copy of the GNU General Public License    *
19
 *   along with this program.  If not, see http://www.gnu.org/licenses/.  *
Chris Allegretta's avatar
Chris Allegretta committed
20
21
22
 *                                                                        *
 **************************************************************************/

23
24
#include "proto.h"

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

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

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

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

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

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

56
57
message_type lastmessage = HUSH;
	/* Messages of type HUSH should not overwrite type MILD nor ALERT. */
58

59
60
61
filestruct *pletion_line = NULL;
	/* The line where the last completion was found, if any. */

62
int controlleft, controlright, controlup, controldown;
63
#ifndef NANO_TINY
64
65
int shiftcontrolleft, shiftcontrolright, shiftcontrolup, shiftcontroldown;
int shiftaltleft, shiftaltright, shiftaltup, shiftaltdown;
66
67
#endif

68
#ifndef DISABLE_WRAPJUSTIFY
69
70
ssize_t fill = 0;
	/* The column where we will wrap lines. */
71
ssize_t wrap_at = -CHARS_FROM_EOL;
72
73
74
75
76
77
78
79
	/* 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. */

80
81
82
char *present_path = NULL;
	/* The current browser directory when trying to do tab completion. */

83
unsigned flags[4] = {0, 0, 0, 0};
84
85
86
87
88
89
	/* 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;
90
	/* The middle portion of the window, i.e. the edit window, where
91
92
93
94
95
96
	 * 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? */
97
int maxrows = 0;
98
	/* How many usable lines there are (due to soft wrapping). */
99
100
101

filestruct *cutbuffer = NULL;
	/* The buffer where we store cut text. */
102
filestruct *cutbottom = NULL;
103
	/* The last line in the cutbuffer. */
104
partition *filepart = NULL;
105
	/* The "partition" where we store a portion of the current file. */
106
openfilestruct *openfile = NULL;
107
	/* The list of all open file buffers. */
108

109
110
111
112
#ifndef NANO_TINY
char *matchbrackets = NULL;
	/* The opening and closing brackets that can be found by bracket
	 * searches. */
113
char *whitespace = NULL;
114
	/* The characters used when visibly showing tabs and spaces. */
115
int whitespace_len[2];
116
	/* The length in bytes of these characters. */
117
118
#endif

119
#ifndef DISABLE_JUSTIFY
120
121
122
123
124
125
126
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(). */
127
#ifdef HAVE_REGEX_H
128
129
130
regex_t quotereg;
	/* The compiled regular expression from the quoting string. */
int quoterc;
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
131
	/* Whether it was compiled successfully. */
132
133
char *quoteerr = NULL;
	/* The error message, if it didn't. */
134
#else
135
136
size_t quotelen;
	/* The length of the quoting string in bytes. */
Chris Allegretta's avatar
Chris Allegretta committed
137
#endif
138
#endif /* !DISABLE_JUSTIFY */
139

140
141
142
char *word_chars = NULL;
	/* Nonalphanumeric characters that also form words. */

143
bool nodelay_mode = FALSE;
144
	/* Are we checking for a cancel wile doing something? */
145

146
char *answer = NULL;
147
	/* The answer string used by the statusbar prompt. */
Chris Allegretta's avatar
Chris Allegretta committed
148

149
ssize_t tabsize = -1;
150
	/* The width of a tab in spaces.  The default is set in main(). */
151

152
153
154
#ifndef NANO_TINY
char *backup_dir = NULL;
	/* The directory where we store backup files. */
155

156
const char *locking_prefix = ".";
157
	/* Prefix of how to store the vim-style lock file. */
158
const char *locking_suffix = ".swp";
159
	/* Suffix of the vim-style lock file. */
160
#endif
161
#ifndef DISABLE_OPERATINGDIR
162
163
164
165
166
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. */
167
168
#endif

169
#ifndef DISABLE_SPELLER
170
171
char *alt_speller = NULL;
	/* The command to use for the alternate spell checker. */
172
173
#endif

174
#ifndef DISABLE_COLOR
175
syntaxtype *syntaxes = NULL;
176
	/* The global list of color syntaxes. */
177
char *syntaxstr = NULL;
178
	/* The color syntax name specified on the command line. */
179
180
#endif

181
182
183
bool refresh_needed = FALSE;
	/* Did a command mangle enough of the buffer that we should
	 * repaint the screen? */
184

185
186
int currmenu = MMOST;
	/* The currently active menu, initialized to a dummy value. */
187
sc *sclist = NULL;
188
	/* The start of the shortcuts list. */
189
subnfunc *allfuncs = NULL;
190
	/* The start of the functions list. */
191
subnfunc *tailfunc;
192
	/* The last function in the list. */
193
subnfunc *exitfunc;
194
	/* A pointer to the special Exit/Close item. */
195
subnfunc *uncutfunc;
196
	/* A pointer to the special Uncut/Unjustify item. */
197

198
#ifndef DISABLE_HISTORIES
199
filestruct *search_history = NULL;
200
	/* The search string history list. */
201
filestruct *searchage = NULL;
202
	/* The top of the search string history list. */
203
filestruct *searchbot = NULL;
204
	/* The bottom of the search string history list. */
205
filestruct *replace_history = NULL;
206
	/* The replace string history list. */
207
filestruct *replaceage = NULL;
208
	/* The top of the replace string history list. */
209
filestruct *replacebot = NULL;
210
	/* The bottom of the replace string history list. */
211
poshiststruct *position_history = NULL;
212
	/* The cursor position history list. */
213
214
#endif

215
#ifdef HAVE_REGEX_H
216
217
218
219
220
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
221
#endif
222

223
int hilite_attribute = A_REVERSE;
224
	/* The curses attribute we use to highlight something. */
225
226
227
228
#ifndef DISABLE_COLOR
char* specified_color_combo[] = {};
	/* The color combinations as specified in the rcfile. */
#endif
229
int interface_color_pair[] = {};
230
	/* The processed color pairs for the interface elements. */
231

232
char *homedir = NULL;
233
	/* The user's home directory, from $HOME or /etc/passwd. */
234

235

236
/* Return the number of entries in the shortcut list for a given menu. */
237
size_t length_of_list(int menu)
238
{
239
    subnfunc *f;
240
    size_t i = 0;
241

242
    for (f = allfuncs; f != NULL; f = f->next)
243
	if ((f->menus & menu) && first_sc_for(menu, f->scfunc) != NULL)
244
	    i++;
245

246
247
248
    return i;
}

249
250
251
252
253
254
/* To make the functions and shortcuts lists clearer. */
#define VIEW  TRUE		/* Is allowed in view mode. */
#define NOVIEW  FALSE
#define BLANKAFTER  TRUE	/* A blank line after this one. */
#define TOGETHER  FALSE

255
/* Just throw this here. */
256
257
258
259
260
261
void case_sens_void(void)
{
}
void regexp_void(void)
{
}
262
263
264
void backwards_void(void)
{
}
265
266
267
void gototext_void(void)
{
}
268
#ifndef DISABLE_BROWSER
269
270
271
void to_files_void(void)
{
}
272
273
274
275
void goto_dir_void(void)
{
}
#endif
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
void dos_format_void(void)
{
}
void mac_format_void(void)
{
}
void append_void(void)
{
}
void prepend_void(void)
{
}
void backup_file_void(void)
{
}
291
292
293
void discard_buffer(void)
{
}
294
295
296
void new_buffer_void(void)
{
}
297
void flip_replace_void(void)
298
299
{
}
300
void flip_execute_void(void)
301
302
303
{
}

304
/* Add a function to the function list. */
305
void add_to_funcs(void (*func)(void), int menus, const char *desc, const char *help,
306
307
    bool blank_after, bool viewok)
{
308
    subnfunc *f = (subnfunc *)nmalloc(sizeof(subnfunc));
309
310
311
312
313
314

    if (allfuncs == NULL)
	allfuncs = f;
    else
	tailfunc->next = f;
    tailfunc = f;
315
316
317
318
319
320

    f->next = NULL;
    f->scfunc = func;
    f->menus = menus;
    f->desc = desc;
    f->viewok = viewok;
321
#ifndef DISABLE_HELP
322
323
324
325
326
    f->help = help;
    f->blank_after = blank_after;
#endif

#ifdef DEBUG
327
    fprintf(stderr, "Added func %ld (%s) for menus %x\n", (long)func, f->desc, menus);
328
#endif
329
330
}

331
/* Add a key combo to the shortcut list. */
332
333
void add_to_sclist(int menus, const char *scstring, const int keycode,
			void (*func)(void), int toggle)
Chris Allegretta's avatar
Chris Allegretta committed
334
{
335
    static sc *tailsc;
336
#ifndef NANO_TINY
337
    static int counter = 0;
338
#endif
339
    sc *s = (sc *)nmalloc(sizeof(sc));
340

341
342
343
344
345
346
347
348
349
    /* Start the list, or tack on the next item. */
    if (sclist == NULL)
	sclist = s;
    else
	tailsc->next = s;
    tailsc = s;
    s->next = NULL;

    /* Fill in the data. */
350
    s->menus = menus;
351
    s->scfunc = func;
352
#ifndef NANO_TINY
353
    s->toggle = toggle;
354
355
    if (toggle)
	s->ordinal = ++counter;
356
#endif
357
    assign_keyinfo(s, scstring, keycode);
358
359

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

364
/* Assign one function's shortcuts to another function. */
365
366
367
368
void replace_scs_for(void (*oldfunc)(void), void (*newfunc)(void))
{
    sc *s;

369
    for (s = sclist; s != NULL; s = s->next)
370
	if (s->scfunc == oldfunc)
371
372
373
	    s->scfunc = newfunc;
}

374
375
376
377
378
379
380
/* Return the first shortcut in the list of shortcuts that
 * matches the given func in the given menu. */
const sc *first_sc_for(int menu, void (*func)(void))
{
    const sc *s;

    for (s = sclist; s != NULL; s = s->next)
381
	if ((s->menus & menu) && s->scfunc == func)
382
383
384
385
386
387
388
389
390
	    return s;

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

391
392
393
/* Return the first keycode that is bound to the given function in the
 * current menu, if any; otherwise, return the given default value. */
int the_code_for(void (*func)(void), int defaultval)
Chris Allegretta's avatar
Chris Allegretta committed
394
395
396
{
    const sc *s = first_sc_for(currmenu, func);

397
398
399
400
401
    if (s == NULL)
	return defaultval;

    meta_key = s->meta;
    return s->keycode;
Chris Allegretta's avatar
Chris Allegretta committed
402
403
}

404
405
406
407
408
409
410
411
412
413
414
/* Return a pointer to the function that is bound to the given key. */
functionptrtype func_from_key(int *kbinput)
{
    const sc *s = get_shortcut(kbinput);

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

415
/* Set the string and its corresponding keycode for the given shortcut s. */
416
void assign_keyinfo(sc *s, const char *keystring, const int keycode)
417
{
418
    s->keystr = keystring;
419
    s->meta = (keystring[0] == 'M');
420

421
422
    assert(strlen(keystring) > 1 && (!s->meta || strlen(keystring) > 2));

423
424
425
    if (keycode)
	s->keycode = keycode;
    else if (keystring[0] == '^') {
426
427
	if (strcasecmp(keystring, "^Space") == 0)
	    s->keycode = 0;
428
429
	else
	    s->keycode = keystring[1] - 64;
430
431
432
    } else if (s->meta) {
	if (strcasecmp(keystring, "M-Space") == 0)
	    s->keycode = (int)' ';
433
434
	else
	    s->keycode = tolower((int)keystring[2]);
435
    } else if (keystring[0] == 'F')
436
437
	s->keycode = KEY_F0 + atoi(&keystring[1]);
    else if (!strcasecmp(keystring, "Ins"))
438
	s->keycode = KEY_IC;
439
    else if (!strcasecmp(keystring, "Del"))
440
	s->keycode = KEY_DC;
441
442
443
444
445
446
447
448
}

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

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

459
460
/* These four tags are used elsewhere too, so they are global. */
/* TRANSLATORS: Try to keep the next fifteen strings at most 10 characters. */
461
462
const char *exit_tag = N_("Exit");
const char *close_tag = N_("Close");
463
const char *uncut_tag = N_("Uncut Text");
464
#ifndef DISABLE_JUSTIFY
465
466
const char *unjust_tag = N_("Unjustify");
#endif
467

468
469
/* Initialize the list of functions and the list of shortcuts. */
void shortcut_init(void)
470
{
471
    const char *read_file_tag = N_("Read File");
472
    const char *whereis_tag = N_("Where Is");
473
474
    const char *replace_tag = N_("Replace");
    const char *gotoline_tag = N_("Go To Line");
475
476
    const char *prev_line_tag = N_("Prev Line");
    const char *next_line_tag = N_("Next Line");
477
478
    const char *prev_page_tag = N_("Prev Page");
    const char *next_page_tag = N_("Next Page");
479
#ifndef DISABLE_JUSTIFY
480
    const char *justify_tag = N_("Justify");
481
    const char *fulljustify_tag = N_("FullJstify");
482
#endif
483
    const char *refresh_tag = N_("Refresh");
484
485
    /* TRANSLATORS: Try to keep this string at most 12 characters. */
    const char *whereis_next_tag = N_("WhereIs Next");
486

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

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

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

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

661
    add_to_funcs(do_cancel, ((MMOST & ~MMAIN & ~MBROWSER) | MYESNO),
662
	N_("Cancel"), IFSCHELP(nano_cancel_msg), BLANKAFTER, VIEW);
663

664
    add_to_funcs(do_exit, MMAIN,
665
	exit_tag, IFSCHELP(nano_exit_msg), TOGETHER, VIEW);
666
667
    /* Remember the entry for Exit, to be able to replace it with Close. */
    exitfunc = tailfunc;
Chris Allegretta's avatar
Chris Allegretta committed
668

669
#ifndef DISABLE_BROWSER
670
    add_to_funcs(do_exit, MBROWSER,
671
	exit_tag, IFSCHELP(nano_exitbrowser_msg), TOGETHER, VIEW);
672
#endif
Chris Allegretta's avatar
Chris Allegretta committed
673

674
    add_to_funcs(do_writeout_void, MMAIN,
675
	N_("Write Out"), IFSCHELP(nano_writeout_msg), TOGETHER, NOVIEW);
676

677
678
679
680
681
682
683
#ifndef DISABLE_JUSTIFY
    if (!ISSET(RESTRICTED)) {
#else
    /* If we can't replace Insert with Justify, show Insert anyway, to
     * keep the help items nicely paired also in restricted mode.  */
    if (TRUE) {
#endif
684
685
	add_to_funcs(do_insertfile_void, MMAIN,
		read_file_tag, IFSCHELP(nano_insert_msg), BLANKAFTER,
686
687
		/* We allow inserting files in view mode if multibuffer mode
		 * is switched on, so that we can view multiple files. */
688
#ifndef DISABLE_MULTIBUFFER
689
		VIEW);
690
#else
691
		NOVIEW);
692
#endif
693
694
    } else {
#ifndef DISABLE_JUSTIFY
695
	add_to_funcs(do_justify_void, MMAIN,
696
		justify_tag, IFSCHELP(nano_justify_msg), BLANKAFTER, NOVIEW);
697
698
#endif
    }
Chris Allegretta's avatar
Chris Allegretta committed
699

700
    add_to_funcs(do_search, MMAIN,
701
	whereis_tag, IFSCHELP(nano_whereis_msg), TOGETHER, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
702

703
    add_to_funcs(do_replace, MMAIN,
704
	replace_tag, IFSCHELP(nano_replace_msg), TOGETHER, NOVIEW);
705
706

#ifndef DISABLE_BROWSER
707
    add_to_funcs(do_search, MBROWSER,
708
	whereis_tag, IFSCHELP(nano_browser_whereis_msg), TOGETHER, VIEW);
709

710
    add_to_funcs(goto_dir_void, MBROWSER,
711
	N_("Go To Dir"), IFSCHELP(nano_gotodir_msg), BLANKAFTER, VIEW);
712
713
#endif

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

719
    add_to_funcs(total_refresh, MHELP, refresh_tag, "x", 0, VIEW);
720
721
722

    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);
723
724
#endif

725
    add_to_funcs(do_cut_text_void, MMAIN,
726
	N_("Cut Text"), IFSCHELP(nano_cut_msg), TOGETHER, NOVIEW);
Chris Allegretta's avatar
Chris Allegretta committed
727

728
    add_to_funcs(do_uncut_text, MMAIN,
729
	uncut_tag, IFSCHELP(nano_uncut_msg), BLANKAFTER, NOVIEW);
730
    /* Remember the entry for Uncut, to be able to replace it with Unjustify. */
731
    uncutfunc = tailfunc;
Chris Allegretta's avatar
Chris Allegretta committed
732

733
    if (!ISSET(RESTRICTED)) {
734
#ifndef DISABLE_JUSTIFY
735
	add_to_funcs(do_justify_void, MMAIN,
736
		justify_tag, IFSCHELP(nano_justify_msg), TOGETHER, NOVIEW);
Chris Allegretta's avatar
Chris Allegretta committed
737
#endif
Chris Allegretta's avatar
Chris Allegretta committed
738

739
#ifndef DISABLE_SPELLER
740
741
	add_to_funcs(do_spell, MMAIN,
		N_("To Spell"), IFSCHELP(nano_spell_msg), TOGETHER, NOVIEW);
742
#endif
743
#ifndef DISABLE_COLOR
744
745
	add_to_funcs(do_linter, MMAIN,
		N_("To Linter"), IFSCHELP(nano_lint_msg), TOGETHER, NOVIEW);
746
#ifndef DISABLE_SPELLER
747
748
	add_to_funcs(do_formatter, MMAIN,
		N_("Formatter"), IFSCHELP(nano_formatter_msg), BLANKAFTER, NOVIEW);
749
#endif
750
#endif
751
    }
752

753
754
755
756
757
758
759
760
761
762
763
    add_to_funcs(do_cursorpos_void, MMAIN,
	N_("Cur Pos"), IFSCHELP(nano_cursorpos_msg), TOGETHER, VIEW);

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

764
    add_to_funcs(case_sens_void, MWHEREIS|MREPLACE,
765
	N_("Case Sens"), IFSCHELP(nano_case_msg), TOGETHER, VIEW);
766
#ifdef HAVE_REGEX_H
767
    add_to_funcs(regexp_void, MWHEREIS|MREPLACE,
768
	N_("Regexp"), IFSCHELP(nano_regexp_msg), TOGETHER, VIEW);
769
#endif
770
    add_to_funcs(backwards_void, MWHEREIS|MREPLACE,
771
	N_("Backwards"), IFSCHELP(nano_reverse_msg), TOGETHER, VIEW);
772

773
    add_to_funcs(flip_replace_void, MWHEREIS,
774
	replace_tag, IFSCHELP(nano_replace_msg), BLANKAFTER, VIEW);
775

776
    add_to_funcs(flip_replace_void, MREPLACE,
777
	N_("No Replace"), IFSCHELP(nano_whereis_msg), BLANKAFTER, VIEW);
778
779

#ifndef DISABLE_JUSTIFY
780
    add_to_funcs(do_full_justify, MWHEREIS,
781
	fulljustify_tag, IFSCHELP(nano_fulljustify_msg), TOGETHER, NOVIEW);
782

783
    add_to_funcs(do_gotolinecolumn_void, MWHEREIS,
784
	gotoline_tag, IFSCHELP(nano_gotoline_msg), BLANKAFTER, VIEW);
785
#endif
786

787
788
789
790
    add_to_funcs(do_page_up, MMAIN|MHELP,
	prev_page_tag, IFSCHELP(nano_prevpage_msg), TOGETHER, VIEW);
    add_to_funcs(do_page_down, MMAIN|MHELP,
	next_page_tag, IFSCHELP(nano_nextpage_msg), TOGETHER, VIEW);
791

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

797
#ifndef NANO_TINY
798
    add_to_funcs(do_research, MMAIN,
799
	whereis_next_tag, IFSCHELP(nano_whereis_next_msg), TOGETHER, VIEW);
800

801
    add_to_funcs(do_find_bracket, MMAIN,
802
	N_("To Bracket"), IFSCHELP(nano_bracket_msg), TOGETHER, VIEW);
803

804
    add_to_funcs(do_mark, MMAIN,
805
	N_("Mark Text"), IFSCHELP(nano_mark_msg), TOGETHER, VIEW);
806

807
    add_to_funcs(do_copy_text, MMAIN,
808
	N_("Copy Text"), IFSCHELP(nano_copy_msg), BLANKAFTER, NOVIEW);
809

810
    add_to_funcs(do_indent_void, MMAIN,
811
	N_("Indent Text"), IFSCHELP(nano_indent_msg), TOGETHER, NOVIEW);
812
    add_to_funcs(do_unindent, MMAIN,
813
	N_("Unindent Text"), IFSCHELP(nano_unindent_msg), BLANKAFTER, NOVIEW);
814

815
    add_to_funcs(do_undo, MMAIN,
816
	N_("Undo"), IFSCHELP(nano_undo_msg), TOGETHER, NOVIEW);
817
    add_to_funcs(do_redo, MMAIN,
818
	N_("Redo"), IFSCHELP(nano_redo_msg), BLANKAFTER, NOVIEW);
819
#endif /* !NANO_TINY */
820

821
    add_to_funcs(do_left, MMAIN,
822
	N_("Back"), IFSCHELP(nano_back_msg), TOGETHER, VIEW);
823
    add_to_funcs(do_right, MMAIN,
824
	N_("Forward"), IFSCHELP(nano_forward_msg), TOGETHER, VIEW);
825
826

#ifndef DISABLE_BROWSER
827
    add_to_funcs(do_left, MBROWSER,
828
	N_("Back"), IFSCHELP(nano_backfile_msg), TOGETHER, VIEW);
829
    add_to_funcs(do_right, MBROWSER,
830
	N_("Forward"), IFSCHELP(nano_forwardfile_msg), TOGETHER, VIEW);
831
832
#endif

833
    add_to_funcs(do_prev_word_void, MMAIN,
834
	N_("Prev Word"), IFSCHELP(nano_prevword_msg), TOGETHER, VIEW);
835
    add_to_funcs(do_next_word_void, MMAIN,
836
	N_("Next Word"), IFSCHELP(nano_nextword_msg), TOGETHER, VIEW);
837

838
    add_to_funcs(do_home, MMAIN,
839
	N_("Home"), IFSCHELP(nano_home_msg), TOGETHER, VIEW);
840
    add_to_funcs(do_end, MMAIN,
841
	N_("End"), IFSCHELP(nano_end_msg), TOGETHER, VIEW);
842

843
    add_to_funcs(do_up_void, MMAIN|MBROWSER,
844
	prev_line_tag, IFSCHELP(nano_prevline_msg), TOGETHER, VIEW);
845
    add_to_funcs(do_down_void, MMAIN|MBROWSER,
846
	next_line_tag, IFSCHELP(nano_nextline_msg), BLANKAFTER, VIEW);
847

848
849
850
851
852
    add_to_funcs(do_prev_block, MMAIN,
	N_("Prev Block"), IFSCHELP(nano_prevblock_msg), TOGETHER, VIEW);
    add_to_funcs(do_next_block, MMAIN,
	N_("Next Block"), IFSCHELP(nano_nextblock_msg), TOGETHER, VIEW);

853
#ifndef DISABLE_JUSTIFY
854
    add_to_funcs(do_para_begin_void, MMAIN|MWHEREIS,
855
	N_("Beg of Par"), IFSCHELP(nano_parabegin_msg), TOGETHER, VIEW);
856
    add_to_funcs(do_para_end_void, MMAIN|MWHEREIS,
857
	N_("End of Par"), IFSCHELP(nano_paraend_msg), TOGETHER, VIEW);
858
#endif
859

860
#ifndef NANO_TINY
861
    add_to_funcs(do_scroll_up, MMAIN,
862
	N_("Scroll Up"), IFSCHELP(nano_scrollup_msg), TOGETHER, VIEW);
863
    add_to_funcs(do_scroll_down, MMAIN,
864
	N_("Scroll Down"), IFSCHELP(nano_scrolldown_msg), BLANKAFTER, VIEW);
865
866
#endif

867
#ifndef DISABLE_MULTIBUFFER
868
    add_to_funcs(switch_to_prev_buffer_void, MMAIN,
869
	N_("Prev File"), IFSCHELP(nano_prevfile_msg), TOGETHER, VIEW);
870
    add_to_funcs(switch_to_next_buffer_void, MMAIN,
871
	N_("Next File"), IFSCHELP(nano_nextfile_msg), BLANKAFTER, VIEW);
872
873
#endif

874
875
#if (defined(DISABLE_JUSTIFY) && (!defined(DISABLE_SPELLER) || !defined(DISABLE_COLOR)) || \
	!defined(DISABLE_JUSTIFY) && defined(DISABLE_SPELLER) && defined(DISABLE_COLOR))
876
    add_to_funcs(do_gotolinecolumn_void, MMAIN,
877
	gotoline_tag, IFSCHELP(nano_gotoline_msg), BLANKAFTER, VIEW);
878
879
#endif

880
881
882
883
884
885
#ifdef NANO_TINY
    /* Place this one here only in the tiny version; otherwise further up. */
    add_to_funcs(do_research, MMAIN,
	whereis_next_tag, IFSCHELP(nano_whereis_next_msg), TOGETHER, VIEW);
#endif

886
    add_to_funcs(do_verbatim_input, MMAIN,
887
	N_("Verbatim"), IFSCHELP(nano_verbatim_msg), TOGETHER, NOVIEW);
888

889
    add_to_funcs(do_tab, MMAIN,
890
	N_("Tab"), IFSCHELP(nano_tab_msg), TOGETHER, NOVIEW);
891
    add_to_funcs(do_enter, MMAIN,
892
893
	N_("Enter"), IFSCHELP(nano_enter_msg), BLANKAFTER, NOVIEW);

894
    add_to_funcs(do_delete, MMAIN,
895
	N_("Delete"), IFSCHELP(nano_delete_msg), TOGETHER, NOVIEW);
896
897
    add_to_funcs(do_backspace, MMAIN,
	N_("Backspace"), IFSCHELP(nano_backspace_msg),
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
898
#ifndef NANO_TINY
899
	TOGETHER,
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
900
#else
901
	BLANKAFTER,
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
902
#endif
903
904
	NOVIEW);

905
#ifndef NANO_TINY
906
    add_to_funcs(do_cut_prev_word, MMAIN,
907
	/* TRANSLATORS: The next two strings refer to cutting words. */
908
909
910
	N_("Cut Left"), IFSCHELP(nano_cut_word_left_msg), TOGETHER, NOVIEW);
    add_to_funcs(do_cut_next_word, MMAIN,
	N_("Cut Right"), IFSCHELP(nano_cut_word_right_msg), TOGETHER, NOVIEW);
911
    add_to_funcs(do_cut_till_eof, MMAIN,
912
	N_("CutTillEnd"), IFSCHELP(nano_cut_till_eof_msg), BLANKAFTER, NOVIEW);
913
#endif
Chris Allegretta's avatar
Chris Allegretta committed
914

915
#ifndef DISABLE_JUSTIFY
916
    add_to_funcs(do_full_justify, MMAIN,
917
	fulljustify_tag, IFSCHELP(nano_fulljustify_msg), TOGETHER, NOVIEW);
918
919
#endif

920
#ifndef NANO_TINY
921
    add_to_funcs(do_wordlinechar_count, MMAIN,
922
	N_("Word Count"), IFSCHELP(nano_wordcount_msg), TOGETHER, VIEW);
923
#endif
924

925
    add_to_funcs(total_refresh, MMAIN,
926
	refresh_tag, IFSCHELP(nano_refresh_msg), TOGETHER, VIEW);
927

928
    add_to_funcs(do_suspend_void, MMAIN,
929
	N_("Suspend"), IFSCHELP(nano_suspend_msg), BLANKAFTER, VIEW);
Chris Allegretta's avatar
Chris Allegretta committed
930

931
932
933
934
#ifdef ENABLE_WORDCOMPLETION
    add_to_funcs(complete_a_word, MMAIN,
	N_("Complete"), IFSCHELP(nano_completion_msg), TOGETHER, NOVIEW);
#endif
935
936
937
938
#ifdef ENABLE_COMMENT
    add_to_funcs(do_comment, MMAIN,
	N_("Comment Lines"), IFSCHELP(nano_comment_msg), BLANKAFTER, NOVIEW);
#endif
939
940
941
#ifndef NANO_TINY
    add_to_funcs(do_savefile, MMAIN,
	N_("Save"), IFSCHELP(nano_savefile_msg), BLANKAFTER, NOVIEW);
942
943
944
945
946

    add_to_funcs(do_findprevious, MMAIN,
	N_("Previous"), IFSCHELP(nano_findprev_msg), TOGETHER, VIEW);
    add_to_funcs(do_findnext, MMAIN,
	N_("Next"), IFSCHELP(nano_findnext_msg), BLANKAFTER, VIEW);
947
948
#endif

949
#ifndef DISABLE_HISTORIES
950
    add_to_funcs(get_history_older_void,
951
	(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE),
952
	N_("PrevHstory"), IFSCHELP(nano_prev_history_msg), TOGETHER, VIEW);
953
    add_to_funcs(get_history_newer_void,
954
	(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE),
955
956
957
	N_("NextHstory"), IFSCHELP(nano_next_history_msg), BLANKAFTER, VIEW);
#endif

958
#ifdef DISABLE_JUSTIFY
959
960
    add_to_funcs(do_gotolinecolumn_void, MWHEREIS,
	gotoline_tag, IFSCHELP(nano_gotoline_msg), BLANKAFTER, VIEW);
961
#endif
962

963
    add_to_funcs(gototext_void, MGOTOLINE,
964
	N_("Go To Text"), IFSCHELP(nano_whereis_msg), BLANKAFTER, VIEW);
965

966
#ifndef NANO_TINY
967
    add_to_funcs(dos_format_void, MWRITEFILE,
968
	N_("DOS Format"), IFSCHELP(nano_dos_msg), TOGETHER, NOVIEW);
969
    add_to_funcs(mac_format_void, MWRITEFILE,
970
971
972
973
974
975
	N_("Mac Format"), IFSCHELP(nano_mac_msg), TOGETHER, NOVIEW);

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

982
	add_to_funcs(backup_file_void, MWRITEFILE,
983
	    N_("Backup File"), IFSCHELP(nano_backup_msg), BLANKAFTER, NOVIEW);
984
    }
985

986
987
988
    /* If we're using restricted mode, file insertion is disabled, and
     * thus command execution and the multibuffer toggle have no place. */
    if (!ISSET(RESTRICTED)) {
989
	add_to_funcs(flip_execute_void, MINSERTFILE,
990
	    N_("Execute Command"), IFSCHELP(nano_execute_msg), TOGETHER, NOVIEW);
991

992
	add_to_funcs(flip_execute_void, MEXTCMD,
993
	    read_file_tag, IFSCHELP(nano_insert_msg), TOGETHER, NOVIEW);
994

995
#ifndef DISABLE_MULTIBUFFER
996
	add_to_funcs(new_buffer_void, MINSERTFILE|MEXTCMD,
997
	    N_("New Buffer"), IFSCHELP(nano_multibuffer_msg), TOGETHER, NOVIEW);
998
#endif
999
    }
1000
#endif /* !NANO_TINY */
1001

1002
#ifndef DISABLE_BROWSER
1003
1004
    if (!ISSET(RESTRICTED))
	add_to_funcs(to_files_void, MWRITEFILE|MINSERTFILE,
1005
	    N_("To Files"), IFSCHELP(nano_tofiles_msg), TOGETHER, VIEW);
1006

1007
1008
1009
1010
1011
    add_to_funcs(do_page_up, MBROWSER,
	prev_page_tag, IFSCHELP(nano_prevpage_msg), TOGETHER, VIEW);
    add_to_funcs(do_page_down, MBROWSER,
	next_page_tag, IFSCHELP(nano_nextpage_msg), TOGETHER, VIEW);

Benno Schulenberg's avatar
Benno Schulenberg committed
1012
    add_to_funcs(do_first_file, (MBROWSER|MWHEREISFILE),
1013
	N_("First File"), IFSCHELP(nano_firstfile_msg), TOGETHER, VIEW);
Benno Schulenberg's avatar
Benno Schulenberg committed
1014
    add_to_funcs(do_last_file, (MBROWSER|MWHEREISFILE),
1015
	N_("Last File"), IFSCHELP(nano_lastfile_msg), BLANKAFTER, VIEW);
1016
#endif
Chris Allegretta's avatar
Chris Allegretta committed
1017

1018
1019
1020
    add_to_funcs(discard_buffer, MWRITEFILE,
	N_("Discard buffer"), IFSCHELP(nano_discard_buffer_msg), BLANKAFTER, NOVIEW);

1021
#if !defined(NANO_TINY) && !defined(DISABLE_BROWSER)
1022
    add_to_funcs(do_research, MBROWSER,
1023
	whereis_next_tag, IFSCHELP(nano_whereis_next_msg), TOGETHER, VIEW);
1024
#endif
1025
1026
1027
#ifndef DISABLE_BROWSER
    add_to_funcs(total_refresh, MBROWSER,
	refresh_tag, IFSCHELP(nano_browser_refresh_msg), BLANKAFTER, VIEW);
1028
#ifndef NANO_TINY
1029
1030
1031
1032
    add_to_funcs(do_prev_word_void, MBROWSER,
	N_("Left Column"), IFSCHELP(nano_browser_lefthand_msg), TOGETHER, VIEW);
    add_to_funcs(do_next_word_void, MBROWSER,
	N_("Right Column"), IFSCHELP(nano_browser_righthand_msg), BLANKAFTER, VIEW);
1033
#endif
1034
#endif
1035
1036
1037

#ifndef DISABLE_COLOR
    add_to_funcs(do_page_up, MLINTER,
1038
	/* TRANSLATORS: Try to keep the next two strings at most 20 characters. */
1039
	N_("Prev Lint Msg"), IFSCHELP(nano_prevlint_msg), TOGETHER, VIEW);
1040
    add_to_funcs(do_page_down, MLINTER,
1041
	N_("Next Lint Msg"), IFSCHELP(nano_nextlint_msg), TOGETHER, VIEW);
1042
1043
#endif

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

1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
    add_to_sclist(MMOST, "^G", 0, do_help_void, 0);
    add_to_sclist(MMOST, "F1", 0, do_help_void, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "^X", 0, do_exit, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "F2", 0, do_exit, 0);
    add_to_sclist(MMAIN, "^O", 0, do_writeout_void, 0);
    add_to_sclist(MMAIN, "F3", 0, do_writeout_void, 0);
    add_to_sclist(MMAIN, "^R", 0, do_insertfile_void, 0);
    add_to_sclist(MMAIN, "F5", 0, do_insertfile_void, 0);
    add_to_sclist(MMAIN, "Ins", 0, do_insertfile_void, 0);
    add_to_sclist(MMAIN|MBROWSER, "^W", 0, do_search, 0);
    add_to_sclist(MMAIN|MBROWSER, "F6", 0, do_search, 0);
    add_to_sclist(MMAIN, "^\\", 0, do_replace, 0);
    add_to_sclist(MMAIN, "M-R", 0, do_replace, 0);
    add_to_sclist(MMAIN, "F14", 0, do_replace, 0);
    add_to_sclist(MMOST, "^K", 0, do_cut_text_void, 0);
    add_to_sclist(MMOST, "F9", 0, do_cut_text_void, 0);
    add_to_sclist(MMAIN, "^U", 0, do_uncut_text, 0);
    add_to_sclist(MMAIN, "F10", 0, do_uncut_text, 0);
1064
#ifndef DISABLE_JUSTIFY
1065
1066
    add_to_sclist(MMAIN, "^J", 0, do_justify_void, 0);
    add_to_sclist(MMAIN, "F4", 0, do_justify_void, 0);
1067
#endif
1068
#ifndef DISABLE_SPELLER
1069
1070
    add_to_sclist(MMAIN, "^T", 0, do_spell, 0);
    add_to_sclist(MMAIN, "F12", 0, do_spell, 0);
1071
1072
#else
#ifndef DISABLE_COLOR
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
    add_to_sclist(MMAIN, "^T", 0, do_linter, 0);
    add_to_sclist(MMAIN, "F12", 0, do_linter, 0);
#endif
#endif
    add_to_sclist(MMAIN, "^C", 0, do_cursorpos_void, 0);
    add_to_sclist(MMAIN, "F11", 0, do_cursorpos_void, 0);
    add_to_sclist(MMAIN, "^_", 0, do_gotolinecolumn_void, 0);
    add_to_sclist(MMAIN, "M-G", 0, do_gotolinecolumn_void, 0);
    add_to_sclist(MMAIN, "F13", 0, do_gotolinecolumn_void, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "^Y", 0, do_page_up, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "F7", 0, do_page_up, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "PgUp", KEY_PPAGE, do_page_up, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "^V", 0, do_page_down, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "F8", 0, do_page_down, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "PgDn", KEY_NPAGE, do_page_down, 0);
    add_to_sclist(MMAIN|MHELP, "M-\\", 0, do_first_line, 0);
    add_to_sclist(MMAIN|MHELP, "M-|", 0, do_first_line, 0);
    add_to_sclist(MMAIN|MHELP, "M-/", 0, do_last_line, 0);
    add_to_sclist(MMAIN|MHELP, "M-?", 0, do_last_line, 0);
    add_to_sclist(MMAIN|MBROWSER, "M-W", 0, do_research, 0);
    add_to_sclist(MMAIN|MBROWSER, "F16", 0, do_research, 0);
1094
#ifndef NANO_TINY
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
    add_to_sclist(MMAIN, "M-]", 0, do_find_bracket, 0);
    add_to_sclist(MMAIN, "^^", 0, do_mark, 0);
    add_to_sclist(MMAIN, "M-A", 0, do_mark, 0);
    add_to_sclist(MMAIN, "F15", 0, do_mark, 0);
    add_to_sclist(MMAIN, "M-^", 0, do_copy_text, 0);
    add_to_sclist(MMAIN, "M-6", 0, do_copy_text, 0);
    add_to_sclist(MMAIN, "M-}", 0, do_indent_void, 0);
    add_to_sclist(MMAIN, "M-{", 0, do_unindent, 0);
    add_to_sclist(MMAIN, "M-U", 0, do_undo, 0);
    add_to_sclist(MMAIN, "M-E", 0, do_redo, 0);
1105
1106
#endif
#ifdef ENABLE_WORDCOMPLETION
1107
    add_to_sclist(MMAIN, "^]", 0, complete_a_word, 0);
1108
1109
#endif
#ifdef ENABLE_COMMENT
1110
    add_to_sclist(MMAIN, "M-3", 0, do_comment, 0);
1111
#endif
1112
1113
1114
1115
    add_to_sclist(MMOST, "^B", 0, do_left, 0);
    add_to_sclist(MMOST, "Left", KEY_LEFT, do_left, 0);
    add_to_sclist(MMOST, "^F", 0, do_right, 0);
    add_to_sclist(MMOST, "Right", KEY_RIGHT, do_right, 0);
1116
#ifdef ENABLE_UTF8
1117
    if (using_utf8()) {
1118
1119
	add_to_sclist(MMOST, "^\xE2\x86\x90", CONTROL_LEFT, do_prev_word_void, 0);
	add_to_sclist(MMOST, "^\xE2\x86\x92", CONTROL_RIGHT, do_next_word_void, 0);
1120
1121
1122
    } else
#endif
    {
1123
1124
	add_to_sclist(MMOST, "^Left", CONTROL_LEFT, do_prev_word_void, 0);
	add_to_sclist(MMOST, "^Right", CONTROL_RIGHT, do_next_word_void, 0);
1125
    }
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
    add_to_sclist(MMOST, "M-Space", 0, do_prev_word_void, 0);
    add_to_sclist(MMOST, "^Space", 0, do_next_word_void, 0);
    add_to_sclist((MMOST & ~MBROWSER), "^A", 0, do_home, 0);
    add_to_sclist((MMOST & ~MBROWSER), "Home", KEY_HOME, do_home, 0);
    add_to_sclist((MMOST & ~MBROWSER), "^E", 0, do_end, 0);
    add_to_sclist((MMOST & ~MBROWSER), "End", KEY_END, do_end, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "^P", 0, do_up_void, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "Up", KEY_UP, do_up_void, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "^N", 0, do_down_void, 0);
    add_to_sclist(MMAIN|MHELP|MBROWSER, "Down", KEY_DOWN, do_down_void, 0);
1136
#ifdef ENABLE_UTF8
1137
    if (using_utf8()) {
1138
1139
	add_to_sclist(MMAIN, "^\xE2\x86\x91", CONTROL_UP, do_prev_block, 0);
	add_to_sclist(MMAIN, "^\xE2\x86\x93", CONTROL_DOWN, do_next_block, 0);
1140
1141
1142
    } else
#endif
    {
1143
1144
	add_to_sclist(MMAIN, "^Up", CONTROL_UP, do_prev_block, 0);
	add_to_sclist(MMAIN, "^Down", CONTROL_DOWN, do_next_block, 0);
1145
    }
1146
1147
    add_to_sclist(MMAIN, "M-7", 0, do_prev_block, 0);
    add_to_sclist(MMAIN, "M-8", 0, do_next_block, 0);
1148
#ifndef DISABLE_JUSTIFY
1149
1150
1151
1152
    add_to_sclist(MMAIN, "M-(", 0, do_para_begin_void, 0);
    add_to_sclist(MMAIN, "M-9", 0, do_para_begin_void, 0);
    add_to_sclist(MMAIN, "M-)", 0, do_para_end_void, 0);
    add_to_sclist(MMAIN, "M-0", 0, do_para_end_void, 0);
Benno Schulenberg's avatar
Benno Schulenberg committed
1153
#endif
1154
#ifndef NANO_TINY
1155
1156
1157
1158
    add_to_sclist(MMAIN, "M--", 0, do_scroll_up, 0);
    add_to_sclist(MMAIN, "M-_", 0, do_scroll_up, 0);
    add_to_sclist(MMAIN, "M-+", 0, do_scroll_down, 0);
    add_to_sclist(MMAIN, "M-=", 0, do_scroll_down, 0);
1159
#endif
1160
#ifndef DISABLE_MULTIBUFFER
1161
1162
1163
1164
    add_to_sclist(MMAIN, "M-<", 0, switch_to_prev_buffer_void, 0);
    add_to_sclist(MMAIN, "M-,", 0, switch_to_prev_buffer_void, 0);
    add_to_sclist(MMAIN, "M->", 0, switch_to_next_buffer_void, 0);
    add_to_sclist(MMAIN, "M-.", 0, switch_to_next_buffer_void, 0);
1165
#endif
1166
    add_to_sclist(MMOST, "M-V", 0, do_verbatim_input, 0);
1167
#ifndef NANO_TINY
1168
1169
    add_to_sclist(MMAIN, "M-T", 0, do_cut_till_eof, 0);
    add_to_sclist(MMAIN, "M-D", 0, do_wordlinechar_count, 0);
1170
#endif
1171
#ifndef DISABLE_JUSTIFY
1172
    add_to_sclist(MMAIN|MWHEREIS, "M-J", 0, do_full_justify, 0);
1173
#endif
1174
1175
    add_to_sclist(MMAIN|MHELP, "^L", 0, total_refresh, 0);
    add_to_sclist(MMAIN, "^Z", 0, do_suspend_void, 0);
1176

1177
#ifndef NANO_TINY
1178
    /* Group of "Appearance" toggles. */
1179
1180
1181
1182
1183
    add_to_sclist(MMAIN, "M-X", 0, do_toggle_void, NO_HELP);
    add_to_sclist(MMAIN, "M-C", 0, do_toggle_void, CONST_UPDATE);
    add_to_sclist(MMAIN, "M-O", 0, do_toggle_void, MORE_SPACE);
    add_to_sclist(MMAIN, "M-S", 0, do_toggle_void, SMOOTH_SCROLL);
    add_to_sclist(MMAIN, "M-$", 0, do_toggle_void, SOFTWRAP);
1184
1185
1186
#ifdef ENABLE_LINENUMBERS
    add_to_sclist(MMAIN, "M-#", 0, do_toggle_void, LINE_NUMBERS);
#endif
1187
    add_to_sclist(MMAIN, "M-P", 0, do_toggle_void, WHITESPACE_DISPLAY);
1188
#ifndef DISABLE_COLOR
1189
    add_to_sclist(MMAIN, "M-Y", 0, do_toggle_void, NO_COLOR_SYNTAX);
1190
#endif
1191

1192
    /* Group of "Editing-behavior" toggles. */
1193
1194
1195
    add_to_sclist(MMAIN, "M-H", 0, do_toggle_void, SMART_HOME);
    add_to_sclist(MMAIN, "M-I", 0, do_toggle_void, AUTOINDENT);
    add_to_sclist(MMAIN, "M-K", 0, do_toggle_void, CUT_TO_END);
1196
#ifndef DISABLE_WRAPPING
1197
    add_to_sclist(MMAIN, "M-L", 0, do_toggle_void, NO_WRAP);
1198
#endif
1199
    add_to_sclist(MMAIN, "M-Q", 0, do_toggle_void, TABS_TO_SPACES);
1200

1201
    /* Group of "Peripheral-feature" toggles. */
1202
    add_to_sclist(MMAIN, "M-B", 0, do_toggle_void, BACKUP_FILE);
1203
#ifndef DISABLE_MULTIBUFFER
1204
    add_to_sclist(MMAIN, "M-F", 0, do_toggle_void, MULTIBUFFER);
1205
1206
#endif
#ifndef DISABLE_MOUSE
1207
    add_to_sclist(MMAIN, "M-M", 0, do_toggle_void, USE_MOUSE);
1208
#endif
1209
1210
    add_to_sclist(MMAIN, "M-N", 0, do_toggle_void, NO_CONVERT);
    add_to_sclist(MMAIN, "M-Z", 0, do_toggle_void, SUSPEND);
1211
#endif /* !NANO_TINY */
Benno Schulenberg's avatar
Benno Schulenberg committed
1212

1213
1214
    add_to_sclist(MMAIN, "^Q", 0, xon_complaint, 0);
    add_to_sclist(MMAIN, "^S", 0, xoff_complaint, 0);
1215

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

1218
1219
1220
1221
1222
1223
    add_to_sclist(MWHEREIS|MREPLACE, "M-C", 0, case_sens_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE, "M-R", 0, regexp_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE, "M-B", 0, backwards_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE, "^R", 0, flip_replace_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE, "^Y", 0, do_first_line, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MGOTOLINE, "^V", 0, do_last_line, 0);
1224
#ifndef DISABLE_JUSTIFY
1225
1226
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^W", 0, do_para_begin_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH, "^O", 0, do_para_end_void, 0);
1227
#endif
1228
1229
    add_to_sclist(MWHEREIS, "^T", 0, do_gotolinecolumn_void, 0);
    add_to_sclist(MGOTOLINE, "^T", 0, gototext_void, 0);
1230
#ifndef DISABLE_HISTORIES
1231
1232
1233
1234
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "^P", 0, get_history_older_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "Up", KEY_UP, get_history_older_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "^N", 0, get_history_newer_void, 0);
    add_to_sclist(MWHEREIS|MREPLACE|MREPLACEWITH|MWHEREISFILE, "Down", KEY_DOWN, get_history_newer_void, 0);
1235
1236
#endif
#ifndef DISABLE_BROWSER
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
    add_to_sclist(MWHEREISFILE, "^Y", 0, do_first_file, 0);
    add_to_sclist(MWHEREISFILE, "^V", 0, do_last_file, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-\\", 0, do_first_file, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-|", 0, do_first_file, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-/", 0, do_last_file, 0);
    add_to_sclist(MBROWSER|MWHEREISFILE, "M-?", 0, do_last_file, 0);
    add_to_sclist(MBROWSER, "Home", KEY_HOME, do_first_file, 0);
    add_to_sclist(MBROWSER, "End", KEY_END, do_last_file, 0);
    add_to_sclist(MBROWSER, "^_", 0, goto_dir_void, 0);
    add_to_sclist(MBROWSER, "M-G", 0, goto_dir_void, 0);
    add_to_sclist(MBROWSER, "F13", 0, goto_dir_void, 0);
    add_to_sclist(MBROWSER, "^L", 0, total_refresh, 0);
1249
#endif
1250
    if (ISSET(TEMP_FILE))
1251
1252
1253
	add_to_sclist(MWRITEFILE, "^Q", 0, discard_buffer, 0);
    add_to_sclist(MWRITEFILE, "M-D", 0, dos_format_void, 0);
    add_to_sclist(MWRITEFILE, "M-M", 0, mac_format_void, 0);
1254
1255
    if (!ISSET(RESTRICTED)) {
	/* Don't allow Appending, Prepending, nor Backups in restricted mode. */
1256
1257
1258
	add_to_sclist(MWRITEFILE, "M-A", 0, append_void, 0);
	add_to_sclist(MWRITEFILE, "M-P", 0, prepend_void, 0);
	add_to_sclist(MWRITEFILE, "M-B", 0, backup_file_void, 0);
1259
#ifndef DISABLE_BROWSER
1260
	add_to_sclist(MWRITEFILE|MINSERTFILE, "^T", 0, to_files_void, 0);
1261
#endif
1262
1263
	add_to_sclist(MINSERTFILE|MEXTCMD, "^X", 0, flip_execute_void, 0);
	add_to_sclist(MINSERTFILE|MEXTCMD, "M-F", 0, new_buffer_void, 0);
1264
    }
1265
    add_to_sclist(MHELP|MBROWSER, "^C", 0, do_exit, 0);
1266
1267
1268
    /* Allow exiting from the file browser and the help viewer with
     * the same key as they were entered. */
#ifndef DISABLE_BROWSER
1269
    add_to_sclist(MBROWSER, "^T", 0, do_exit, 0);
1270
#endif
1271
#ifndef DISABLE_HELP
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
    add_to_sclist(MHELP, "^G", 0, do_exit, 0);
    add_to_sclist(MHELP, "Home", KEY_HOME, do_first_line, 0);
    add_to_sclist(MHELP, "End", KEY_END, do_last_line, 0);
#endif
    add_to_sclist(MMOST, "^I", 0, do_tab, 0);
    add_to_sclist(MMOST, "Tab", TAB_CODE, do_tab, 0);
    add_to_sclist(MMOST, "^M", 0, do_enter, 0);
    add_to_sclist(MMOST, "Enter", KEY_ENTER, do_enter, 0);
    add_to_sclist(MMOST, "^D", 0, do_delete, 0);
    add_to_sclist(MMOST, "Del", 0, do_delete, 0);
    add_to_sclist(MMOST, "^H", 0, do_backspace, 0);
    add_to_sclist(MMOST, "Bsp", KEY_BACKSPACE, do_backspace, 0);
Chris Allegretta's avatar
Chris Allegretta committed
1284

1285
1286
#ifdef DEBUG
    print_sclist();
Chris Allegretta's avatar
Chris Allegretta committed
1287
#endif
1288
}
1289

1290
#ifndef DISABLE_COLOR
1291
void set_lint_or_format_shortcuts(void)
1292
1293
{
#ifndef DISABLE_SPELLER
1294
1295
1296
1297
1298
1299
1300
    if (openfile->syntax->formatter) {
	replace_scs_for(do_spell, do_formatter);
	replace_scs_for(do_linter, do_formatter);
    } else {
	replace_scs_for(do_spell, do_linter);
	replace_scs_for(do_formatter, do_linter);
    }
1301
1302
1303
1304
1305
1306
#endif
}

void set_spell_shortcuts(void)
{
#ifndef DISABLE_SPELLER
1307
1308
	replace_scs_for(do_formatter, do_spell);
	replace_scs_for(do_linter, do_spell);
1309
1310
#endif
}
1311
#endif /* !DISABLE_COLOR */
1312

1313
const subnfunc *sctofunc(const sc *s)
1314
{
1315
    subnfunc *f = allfuncs;
1316

1317
1318
    while (f != NULL && f->scfunc != s->scfunc)
	f = f->next;
1319

1320
    return f;
1321
1322
}

1323
#ifndef NANO_TINY
1324
1325
/* Now let's come up with a single (hopefully) function to get a string
 * for each flag. */
1326
const char *flagtostr(int flag)
1327
{
1328
    switch (flag) {
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
	case NO_HELP:
	    /* TRANSLATORS: The next seventeen strings are toggle descriptions;
	     * they are best kept shorter than 40 characters, but may be longer. */
	    return N_("Help mode");
	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 SOFTWRAP:
	    return N_("Soft wrapping of overlong lines");
	case WHITESPACE_DISPLAY:
	    return N_("Whitespace display");
	case NO_COLOR_SYNTAX:
	    return N_("Color syntax highlighting");
	case SMART_HOME:
	    return N_("Smart home key");
	case AUTOINDENT:
	    return N_("Auto indent");
	case CUT_TO_END:
	    return N_("Cut to end");
	case NO_WRAP:
	    return N_("Hard wrapping of overlong lines");
	case TABS_TO_SPACES:
	    return N_("Conversion of typed tabs to spaces");
	case BACKUP_FILE:
	    return N_("Backup files");
	case MULTIBUFFER:
1358
	    return N_("Reading file into separate buffer");
1359
1360
1361
1362
1363
1364
	case USE_MOUSE:
	    return N_("Mouse support");
	case NO_CONVERT:
	    return N_("No conversion from DOS/Mac format");
	case SUSPEND:
	    return N_("Suspension");
1365
1366
	case LINE_NUMBERS:
	    return N_("Line numbering");
1367
1368
	default:
	    return "?????";
1369
1370
    }
}
1371
#endif /* !NANO_TINY */
1372

1373
#ifndef DISABLE_NANORC
1374
/* Interpret a function string given in the rc file, and return a
1375
 * shortcut struct with the corresponding function filled in. */
1376
sc *strtosc(const char *input)
1377
{
1378
    sc *s = nmalloc(sizeof(sc));
1379

1380
#ifndef NANO_TINY
1381
    s->toggle = 0;
1382
#endif
1383

Chris Allegretta's avatar
Chris Allegretta committed
1384
#ifndef DISABLE_HELP
1385
    if (!strcasecmp(input, "help"))
1386
1387
	s->scfunc = do_help_void;
    else
Chris Allegretta's avatar
Chris Allegretta committed
1388
#endif
1389
    if (!strcasecmp(input, "cancel"))
1390
	s->scfunc = do_cancel;
1391
    else if (!strcasecmp(input, "exit"))
1392
	s->scfunc = do_exit;
1393
1394
    else if (!strcasecmp(input, "discardbuffer"))
	s->scfunc = discard_buffer;
1395
    else if (!strcasecmp(input, "writeout"))
1396
	s->scfunc = do_writeout_void;
1397
1398
1399
1400
#ifndef NANO_TINY
    else if (!strcasecmp(input, "savefile"))
	s->scfunc = do_savefile;
#endif
1401
    else if (!strcasecmp(input, "insert"))
1402
	s->scfunc = do_insertfile_void;
1403
    else if (!strcasecmp(input, "whereis"))
1404
	s->scfunc = do_search;
1405
    else if (!strcasecmp(input, "searchagain") ||
1406
	     !strcasecmp(input, "research"))  /* Deprecated.  Remove in 2018. */
1407
	s->scfunc = do_research;
1408
#ifndef NANO_TINY
1409
1410
1411
1412
    else if (!strcasecmp(input, "findprevious"))
	s->scfunc = do_findprevious;
    else if (!strcasecmp(input, "findnext"))
	s->scfunc = do_findnext;
1413
#endif
1414
1415
    else if (!strcasecmp(input, "replace"))
	s->scfunc = do_replace;
1416
    else if (!strcasecmp(input, "cut"))
1417
	s->scfunc = do_cut_text_void;
1418
    else if (!strcasecmp(input, "uncut"))
1419
	s->scfunc = do_uncut_text;
1420
#ifndef NANO_TINY
1421
    else if (!strcasecmp(input, "cutrestoffile"))
1422
	s->scfunc = do_cut_till_eof;
1423
1424
    else if (!strcasecmp(input, "copytext"))
	s->scfunc = do_copy_text;
1425
1426
    else if (!strcasecmp(input, "mark"))
	s->scfunc = do_mark;
1427
1428
#endif
#ifndef DISABLE_SPELLER
1429
1430
1431
    else if (!strcasecmp(input, "tospell") ||
	     !strcasecmp(input, "speller"))
	s->scfunc = do_spell;
1432
#endif
1433
#ifndef DISABLE_COLOR
1434
1435
    else if (!strcasecmp(input, "linter"))
	s->scfunc = do_linter;
1436
#endif
1437
    else if (!strcasecmp(input, "curpos") ||
1438
	     !strcasecmp(input, "cursorpos"))  /* Deprecated.  Remove in 2018. */
1439
	s->scfunc = do_cursorpos_void;
1440
    else if (!strcasecmp(input, "gotoline"))
1441
	s->scfunc = do_gotolinecolumn_void;
1442
#ifndef DISABLE_JUSTIFY
Chris Allegretta's avatar
Chris Allegretta committed
1443
    else if (!strcasecmp(input, "justify"))
1444
	s->scfunc = do_justify_void;
1445
1446
    else if (!strcasecmp(input, "fulljustify"))
	s->scfunc = do_full_justify;
1447
    else if (!strcasecmp(input, "beginpara"))
1448
	s->scfunc = do_para_begin_void;
1449
    else if (!strcasecmp(input, "endpara"))
1450
	s->scfunc = do_para_end_void;
1451
#endif
1452
1453
1454
1455
#ifdef ENABLE_COMMENT
    else if (!strcasecmp(input, "comment"))
	s->scfunc = do_comment;
#endif
1456
1457
1458
1459
#ifdef ENABLE_WORDCOMPLETION
    else if (!strcasecmp(input, "complete"))
	s->scfunc = complete_a_word;
#endif
1460
#ifndef NANO_TINY
1461
    else if (!strcasecmp(input, "indent"))
1462
	s->scfunc = do_indent_void;
1463
    else if (!strcasecmp(input, "unindent"))
1464
	s->scfunc = do_unindent;
Chris Allegretta's avatar
Chris Allegretta committed
1465
    else if (!strcasecmp(input, "scrollup"))
1466
	s->scfunc = do_scroll_up;
Chris Allegretta's avatar
Chris Allegretta committed
1467
    else if (!strcasecmp(input, "scrolldown"))
1468
	s->scfunc = do_scroll_down;
1469
    else if (!strcasecmp(input, "prevword"))
1470
	s->scfunc = do_prev_word_void;
1471
1472
    else if (!strcasecmp(input, "nextword"))
	s->scfunc = do_next_word_void;
1473
1474
1475
1476
    else if (!strcasecmp(input, "cutwordleft"))
	s->scfunc = do_cut_prev_word;
    else if (!strcasecmp(input, "cutwordright"))
	s->scfunc = do_cut_next_word;
1477
1478
1479
1480
    else if (!strcasecmp(input, "prevblock"))
	s->scfunc = do_prev_block;
    else if (!strcasecmp(input, "nextblock"))
	s->scfunc = do_next_block;
1481
    else if (!strcasecmp(input, "findbracket"))
1482
	s->scfunc = do_find_bracket;
1483
    else if (!strcasecmp(input, "wordcount"))
1484
	s->scfunc = do_wordlinechar_count;
1485
    else if (!strcasecmp(input, "undo"))
1486
	s->scfunc = do_undo;
1487
    else if (!strcasecmp(input, "redo"))
1488
	s->scfunc = do_redo;
1489
#endif
Chris Allegretta's avatar
Chris Allegretta committed
1490
    else if (!strcasecmp(input, "left") ||
1491
	     !strcasecmp(input, "back"))
1492
	s->scfunc = do_left;
1493
1494
1495
    else if (!strcasecmp(input, "right") ||
	     !strcasecmp(input, "forward"))
	s->scfunc = do_right;
Chris Allegretta's avatar
Chris Allegretta committed
1496
    else if (!strcasecmp(input, "up") ||
1497
	     !strcasecmp(input, "prevline"))
1498
	s->scfunc = do_up_void;
Chris Allegretta's avatar
Chris Allegretta committed
1499
    else if (!strcasecmp(input, "down") ||
1500
	     !strcasecmp(input, "nextline"))
1501
	s->scfunc = do_down_void;
Chris Allegretta's avatar
Chris Allegretta committed
1502
    else if (!strcasecmp(input, "home"))
1503
	s->scfunc = do_home;
Chris Allegretta's avatar
Chris Allegretta committed
1504
    else if (!strcasecmp(input, "end"))
1505
	s->scfunc = do_end;
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
    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;
1516
#ifndef DISABLE_MULTIBUFFER
Chris Allegretta's avatar
Chris Allegretta committed
1517
    else if (!strcasecmp(input, "prevbuf"))
1518
	s->scfunc = switch_to_prev_buffer_void;
Chris Allegretta's avatar
Chris Allegretta committed
1519
    else if (!strcasecmp(input, "nextbuf"))
1520
	s->scfunc = switch_to_next_buffer_void;
Chris Allegretta's avatar
Chris Allegretta committed
1521
1522
#endif
    else if (!strcasecmp(input, "verbatim"))
1523
	s->scfunc = do_verbatim_input;
Chris Allegretta's avatar
Chris Allegretta committed
1524
    else if (!strcasecmp(input, "tab"))
1525
	s->scfunc = do_tab;
Chris Allegretta's avatar
Chris Allegretta committed
1526
    else if (!strcasecmp(input, "enter"))
1527
	s->scfunc = do_enter;
Chris Allegretta's avatar
Chris Allegretta committed
1528
    else if (!strcasecmp(input, "delete"))
1529
	s->scfunc = do_delete;
1530
    else if (!strcasecmp(input, "backspace"))
1531
	s->scfunc = do_backspace;
Chris Allegretta's avatar
Chris Allegretta committed
1532
    else if (!strcasecmp(input, "refresh"))
1533
	s->scfunc = total_refresh;
1534
1535
    else if (!strcasecmp(input, "suspend"))
	s->scfunc = do_suspend_void;
1536
    else if (!strcasecmp(input, "casesens"))
1537
	s->scfunc = case_sens_void;
1538
    else if (!strcasecmp(input, "regexp") ||
1539
	     !strcasecmp(input, "regex"))  /* Deprecated.  Remove in 2018. */
1540
	s->scfunc = regexp_void;
1541
    else if (!strcasecmp(input, "backwards"))
1542
	s->scfunc = backwards_void;
1543
    else if (!strcasecmp(input, "flipreplace") ||
1544
	     !strcasecmp(input, "dontreplace"))  /* Deprecated.  Remove in 2018. */
1545
	s->scfunc = flip_replace_void;
1546
    else if (!strcasecmp(input, "gototext"))
1547
	s->scfunc = gototext_void;
1548
1549
1550
1551
1552
1553
1554
#ifndef DISABLE_HISTORIES
    else if (!strcasecmp(input, "prevhistory"))
	s->scfunc = get_history_older_void;
    else if (!strcasecmp(input, "nexthistory"))
	s->scfunc = get_history_newer_void;
#endif
    else if (!strcasecmp(input, "dosformat"))
1555
	s->scfunc = dos_format_void;
1556
    else if (!strcasecmp(input, "macformat"))
1557
	s->scfunc = mac_format_void;
1558
    else if (!strcasecmp(input, "append"))
1559
	s->scfunc = append_void;
1560
    else if (!strcasecmp(input, "prepend"))
1561
	s->scfunc = prepend_void;
1562
    else if (!strcasecmp(input, "backup"))
1563
	s->scfunc = backup_file_void;
1564
#ifndef ENABLE_TINY
1565
    else if (!strcasecmp(input, "flipexecute"))
1566
1567
	s->scfunc = flip_execute_void;
#endif
1568
#ifndef DISABLE_MULTIBUFFER
1569
    else if (!strcasecmp(input, "flipnewbuffer") ||
1570
	     !strcasecmp(input, "newbuffer"))  /* Deprecated.  Remove in 2018. */
1571
	s->scfunc = new_buffer_void;
Chris Allegretta's avatar
Chris Allegretta committed
1572
#endif
1573
#ifndef DISABLE_BROWSER
1574
1575
    else if (!strcasecmp(input, "tofiles") ||
	     !strcasecmp(input, "browser"))
1576
	s->scfunc = to_files_void;
1577
    else if (!strcasecmp(input, "gotodir"))
1578
	s->scfunc = goto_dir_void;
1579
    else if (!strcasecmp(input, "firstfile"))
1580
	s->scfunc = do_first_file;
1581
    else if (!strcasecmp(input, "lastfile"))
1582
1583
	s->scfunc = do_last_file;
#endif
1584
    else {
1585
#ifndef NANO_TINY
1586
	s->scfunc = do_toggle_void;
1587
	if (!strcasecmp(input, "nohelp"))
1588
	    s->toggle = NO_HELP;
1589
	else if (!strcasecmp(input, "constupdate"))
1590
	    s->toggle = CONST_UPDATE;
1591
	else if (!strcasecmp(input, "morespace"))
1592
	    s->toggle = MORE_SPACE;
1593
	else if (!strcasecmp(input, "smoothscroll"))
1594
	    s->toggle = SMOOTH_SCROLL;
1595
	else if (!strcasecmp(input, "softwrap"))
1596
	    s->toggle = SOFTWRAP;
1597
	else if (!strcasecmp(input, "whitespacedisplay"))
1598
	    s->toggle = WHITESPACE_DISPLAY;
1599
#ifndef DISABLE_COLOR
1600
	else if (!strcasecmp(input, "nosyntax"))
1601
1602
	    s->toggle = NO_COLOR_SYNTAX;
#endif
1603
	else if (!strcasecmp(input, "smarthome"))
1604
	    s->toggle = SMART_HOME;
1605
	else if (!strcasecmp(input, "autoindent"))
1606
	    s->toggle = AUTOINDENT;
1607
	else if (!strcasecmp(input, "cuttoend"))
1608
	    s->toggle = CUT_TO_END;
1609
#ifndef DISABLE_WRAPPING
1610
	else if (!strcasecmp(input, "nowrap"))
1611
	    s->toggle = NO_WRAP;
1612
#endif
1613
	else if (!strcasecmp(input, "tabstospaces"))
1614
	    s->toggle = TABS_TO_SPACES;
1615
	else if (!strcasecmp(input, "backupfile"))
1616
	    s->toggle = BACKUP_FILE;
1617
#ifndef DISABLE_MULTIBUFFER
1618
	else if (!strcasecmp(input, "multibuffer"))
1619
	    s->toggle = MULTIBUFFER;
1620
1621
#endif
#ifndef DISABLE_MOUSE
1622
	else if (!strcasecmp(input, "mouse"))
1623
	    s->toggle = USE_MOUSE;
1624
#endif
1625
	else if (!strcasecmp(input, "noconvert"))
1626
	    s->toggle = NO_CONVERT;
1627
	else if (!strcasecmp(input, "suspendenable"))
1628
	    s->toggle = SUSPEND;
1629
	else
1630
#endif /* !NANO_TINY */
1631
	{
1632
1633
1634
	    free(s);
	    return NULL;
	}
1635
1636
1637
    }
    return s;
}
1638

1639
/* Interpret a menu name and return the corresponding menu flag. */
1640
int strtomenu(const char *input)
1641
1642
{
    if (!strcasecmp(input, "all"))
1643
	return (MMOST|MHELP|MYESNO);
1644
1645
1646
1647
1648
1649
    else if (!strcasecmp(input, "main"))
	return MMAIN;
    else if (!strcasecmp(input, "search"))
	return MWHEREIS;
    else if (!strcasecmp(input, "replace"))
	return MREPLACE;
1650
    else if (!strcasecmp(input, "replace2") ||  /* Deprecated.  Remove in 2018. */
Benno Schulenberg's avatar
Benno Schulenberg committed
1651
	     !strcasecmp(input, "replacewith"))
1652
	return MREPLACEWITH;
1653
1654
1655
1656
1657
1658
1659
    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
1660
	     !strcasecmp(input, "extcmd"))
1661
	return MEXTCMD;
1662
#ifndef DISABLE_HELP
1663
1664
    else if (!strcasecmp(input, "help"))
	return MHELP;
1665
1666
#endif
#ifndef DISABLE_SPELLER
1667
    else if (!strcasecmp(input, "spell"))
1668
	return MSPELL;
1669
#endif
1670
1671
    else if (!strcasecmp(input, "linter"))
	return MLINTER;
1672
#ifndef DISABLE_BROWSER
1673
1674
1675
1676
1677
1678
    else if (!strcasecmp(input, "browser"))
	return MBROWSER;
    else if (!strcasecmp(input, "whereisfile"))
	return MWHEREISFILE;
    else if (!strcasecmp(input, "gotodir"))
	return MGOTODIR;
1679
#endif
1680
1681
    return -1;
}
1682
#endif /* !DISABLE_NANORC */
1683

Chris Allegretta's avatar
Chris Allegretta committed
1684

1685
1686
1687
#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
1688
1689
 * 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
1690
1691
 * function unless debugging is turned on. */
void thanks_for_all_the_fish(void)
1692
{
1693
1694
1695
1696
    delwin(topwin);
    delwin(edit);
    delwin(bottomwin);

1697
    free(word_chars);
Chris Allegretta's avatar
Chris Allegretta committed
1698
#ifndef DISABLE_JUSTIFY
1699
    free(quotestr);
1700
1701
#ifdef HAVE_REGEX_H
    regfree(&quotereg);
1702
    free(quoteerr);
1703
#endif
Chris Allegretta's avatar
Chris Allegretta committed
1704
#endif
1705
#ifndef NANO_TINY
1706
    free(backup_dir);
1707
#endif
Chris Allegretta's avatar
Chris Allegretta committed
1708
#ifndef DISABLE_OPERATINGDIR
1709
1710
    free(operating_dir);
    free(full_operating_dir);
1711
#endif
1712
    free(answer);
1713
    free(last_search);
1714
    free(present_path);
1715
#ifndef DISABLE_SPELLER
1716
    free(alt_speller);
1717
#endif
1718
    free_filestruct(cutbuffer);
David Lawrence Ramsey's avatar
David Lawrence Ramsey committed
1719
    /* Free the memory associated with each open file buffer. */
1720
1721
1722
1723
1724
    while (openfile != openfile->next) {
	openfile = openfile->next;
	delete_opennode(openfile->prev);
    }
    delete_opennode(openfile);
1725
#ifndef DISABLE_COLOR
1726
    free(syntaxstr);
Chris Allegretta's avatar
Chris Allegretta committed
1727
    while (syntaxes != NULL) {
1728
1729
	syntaxtype *sint = syntaxes;
	syntaxes = syntaxes->next;
Chris Allegretta's avatar
Chris Allegretta committed
1730

1731
1732
1733
	free(sint->name);
	free(sint->linter);
	free(sint->formatter);
1734

1735
1736
1737
1738
1739
	while (sint->extensions != NULL) {
	    regexlisttype *item = sint->extensions;
	    sint->extensions = sint->extensions->next;
	    free(item->full_regex);
	    free(item);
Chris Allegretta's avatar
Chris Allegretta committed
1740
	}
1741
1742
1743
1744
1745
	while (sint->headers != NULL) {
	    regexlisttype *item = sint->headers;
	    sint->headers = sint->headers->next;
	    free(item->full_regex);
	    free(item);
1746
	}
1747
1748
1749
1750
1751
	while (sint->magics != NULL) {
	    regexlisttype *item = sint->magics;
	    sint->magics = sint->magics->next;
	    free(item->full_regex);
	    free(item);
1752
	}
1753

1754
1755
1756
1757
1758
1759
1760
	while (sint->color != NULL) {
	    colortype *ink = sint->color;
	    sint->color = sint->color->next;
	    free(ink->start_regex);
	    if (ink->start != NULL) {
		regfree(ink->start);
		free(ink->start);
1761
	    }
1762
1763
1764
1765
	    free(ink->end_regex);
	    if (ink->end != NULL) {
		regfree(ink->end);
		free(ink->end);
1766
	    }
1767
	    free(ink);
Chris Allegretta's avatar
Chris Allegretta committed
1768
	}
1769
1770

	free(sint);
Chris Allegretta's avatar
Chris Allegretta committed
1771
    }
1772
#endif /* !DISABLE_COLOR */
1773
#ifndef DISABLE_HISTORIES
1774
    /* Free the search and replace history lists. */
1775
1776
    free_filestruct(searchage);
    free_filestruct(replaceage);
1777
#endif
1778
    /* Free the list of functions. */
1779
    while (allfuncs != NULL) {
1780
1781
1782
	subnfunc *f = allfuncs;
	allfuncs = allfuncs->next;
	free(f);
1783
    }
1784
    /* Free the list of shortcuts. */
1785
    while (sclist != NULL) {
1786
1787
1788
	sc *s = sclist;
	sclist = sclist->next;
	free(s);
1789
    }
1790
#ifndef DISABLE_NANORC
1791
    free(homedir);
1792
#endif
1793
}
1794
#endif /* DEBUG */