From 79a33bb38d7ec6fd753761b4370f216dc6fcd24d Mon Sep 17 00:00:00 2001 From: Chris Allegretta Date: Wed, 5 Mar 2008 07:34:01 +0000 Subject: [PATCH] New keybindings code and backend. New structs subnfunc for menu functions and toggles and sc for shortcut keys, old 'shortcut' and 'toggles' structs are gone. The current implementation has a bunch of broken stuff (some of which is documented in BUGS). Updated nanorc.5 with some mostly complete documentation on configuring. git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4215 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- src/browser.c | 20 +- src/files.c | 8 +- src/global.c | 1738 +++++++++++++++++++++++++------------------------ src/help.c | 224 +++---- src/nano.c | 122 ++-- src/nano.h | 65 ++ src/prompt.c | 39 +- src/proto.h | 62 +- src/rcfile.c | 91 +++ src/search.c | 35 +- src/text.c | 4 +- src/winio.c | 316 +++++---- 12 files changed, 1418 insertions(+), 1306 deletions(-) diff --git a/src/browser.c b/src/browser.c index d7be9744..37d904c4 100644 --- a/src/browser.c +++ b/src/browser.c @@ -64,9 +64,9 @@ char *do_browser(char *path, DIR *dir) curs_set(0); blank_statusbar(); #if !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE) - currshortcut = browser_list; + currmenu = MBROWSER; #endif - bottombars(browser_list); + bottombars(MBROWSER); wnoutrefresh(bottomwin); UNSET(CONST_UPDATE); @@ -213,17 +213,17 @@ char *do_browser(char *path, DIR *dir) #ifndef DISABLE_TABCOMP FALSE, #endif - gotodir_list, ans, + MGOTODIR, ans, #ifndef NANO_TINY NULL, #endif - browser_refresh, _("Go To Directory")); + browser_refresh, N_("Go To Directory")); curs_set(0); #if !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE) - currshortcut = browser_list; + currmenu = MBROWSER; #endif - bottombars(browser_list); + bottombars(MBROWSER); /* If the directory begins with a newline (i.e. an * encoded null), treat it as though it's blank. */ @@ -552,7 +552,7 @@ void browser_init(const char *path, DIR *dir) * shortcut keys. */ void parse_browser_input(int *kbinput, bool *meta_key, bool *func_key) { - get_shortcut(browser_list, kbinput, meta_key, func_key); + get_shortcut(MBROWSER, kbinput, meta_key, func_key); /* Pico compatibility. */ if (!*meta_key) { @@ -796,7 +796,7 @@ int filesearch_init(void) #ifndef DISABLE_TABCOMP TRUE, #endif - whereis_file_list, backupstring, + MWHEREISFILE, backupstring, #ifndef NANO_TINY &search_history, #endif @@ -955,8 +955,8 @@ void findnextfile_wrap_reset(void) * search, if any. */ void filesearch_abort(void) { - currshortcut = browser_list; - bottombars(browser_list); + currmenu = MBROWSER; + bottombars(MBROWSER); #ifdef HAVE_REGEX_H regexp_cleanup(); #endif diff --git a/src/files.c b/src/files.c index a74054d2..77973700 100644 --- a/src/files.c +++ b/src/files.c @@ -731,9 +731,9 @@ void do_insertfile( TRUE, #endif #ifndef NANO_TINY - execute ? extcmd_list : + execute ? MEXTCMD : #endif - insertfile_list, ans, + MINSERTFILE, ans, #ifndef NANO_TINY NULL, #endif @@ -1814,7 +1814,7 @@ bool do_writeout(bool exiting) #endif bool retval = FALSE; - currshortcut = writefile_list; + currmenu = MWRITEFILE; if (exiting && openfile->filename[0] != '\0' && ISSET(TEMP_FILE)) { retval = write_file(openfile->filename, NULL, FALSE, OVERWRITE, @@ -1865,7 +1865,7 @@ bool do_writeout(bool exiting) #ifndef DISABLE_TABCOMP TRUE, #endif - writefile_list, ans, + MWRITEFILE, ans, #ifndef NANO_TINY NULL, #endif diff --git a/src/global.c b/src/global.c index f4c82776..e33fde0d 100644 --- a/src/global.c +++ b/src/global.c @@ -1,4 +1,5 @@ -/* $Id$ */ +/* $Id$ +*/ /************************************************************************** * global.c * * * @@ -21,6 +22,9 @@ * * **************************************************************************/ +#include +#include +#include "assert.h" #include "proto.h" /* Global variables. */ @@ -133,41 +137,6 @@ char *alt_speller = NULL; /* The command to use for the alternate spell checker. */ #endif -shortcut *main_list = NULL; - /* The main shortcut list. */ -shortcut *whereis_list = NULL; - /* The "Search" shortcut list. */ -shortcut *replace_list = NULL; - /* The "Search (to replace)" shortcut list. */ -shortcut *replace_list_2 = NULL; - /* The "Replace with" shortcut list. */ -shortcut *gotoline_list = NULL; - /* The "Enter line number, column number" shortcut list. */ -shortcut *writefile_list = NULL; - /* The "File Name to Write" shortcut list. */ -shortcut *insertfile_list = NULL; - /* The "File to insert" shortcut list. */ -#ifndef NANO_TINY -shortcut *extcmd_list = NULL; - /* The "Command to execute" shortcut list. */ -#endif -#ifndef DISABLE_HELP -shortcut *help_list = NULL; - /* The help text shortcut list. */ -#endif -#ifndef DISABLE_SPELLER -shortcut *spell_list = NULL; - /* The internal spell checker shortcut list. */ -#endif -#ifndef DISABLE_BROWSER -shortcut *browser_list = NULL; - /* The file browser shortcut list. */ -shortcut *whereis_file_list = NULL; - /* The file browser "Search" shortcut list. */ -shortcut *gotodir_list = NULL; - /* The "Go To Directory" shortcut list. */ -#endif - #ifdef ENABLE_COLOR syntaxtype *syntaxes = NULL; /* The global list of color syntaxes. */ @@ -177,11 +146,19 @@ char *syntaxstr = NULL; const shortcut *currshortcut; /* The current shortcut list we're using. */ +int currmenu; + /* The currently loaded menu */ + #ifndef NANO_TINY toggle *toggles = NULL; /* The global toggle list. */ #endif +sc *sclist = NULL; + /* New shortcut key struct */ +subnfunc *allfuncs = NULL; + /* New struct for the function list */ + #ifndef NANO_TINY filestruct *search_history = NULL; /* The search string history list. */ @@ -212,66 +189,255 @@ int reverse_attr = A_REVERSE; char *homedir = NULL; /* The user's home directory, from $HOME or /etc/passwd. */ -/* Return the number of entries in the shortcut list s. */ -size_t length_of_list(const shortcut *s) +/* Return the number of entries in the shortcut list s for a given menu. */ +size_t length_of_list(int menu) { + subnfunc *f; size_t i = 0; - for (; s != NULL; s = s->next) - i++; + for (f = allfuncs; f != NULL; f = f->next) + if ((f->menus & menu) != 0) { + i++; + } return i; } -/* Add a new shortcut to the end of the shortcut list. */ -void sc_init_one(shortcut **shortcutage, int ctrlval, const char *desc -#ifndef DISABLE_HELP - , const char *help, bool blank_after -#endif - , int metaval, int funcval, int miscval, bool view, - void (*func)(void)) +/* Set type of function based on the string */ +function_type strtokeytype(char *str) { - shortcut *s; - - if (*shortcutage == NULL) { - *shortcutage = (shortcut *)nmalloc(sizeof(shortcut)); - s = *shortcutage; + if (str[0] == 'M' || str[0] == 'm') { + return META; + } else if (str[0] == '^') { + return CONTROL; + } else if (str[0] == 'M' || str[0] == 'm') { + return FKEY; } else { - for (s = *shortcutage; s->next != NULL; s = s->next) - ; - s->next = (shortcut *)nmalloc(sizeof(shortcut)); - s = s->next; + return RAW; + } +} + +/* Add a string to the new function list strict. + Does not allow updates, yet anyway */ +void add_to_funcs(void *func, int menus, const char *desc, const char *help, + bool blank_after, bool viewok) +{ + subnfunc *f; + + if (allfuncs == NULL) { + allfuncs = nmalloc(sizeof(subnfunc)); + f = allfuncs; + } else { + for (f = allfuncs; f->next != NULL; f = f->next) + ; + f->next = (subnfunc *)nmalloc(sizeof(subnfunc)); + f = f->next; + } + f->next = NULL; + f->scfunc = func; + f->menus = menus; + f->desc = desc; + f->viewok = viewok; +#ifndef NANO_TINY + f->help = help; + f->blank_after = blank_after; +#endif + +#ifdef DEBUG + fprintf(stderr, "Added func \"%s\"", f->desc); +#endif +} + +const sc *first_sc_for(int menu, void *func) { + const sc *s; + + for (s = sclist; s != NULL; s = s->next) { + if ((s->menu & menu) && s->scfunc == func) { + return s; + } } - s->ctrlval = ctrlval; - s->desc = (desc == NULL) ? "" : _(desc); -#ifndef DISABLE_HELP - s->help = (help == NULL) ? "" : _(help); - s->blank_after = blank_after; +#ifdef DEBUG + fprintf(stderr, "Whoops, returning null given func %ld\n", (long) func); #endif - s->metaval = metaval; - s->funcval = funcval; - s->miscval = miscval; - s->viewok = view; - s->func = func; - s->next = NULL; + /* Otherwise... */ + return NULL; } + +/* Add a string to the new shortcut list implementation + Allows updates to existing entries in the list */ +void add_to_sclist(int menu, char *scstring, void *func, int toggle, int execute) +{ + sc *s; + + if (sclist == NULL) { + sclist = nmalloc(sizeof(sc)); + s = sclist; + s->next = NULL; + } else { + 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; + } + } + + s->type = strtokeytype(scstring); + s->menu = menu; + s->toggle = toggle; + s->keystr = scstring; + s->scfunc = func; + s->execute = execute; + assign_keyinfo(s); + +#ifdef DEBUG + fprintf(stderr, "list val = %d\n", (int) s->menu); + fprintf(stderr, "Hey, set sequence to %d for shortcut \"%s\"\n", s->seq, scstring); +#endif +} + +/* Assign the info to the shortcut struct + Assumes keystr is already assigned, naturally */ +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]); + } else /* raw */ + s->seq = (int) s->keystr[0]; +} + +#ifdef DEBUG + +void print_sclist(void) +{ + sc *s; + const subnfunc *f; + + for (s = sclist; s->next != NULL; s = s->next) { + f = sctofunc(s); + if (f) + fprintf(stderr, "Shortcut \"%s\", function: %s\n", s->keystr, f->desc); + else + fprintf(stderr, "Hmm, didnt find a func for \"%s\"\n", s->keystr); + } + +} +#endif + + +/* Stuff we need to make at least static here so we can access it below */ +const char *cancel_msg = N_("Cancel"); + +#ifndef NANO_TINY +const char *case_sens_msg = N_("Case Sens"); +const char *backwards_msg = N_("Backwards"); +#endif + +#ifdef HAVE_REGEX_H +const char *regexp_msg = N_("Regexp"); +#endif + +/* Stuff we want to just stun out if we're in TINY mode */ +#ifdef NANO_TINY +const char *nano_cancel_msg = ""; +const char *nano_exit_msg = ""; +const char *nano_writeout_msg = ""; +const char *nano_insert_msg = ""; +const char *nano_whereis_msg = ""; +const char *nano_prevpage_msg = ""; +const char *nano_nextpage_msg = ""; +const char *nano_cut_msg = ""; +const char *nano_uncut_msg = ""; +const char *nano_cursorpos_msg = ""; +const char *nano_lastline_msg = ""; +const char *nano_gotoline_msg = ""; +const char *nano_replace_msg = ""; +const char *nano_forward_msg = ""; +const char *nano_back_msg = ""; +const char *nano_prevline_msg = ""; +const char *nano_nextline_msg = ""; +const char *nano_home_msg = ""; +const char *nano_end_msg = ""; +const char *nano_verbatim_msg = ""; +const char *nano_tab_msg = ""; +const char *nano_enter_msg = ""; +const char *nano_delete_msg = ""; +const char *nano_backspace_msg = ""; +const char *nano_regexp_msg = ""; +const char *gototext_msg = ""; +const char *do_para_begin_void = ""; +const char *do_para_end_void = ""; +const char *case_sens_msg = ""; +const char *backwards_msg = ""; +const char *do_cut_till_end = ""; +const char *dos_format_msg = ""; +const char *mac_format_msg = ""; +const char *append_msg = ""; +const char *prepend_msg = ""; +const char *backup_file_msg = ""; +const char *to_files_msg = ""; +#else /* NANO_TINY */ +const char *prev_history_msg = N_("PrevHstory"); +/* TRANSLATORS: Try to keep this and previous strings at most 10 + * characters. */ +const char *next_history_msg = N_("NextHstory"); +const char *replace_msg = N_("Replace"); +const char *no_replace_msg = N_("No Replace"); +const char *go_to_line_msg = N_("Go To Line"); +const char *gototext_msg = N_("Go To Text"); +#ifndef DISABLE_BROWSER +/* TRANSLATORS: Try to keep this at most 16 characters. */ +const char *to_files_msg = N_("To Files"); +/* TRANSLATORS: Try to keep this at most 12 characters. */ +const char *first_file_msg = N_("First File"); +/* TRANSLATORS: Try to keep this at most 12 characters. */ +const char *last_file_msg = N_("Last File"); +#endif +/* TRANSLATORS: Try to keep this at most 16 characters. */ +const char *dos_format_msg = N_("DOS Format"); +/* TRANSLATORS: Try to keep this at most 16 characters. */ +const char *mac_format_msg = N_("Mac Format"); +/* TRANSLATORS: Try to keep this at most 16 characters. */ +const char *append_msg = N_("Append"); +/* TRANSLATORS: Try to keep this at most 16 characters. */ +const char *prepend_msg = N_("Prepend"); +/* TRANSLATORS: Try to keep this at most 16 characters. */ +const char *backup_file_msg = N_("Backup File"); + +#ifdef ENABLE_MULTIBUFFER +/* TRANSLATORS: Try to keep this at most 16 characters. */ +const char *new_buffer_msg = N_("New Buffer"); +#endif + +#endif + /* Initialize all shortcut lists. If unjustify is TRUE, replace the * Uncut shortcut in the main shortcut list with UnJustify. */ void shortcut_init(bool unjustify) { /* TRANSLATORS: Try to keep this and following strings at most 10 * characters. */ - const char *cancel_msg = N_("Cancel"); const char *get_help_msg = N_("Get Help"); const char *exit_msg = N_("Exit"); const char *whereis_msg = N_("Where Is"); const char *prev_page_msg = N_("Prev Page"); const char *next_page_msg = N_("Next Page"); - const char *go_to_line_msg = N_("Go To Line"); - /* TRANSLATORS: Try to keep this and previous strings at most 10 - * characters. */ - const char *replace_msg = N_("Replace"); + /* TRANSLATORS: Try to keep this string at most 10 characters. */ + #ifndef NANO_TINY /* TRANSLATORS: Try to keep this at most 12 characters. */ const char *whereis_next_msg = N_("WhereIs Next"); @@ -286,31 +452,10 @@ void shortcut_init(bool unjustify) const char *fulljstify_msg = N_("FullJstify"); #endif const char *refresh_msg = N_("Refresh"); -#ifndef NANO_TINY - const char *case_sens_msg = N_("Case Sens"); - const char *backwards_msg = N_("Backwards"); -#endif -#ifdef HAVE_REGEX_H - const char *regexp_msg = N_("Regexp"); -#endif -#ifndef NANO_TINY - const char *prev_history_msg = N_("PrevHstory"); - /* TRANSLATORS: Try to keep this and previous strings at most 10 - * characters. */ - const char *next_history_msg = N_("NextHstory"); -#ifdef ENABLE_MULTIBUFFER - /* TRANSLATORS: Try to keep this at most 16 characters. */ - const char *new_buffer_msg = N_("New Buffer"); -#endif -#endif -#ifndef DISABLE_BROWSER - /* TRANSLATORS: Try to keep this at most 16 characters. */ - const char *to_files_msg = N_("To Files"); - /* TRANSLATORS: Try to keep this at most 12 characters. */ - const char *first_file_msg = N_("First File"); - /* TRANSLATORS: Try to keep this at most 12 characters. */ - const char *last_file_msg = N_("Last File"); -#endif + const char *insert_file_msg = N_("Insert File"); + const char *goto_dir_msg = N_("Go To Dir"); + const char *ext_cmd_msg = N_("Execute Command"); + #ifndef DISABLE_HELP const char *nano_cancel_msg = N_("Cancel the current function"); const char *nano_help_msg = N_("Display this help text"); @@ -338,9 +483,9 @@ void shortcut_init(bool unjustify) N_("Display the position of the cursor"); const char *nano_spell_msg = N_("Invoke the spell checker, if available"); - const char *nano_gotoline_msg = N_("Go to line and column number"); const char *nano_replace_msg = N_("Replace a string or a regular expression"); + const char *nano_gotoline_msg = N_("Go to line and column number"); #ifndef NANO_TINY const char *nano_mark_msg = N_("Mark text at the cursor position"); const char *nano_whereis_next_msg = N_("Repeat last search"); @@ -446,53 +591,49 @@ void shortcut_init(bool unjustify) const char *nano_lastfile_msg = N_("Go to the last file in the list"); const char *nano_gotodir_msg = N_("Go to directory"); + #endif #endif /* !DISABLE_HELP */ -/* The following macro is to be used in calling sc_init_one(). The - * point is that sc_init_one() takes 10 arguments, unless DISABLE_HELP - * is defined, when the 4th and 5th ones should not be there. */ #ifndef DISABLE_HELP #define IFSCHELP(help, blank, nextvar) help, blank, nextvar #else #define IFSCHELP(help, blank, nextvar) nextvar #endif - free_shortcutage(&main_list); + while (allfuncs != NULL) { + subnfunc *f = allfuncs; + allfuncs = (allfuncs)->next; + free(f); + } - sc_init_one(&main_list, NANO_HELP_KEY, get_help_msg, - IFSCHELP(nano_help_msg, FALSE, NANO_NO_KEY), NANO_HELP_FKEY, - NANO_NO_KEY, VIEW, #ifndef DISABLE_HELP - do_help_void -#else - nano_disabled_msg + add_to_funcs(do_help_void, MALL, get_help_msg, nano_help_msg, + FALSE, VIEW); #endif - ); - sc_init_one(&main_list, NANO_EXIT_KEY, + add_to_funcs((void *) cancel_msg, + (MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE|MWRITEFILE|MINSERTFILE|MEXTCMD|MSPELL|MWHEREISFILE|MGOTODIR), + cancel_msg, nano_cancel_msg, FALSE, VIEW); + + add_to_funcs(do_exit, MMAIN, #ifdef ENABLE_MULTIBUFFER /* TRANSLATORS: Try to keep this at most 10 characters. */ openfile != NULL && openfile != openfile->next ? N_("Close") : #endif - exit_msg, IFSCHELP(nano_exit_msg, FALSE, NANO_NO_KEY), - NANO_EXIT_FKEY, NANO_NO_KEY, VIEW, do_exit); + exit_msg, nano_exit_msg, FALSE, VIEW); + + add_to_funcs(do_exit, MBROWSER|MHELP, exit_msg, nano_exit_msg, FALSE, VIEW); /* TRANSLATORS: Try to keep this at most 10 characters. */ - sc_init_one(&main_list, NANO_WRITEOUT_KEY, N_("WriteOut"), - IFSCHELP(nano_writeout_msg, FALSE, NANO_NO_KEY), - NANO_WRITEOUT_FKEY, NANO_NO_KEY, NOVIEW, do_writeout_void); + add_to_funcs(do_writeout_void, MMAIN, N_("WriteOut"), + nano_writeout_msg, FALSE, NOVIEW); - /* TRANSLATORS: Try to keep this at most 10 characters. */ - sc_init_one(&main_list, NANO_JUSTIFY_KEY, N_("Justify"), - IFSCHELP(nano_justify_msg, TRUE, NANO_NO_KEY), - NANO_JUSTIFY_FKEY, NANO_NO_KEY, NOVIEW, #ifndef DISABLE_JUSTIFY - do_justify_void -#else - nano_disabled_msg + /* TRANSLATORS: Try to keep this at most 10 characters. */ + add_to_funcs(do_justify_void, MMAIN, N_("Justify"), + nano_justify_msg, TRUE, NOVIEW); #endif - ); /* We allow inserting files in view mode if multibuffers are * available, so that we can view multiple files. If we're using @@ -500,442 +641,222 @@ void shortcut_init(bool unjustify) * reading from or writing to files not specified on the command * line. */ /* TRANSLATORS: Try to keep this at most 10 characters. */ - sc_init_one(&main_list, NANO_INSERTFILE_KEY, N_("Read File"), - IFSCHELP(nano_insert_msg, FALSE, NANO_NO_KEY), - NANO_INSERTFILE_FKEY, NANO_NO_KEY, + add_to_funcs(!ISSET(RESTRICTED) ? do_insertfile_void : nano_disabled_msg, + MMAIN, N_("Read File"), nano_insert_msg, FALSE, #ifdef ENABLE_MULTIBUFFER - VIEW + VIEW); #else - NOVIEW + NOVIEW); #endif - , !ISSET(RESTRICTED) ? do_insertfile_void : nano_disabled_msg); - sc_init_one(&main_list, NANO_WHEREIS_KEY, whereis_msg, - IFSCHELP(nano_whereis_msg, FALSE, NANO_NO_KEY), - NANO_WHEREIS_FKEY, NANO_NO_KEY, VIEW, do_search); + add_to_funcs(do_search, MMAIN, whereis_msg, + nano_whereis_msg, FALSE, VIEW); - sc_init_one(&main_list, NANO_PREVPAGE_KEY, prev_page_msg, - IFSCHELP(nano_prevpage_msg, FALSE, NANO_NO_KEY), - NANO_PREVPAGE_FKEY, NANO_NO_KEY, VIEW, do_page_up); - - sc_init_one(&main_list, NANO_NEXTPAGE_KEY, next_page_msg, - IFSCHELP(nano_nextpage_msg, TRUE, NANO_NO_KEY), - NANO_NEXTPAGE_FKEY, NANO_NO_KEY, VIEW, do_page_down); + add_to_funcs(do_page_up, (MMAIN|MHELP|MBROWSER), + prev_page_msg, nano_prevpage_msg, FALSE, VIEW); + add_to_funcs(do_page_down, (MMAIN|MHELP|MBROWSER), + next_page_msg, nano_nextpage_msg, TRUE, VIEW); /* TRANSLATORS: Try to keep this at most 10 characters. */ - sc_init_one(&main_list, NANO_CUT_KEY, N_("Cut Text"), - IFSCHELP(nano_cut_msg, FALSE, NANO_NO_KEY), NANO_CUT_FKEY, - NANO_NO_KEY, NOVIEW, do_cut_text_void); + add_to_funcs(do_cut_text_void, MMAIN, N_("Cut Text"), nano_cut_msg, + FALSE, NOVIEW); if (unjustify) /* TRANSLATORS: Try to keep this at most 10 characters. */ - sc_init_one(&main_list, NANO_UNJUSTIFY_KEY, N_("UnJustify"), - IFSCHELP(NULL, FALSE, NANO_NO_KEY), NANO_UNJUSTIFY_FKEY, - NANO_NO_KEY, NOVIEW, NULL); + add_to_funcs(do_uncut_text, MMAIN, N_("UnJustify"), "", + FALSE, NOVIEW); + else /* TRANSLATORS: Try to keep this at most 10 characters. */ - sc_init_one(&main_list, NANO_UNCUT_KEY, N_("UnCut Text"), - IFSCHELP(nano_uncut_msg, FALSE, NANO_NO_KEY), - NANO_UNCUT_FKEY, NANO_NO_KEY, NOVIEW, do_uncut_text); + add_to_funcs(do_uncut_text, MMAIN, N_("UnCut Text"), nano_uncut_msg, + FALSE, NOVIEW); /* TRANSLATORS: Try to keep this at most 10 characters. */ - sc_init_one(&main_list, NANO_CURSORPOS_KEY, N_("Cur Pos"), - IFSCHELP(nano_cursorpos_msg, FALSE, NANO_NO_KEY), - NANO_CURSORPOS_FKEY, NANO_NO_KEY, VIEW, do_cursorpos_void); + add_to_funcs(do_cursorpos_void, MMAIN, N_("Cur Pos"), nano_cursorpos_msg, + FALSE, VIEW); /* 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. */ /* TRANSLATORS: Try to keep this at most 10 characters. */ - sc_init_one(&main_list, NANO_SPELL_KEY, N_("To Spell"), - IFSCHELP(nano_spell_msg, TRUE, NANO_NO_KEY), NANO_SPELL_FKEY, - NANO_NO_KEY, NOVIEW, #ifndef DISABLE_SPELLER - !ISSET(RESTRICTED) ? do_spell : + if (!ISSET(RESTRICTED)) + add_to_funcs(do_spell, MMAIN, N_("To Spell"), nano_spell_msg, + TRUE, NOVIEW); #endif - nano_disabled_msg); - sc_init_one(&main_list, NANO_GOTOLINE_KEY, go_to_line_msg, - IFSCHELP(nano_gotoline_msg, FALSE, NANO_GOTOLINE_METAKEY), - NANO_GOTOLINE_FKEY, NANO_NO_KEY, VIEW, - do_gotolinecolumn_void); + add_to_funcs(do_first_line, + (MMAIN|MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE|MHELP), + first_line_msg, first_line_msg, FALSE, VIEW); + + add_to_funcs(do_last_line, + (MMAIN|MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE|MHELP), + last_line_msg, nano_lastline_msg, TRUE, VIEW); + + + add_to_funcs(do_gotolinecolumn_void, (MMAIN|MWHEREIS), + go_to_line_msg, nano_gotoline_msg, FALSE, VIEW); + + add_to_funcs(do_replace, (MMAIN|MWHEREIS), replace_msg, nano_replace_msg, - sc_init_one(&main_list, NANO_REPLACE_KEY, replace_msg #ifndef NANO_TINY - , IFSCHELP(nano_replace_msg, FALSE, NANO_REPLACE_METAKEY) + FALSE, #else - , IFSCHELP(nano_replace_msg, TRUE, NANO_REPLACE_METAKEY) + TRUE, #endif - , NANO_REPLACE_FKEY, NANO_NO_KEY, NOVIEW, do_replace); + NOVIEW); #ifndef NANO_TINY - sc_init_one(&main_list, NANO_MARK_KEY, N_("Mark Text"), - IFSCHELP(nano_mark_msg, FALSE, NANO_MARK_METAKEY), - NANO_MARK_FKEY, NANO_NO_KEY, VIEW, do_mark); - sc_init_one(&main_list, NANO_NO_KEY, whereis_next_msg, - IFSCHELP(nano_whereis_next_msg, TRUE, NANO_WHEREIS_NEXT_KEY), - NANO_WHEREIS_NEXT_FKEY, NANO_NO_KEY, VIEW, do_research); + add_to_funcs(do_mark, MMAIN, N_("Mark Text"), + nano_mark_msg, FALSE, VIEW); - sc_init_one(&main_list, NANO_NO_KEY, N_("Copy Text"), - IFSCHELP(nano_copy_msg, FALSE, NANO_COPY_KEY), NANO_NO_KEY, - NANO_COPY_METAKEY, NOVIEW, do_copy_text); + add_to_funcs(do_research, (MMAIN|MBROWSER), whereis_next_msg, + nano_whereis_next_msg, TRUE, VIEW); - sc_init_one(&main_list, NANO_NO_KEY, N_("Indent Text"), - IFSCHELP(nano_indent_msg, FALSE, NANO_INDENT_KEY), NANO_NO_KEY, - NANO_NO_KEY, NOVIEW, do_indent_void); + add_to_funcs(do_copy_text, MMAIN, N_("Copy Text"), + nano_copy_msg, FALSE, NOVIEW); + + add_to_funcs(do_indent_void, MMAIN, N_("Indent Text"), + nano_indent_msg, FALSE, NOVIEW); + + add_to_funcs(do_unindent, MMAIN, N_("Unindent Text"), + nano_unindent_msg, TRUE, NOVIEW); - sc_init_one(&main_list, NANO_NO_KEY, N_("Unindent Text"), - IFSCHELP(nano_unindent_msg, TRUE, NANO_UNINDENT_KEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, do_unindent); #endif - sc_init_one(&main_list, NANO_FORWARD_KEY, N_("Forward"), - IFSCHELP(nano_forward_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, do_right); - sc_init_one(&main_list, NANO_BACK_KEY, N_("Back"), - IFSCHELP(nano_back_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, do_left); + add_to_funcs(do_right, MMAIN, N_("Forward"), nano_forward_msg, + FALSE, VIEW); + + add_to_funcs(do_left, MMAIN, N_("Back"), nano_back_msg, + FALSE, VIEW); #ifndef NANO_TINY - sc_init_one(&main_list, NANO_NEXTWORD_KEY, N_("Next Word"), - IFSCHELP(nano_nextword_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, do_next_word_void); + add_to_funcs(do_next_word_void, MMAIN, N_("Next Word"), + nano_nextword_msg, FALSE, VIEW); - sc_init_one(&main_list, NANO_NO_KEY, N_("Prev Word"), - IFSCHELP(nano_prevword_msg, FALSE, NANO_PREVWORD_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, do_prev_word_void); + add_to_funcs(do_prev_word_void, MMAIN, N_("Prev Word"), + nano_prevword_msg, FALSE, VIEW); #endif - sc_init_one(&main_list, NANO_PREVLINE_KEY, N_("Prev Line"), - IFSCHELP(nano_prevline_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, do_up_void); + add_to_funcs(do_up_void, (MMAIN|MHELP), N_("Prev Line"), + nano_prevline_msg, FALSE, VIEW); - sc_init_one(&main_list, NANO_NEXTLINE_KEY, N_("Next Line"), - IFSCHELP(nano_nextline_msg, TRUE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, do_down_void); + add_to_funcs(do_down_void, (MMAIN|MHELP), N_("Next Line"), + nano_nextline_msg, TRUE, VIEW); - sc_init_one(&main_list, NANO_HOME_KEY, N_("Home"), - IFSCHELP(nano_home_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, do_home); + add_to_funcs(do_home, MMAIN, N_("Home"), nano_home_msg, + FALSE, VIEW); - sc_init_one(&main_list, NANO_END_KEY, N_("End"), - IFSCHELP(nano_end_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, do_end); + add_to_funcs(do_end, MMAIN, N_("End"), nano_end_msg, + FALSE, VIEW); #ifndef DISABLE_JUSTIFY - sc_init_one(&main_list, NANO_NO_KEY, beg_of_par_msg, - IFSCHELP(nano_parabegin_msg, FALSE, NANO_PARABEGIN_METAKEY), - NANO_NO_KEY, NANO_PARABEGIN_METAKEY2, VIEW, do_para_begin_void); + add_to_funcs(do_para_begin_void, (MMAIN|MWHEREIS), beg_of_par_msg, + nano_parabegin_msg, FALSE, VIEW); - sc_init_one(&main_list, NANO_NO_KEY, end_of_par_msg, - IFSCHELP(nano_paraend_msg, FALSE, NANO_PARAEND_METAKEY), - NANO_NO_KEY, NANO_PARAEND_METAKEY2, VIEW, do_para_end_void); + add_to_funcs(do_para_end_void, (MMAIN|MWHEREIS), end_of_par_msg, + nano_paraend_msg, FALSE, VIEW); #endif - sc_init_one(&main_list, NANO_NO_KEY, first_line_msg, - IFSCHELP(nano_firstline_msg, FALSE, NANO_FIRSTLINE_METAKEY), - NANO_NO_KEY, NANO_FIRSTLINE_METAKEY2, VIEW, do_first_line); - - sc_init_one(&main_list, NANO_NO_KEY, last_line_msg, - IFSCHELP(nano_lastline_msg, TRUE, NANO_LASTLINE_METAKEY), - NANO_NO_KEY, NANO_LASTLINE_METAKEY2, VIEW, do_last_line); - #ifndef NANO_TINY - sc_init_one(&main_list, NANO_NO_KEY, N_("Find Other Bracket"), - IFSCHELP(nano_bracket_msg, FALSE, NANO_BRACKET_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, do_find_bracket); + add_to_funcs(do_find_bracket, MMAIN, _("Find Other Bracket"), + nano_bracket_msg, FALSE, VIEW); - sc_init_one(&main_list, NANO_NO_KEY, N_("Scroll Up"), - IFSCHELP(nano_scrollup_msg, FALSE, NANO_SCROLLUP_KEY), - NANO_NO_KEY, NANO_SCROLLUP_METAKEY, VIEW, do_scroll_up); + add_to_funcs(do_scroll_up, MMAIN, N_("Scroll Up"), + nano_scrollup_msg, FALSE, VIEW); - sc_init_one(&main_list, NANO_NO_KEY, N_("Scroll Down"), - IFSCHELP(nano_scrolldown_msg, TRUE, NANO_SCROLLDOWN_KEY), - NANO_NO_KEY, NANO_SCROLLDOWN_METAKEY, VIEW, do_scroll_down); + add_to_funcs(do_scroll_down, MMAIN, N_("Scroll Down"), + nano_scrolldown_msg, FALSE, VIEW); #endif #ifdef ENABLE_MULTIBUFFER - sc_init_one(&main_list, NANO_NO_KEY, N_("Previous File"), - IFSCHELP(nano_prevfile_msg, FALSE, NANO_PREVFILE_KEY), - NANO_NO_KEY, NANO_PREVFILE_METAKEY, VIEW, - switch_to_prev_buffer_void); - - sc_init_one(&main_list, NANO_NO_KEY, N_("Next File"), - IFSCHELP(nano_nextfile_msg, TRUE, NANO_NEXTFILE_KEY), - NANO_NO_KEY, NANO_NEXTFILE_METAKEY, VIEW, - switch_to_next_buffer_void); + add_to_funcs(switch_to_prev_buffer_void, MMAIN, _("Previous File"), + nano_prevfile_msg, FALSE, VIEW); + add_to_funcs(switch_to_next_buffer_void, MMAIN, N_("Next File"), + nano_nextfile_msg, TRUE, VIEW); #endif - sc_init_one(&main_list, NANO_NO_KEY, N_("Verbatim Input"), - IFSCHELP(nano_verbatim_msg, FALSE, NANO_VERBATIM_KEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, do_verbatim_input); - - sc_init_one(&main_list, NANO_TAB_KEY, N_("Tab"), - IFSCHELP(nano_tab_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, NOVIEW, do_tab); - - sc_init_one(&main_list, NANO_ENTER_KEY, N_("Enter"), - IFSCHELP(nano_enter_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, NOVIEW, do_enter); - - sc_init_one(&main_list, NANO_DELETE_KEY, N_("Delete"), - IFSCHELP(nano_delete_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, NOVIEW, do_delete); - - sc_init_one(&main_list, NANO_BACKSPACE_KEY, N_("Backspace") + add_to_funcs(do_verbatim_input, MMAIN, N_("Verbatim Input"), + nano_verbatim_msg, FALSE, NOVIEW); + add_to_funcs(do_tab, MMAIN, N_("Tab"), nano_tab_msg, + FALSE, NOVIEW); + add_to_funcs(do_enter, MMAIN, N_("Enter"), nano_enter_msg, + FALSE, NOVIEW); + add_to_funcs(do_delete, MMAIN, N_("Delete"), nano_delete_msg, + FALSE, NOVIEW); + add_to_funcs(do_backspace, MMAIN, N_("Backspace"), nano_backspace_msg, #ifndef NANO_TINY - , IFSCHELP(nano_backspace_msg, FALSE, NANO_NO_KEY) + FALSE, #else - , IFSCHELP(nano_backspace_msg, TRUE, NANO_NO_KEY) + TRUE, #endif - , NANO_NO_KEY, NANO_NO_KEY, NOVIEW, do_backspace); + VIEW); #ifndef NANO_TINY - sc_init_one(&main_list, NANO_NO_KEY, N_("CutTillEnd"), - IFSCHELP(nano_cut_till_end_msg, TRUE, NANO_CUTTILLEND_METAKEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, do_cut_till_end); + add_to_funcs(do_cut_till_end, MMAIN, N_("CutTillEnd"), + nano_cut_till_end_msg, TRUE, NOVIEW); #endif + add_to_funcs(xon_complaint, MMAIN, "", "", FALSE, VIEW); + add_to_funcs(xoff_complaint, MMAIN, "", "", FALSE, VIEW); + #ifndef DISABLE_JUSTIFY - sc_init_one(&main_list, NANO_NO_KEY, fulljstify_msg, - IFSCHELP(nano_fulljustify_msg, FALSE, NANO_FULLJUSTIFY_METAKEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, do_full_justify); + add_to_funcs(do_full_justify, (MMAIN|MWHEREIS), fulljstify_msg, + nano_fulljustify_msg, FALSE, NOVIEW); #endif #ifndef NANO_TINY - sc_init_one(&main_list, NANO_NO_KEY, N_("Word Count"), - IFSCHELP(nano_wordcount_msg, FALSE, NANO_WORDCOUNT_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, do_wordlinechar_count); + add_to_funcs(do_wordlinechar_count, MMAIN, N_("Word Count"), + nano_wordcount_msg, FALSE, VIEW); #endif - sc_init_one(&main_list, NANO_REFRESH_KEY, refresh_msg + add_to_funcs(total_refresh, (MMAIN|MHELP), refresh_msg, refresh_msg, #ifndef NANO_TINY - , IFSCHELP(nano_refresh_msg, TRUE, NANO_NO_KEY) + TRUE, #else - , IFSCHELP(nano_refresh_msg, FALSE, NANO_NO_KEY) -#endif - , NANO_NO_KEY, NANO_NO_KEY, VIEW, total_refresh); - - free_shortcutage(&whereis_list); - - sc_init_one(&whereis_list, NANO_HELP_KEY, get_help_msg, - IFSCHELP(nano_help_msg, FALSE, NANO_NO_KEY), NANO_HELP_FKEY, - NANO_NO_KEY, VIEW, -#ifndef DISABLE_HELP - do_help_void -#else - nano_disabled_msg -#endif - ); - - sc_init_one(&whereis_list, NANO_CANCEL_KEY, cancel_msg, - IFSCHELP(nano_cancel_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&whereis_list, NANO_FIRSTLINE_KEY, first_line_msg, - IFSCHELP(nano_firstline_msg, FALSE, NANO_FIRSTLINE_METAKEY), - NANO_FIRSTLINE_FKEY, NANO_FIRSTLINE_METAKEY2, VIEW, - do_first_line); - - sc_init_one(&whereis_list, NANO_LASTLINE_KEY, last_line_msg, - IFSCHELP(nano_lastline_msg, FALSE, NANO_LASTLINE_METAKEY), - NANO_LASTLINE_FKEY, NANO_LASTLINE_METAKEY2, VIEW, do_last_line); - - sc_init_one(&whereis_list, NANO_TOOTHERSEARCH_KEY, replace_msg, - IFSCHELP(nano_replace_msg, FALSE, NANO_NO_KEY), - NANO_REPLACE_FKEY, NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&whereis_list, NANO_TOGOTOLINE_KEY, go_to_line_msg, - IFSCHELP(nano_gotoline_msg, FALSE, NANO_NO_KEY), - NANO_GOTOLINE_FKEY, NANO_NO_KEY, VIEW, NULL); - -#ifndef DISABLE_JUSTIFY - sc_init_one(&whereis_list, NANO_PARABEGIN_KEY, beg_of_par_msg, - IFSCHELP(nano_parabegin_msg, FALSE, NANO_PARABEGIN_METAKEY), - NANO_NO_KEY, NANO_PARABEGIN_METAKEY2, VIEW, do_para_begin_void); - - sc_init_one(&whereis_list, NANO_PARAEND_KEY, end_of_par_msg, - IFSCHELP(nano_paraend_msg, FALSE, NANO_PARAEND_METAKEY), - NANO_NO_KEY, NANO_PARAEND_METAKEY2, VIEW, do_para_end_void); + FALSE, #endif + VIEW); #ifndef NANO_TINY - sc_init_one(&whereis_list, NANO_NO_KEY, case_sens_msg, - IFSCHELP(nano_case_msg, FALSE, TOGGLE_CASE_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); + add_to_funcs((void *) case_sens_msg, + (MWHEREIS|MREPLACE|MWHEREISFILE), + case_sens_msg, nano_case_msg, FALSE, VIEW); - sc_init_one(&whereis_list, NANO_NO_KEY, backwards_msg, - IFSCHELP(nano_reverse_msg, FALSE, TOGGLE_BACKWARDS_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, NULL); + add_to_funcs((void *) backwards_msg, + (MWHEREIS|MREPLACE|MWHEREISFILE), + backwards_msg, nano_reverse_msg, FALSE, VIEW); #endif #ifdef HAVE_REGEX_H - sc_init_one(&whereis_list, NANO_NO_KEY, regexp_msg, - IFSCHELP(nano_regexp_msg, FALSE, NANO_REGEXP_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); + add_to_funcs((void *) regexp_msg, + (MWHEREIS|MREPLACE|MWHEREISFILE), + regexp_msg, nano_regexp_msg, FALSE, VIEW); #endif #ifndef NANO_TINY - sc_init_one(&whereis_list, NANO_PREVLINE_KEY, prev_history_msg, - IFSCHELP(nano_prev_history_msg, FALSE, NANO_NO_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, NULL); + add_to_funcs((void *) prev_history_msg, + (MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE), + prev_history_msg, nano_prev_history_msg, FALSE, VIEW); - sc_init_one(&whereis_list, NANO_NEXTLINE_KEY, next_history_msg, - IFSCHELP(nano_next_history_msg, FALSE, NANO_NO_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, NULL); + add_to_funcs((void *) next_history_msg, + (MWHEREIS|MREPLACE|MREPLACE2|MWHEREISFILE), + next_history_msg, nano_next_history_msg, FALSE, VIEW); #endif -#ifndef DISABLE_JUSTIFY - sc_init_one(&whereis_list, NANO_FULLJUSTIFY_KEY, fulljstify_msg, - IFSCHELP(nano_fulljustify_msg, FALSE, NANO_FULLJUSTIFY_METAKEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, do_full_justify); -#endif + add_to_funcs((void *) no_replace_msg, MREPLACE, + no_replace_msg, nano_whereis_msg, FALSE, VIEW); - free_shortcutage(&replace_list); - - sc_init_one(&replace_list, NANO_HELP_KEY, get_help_msg, - IFSCHELP(nano_help_msg, FALSE, NANO_NO_KEY), NANO_HELP_FKEY, - NANO_NO_KEY, VIEW, -#ifndef DISABLE_HELP - do_help_void -#else - nano_disabled_msg -#endif - ); - - sc_init_one(&replace_list, NANO_CANCEL_KEY, cancel_msg, - IFSCHELP(nano_cancel_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&replace_list, NANO_FIRSTLINE_KEY, first_line_msg, - IFSCHELP(nano_firstline_msg, FALSE, NANO_FIRSTLINE_METAKEY), - NANO_FIRSTLINE_FKEY, NANO_FIRSTLINE_METAKEY2, VIEW, - do_first_line); - - sc_init_one(&replace_list, NANO_LASTLINE_KEY, last_line_msg, - IFSCHELP(nano_lastline_msg, FALSE, NANO_LASTLINE_METAKEY), - NANO_LASTLINE_FKEY, NANO_LASTLINE_METAKEY2, VIEW, do_last_line); - - /* TRANSLATORS: Try to keep this at most 12 characters. */ - sc_init_one(&replace_list, NANO_TOOTHERSEARCH_KEY, N_("No Replace"), - IFSCHELP(nano_whereis_msg, FALSE, NANO_NO_KEY), - NANO_REPLACE_FKEY, NANO_NO_KEY, VIEW, NULL); - -#ifndef NANO_TINY - sc_init_one(&replace_list, NANO_NO_KEY, case_sens_msg, - IFSCHELP(nano_case_msg, FALSE, TOGGLE_CASE_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&replace_list, NANO_NO_KEY, backwards_msg, - IFSCHELP(nano_reverse_msg, FALSE, TOGGLE_BACKWARDS_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, NULL); -#endif - -#ifdef HAVE_REGEX_H - sc_init_one(&replace_list, NANO_NO_KEY, regexp_msg, - IFSCHELP(nano_regexp_msg, FALSE, NANO_REGEXP_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); -#endif - -#ifndef NANO_TINY - sc_init_one(&replace_list, NANO_PREVLINE_KEY, prev_history_msg, - IFSCHELP(nano_prev_history_msg, FALSE, NANO_NO_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&replace_list, NANO_NEXTLINE_KEY, next_history_msg, - IFSCHELP(nano_next_history_msg, FALSE, NANO_NO_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, NULL); -#endif - - free_shortcutage(&replace_list_2); - - sc_init_one(&replace_list_2, NANO_HELP_KEY, get_help_msg, - IFSCHELP(nano_help_msg, FALSE, NANO_NO_KEY), NANO_HELP_FKEY, - NANO_NO_KEY, VIEW, -#ifndef DISABLE_HELP - do_help_void -#else - nano_disabled_msg -#endif - ); - - sc_init_one(&replace_list_2, NANO_CANCEL_KEY, cancel_msg, - IFSCHELP(nano_cancel_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&replace_list_2, NANO_FIRSTLINE_KEY, first_line_msg, - IFSCHELP(nano_firstline_msg, FALSE, NANO_FIRSTLINE_METAKEY), - NANO_FIRSTLINE_FKEY, NANO_FIRSTLINE_METAKEY2, VIEW, - do_first_line); - - sc_init_one(&replace_list_2, NANO_LASTLINE_KEY, last_line_msg, - IFSCHELP(nano_lastline_msg, FALSE, NANO_LASTLINE_METAKEY), - NANO_LASTLINE_FKEY, NANO_LASTLINE_METAKEY2, VIEW, do_last_line); - -#ifndef NANO_TINY - sc_init_one(&replace_list_2, NANO_PREVLINE_KEY, prev_history_msg, - IFSCHELP(nano_prev_history_msg, FALSE, NANO_NO_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&replace_list_2, NANO_NEXTLINE_KEY, next_history_msg, - IFSCHELP(nano_next_history_msg, FALSE, NANO_NO_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, NULL); -#endif - - free_shortcutage(&gotoline_list); - - sc_init_one(&gotoline_list, NANO_HELP_KEY, get_help_msg, - IFSCHELP(nano_help_msg, FALSE, NANO_NO_KEY), NANO_HELP_FKEY, - NANO_NO_KEY, VIEW, -#ifndef DISABLE_HELP - do_help_void -#else - nano_disabled_msg -#endif - ); - - sc_init_one(&gotoline_list, NANO_CANCEL_KEY, cancel_msg, - IFSCHELP(nano_cancel_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&gotoline_list, NANO_FIRSTLINE_KEY, first_line_msg, - IFSCHELP(nano_firstline_msg, FALSE, NANO_FIRSTLINE_METAKEY), - NANO_FIRSTLINE_FKEY, NANO_FIRSTLINE_METAKEY2, VIEW, - do_first_line); - - sc_init_one(&gotoline_list, NANO_LASTLINE_KEY, last_line_msg, - IFSCHELP(nano_lastline_msg, FALSE, NANO_LASTLINE_METAKEY), - NANO_LASTLINE_FKEY, NANO_LASTLINE_METAKEY2, VIEW, do_last_line); - - sc_init_one(&gotoline_list, NANO_TOOTHERWHEREIS_KEY, - N_("Go To Text"), IFSCHELP(nano_whereis_msg, FALSE, - NANO_NO_KEY), NANO_NO_KEY, NANO_NO_KEY, VIEW, NULL); - - free_shortcutage(&writefile_list); - - sc_init_one(&writefile_list, NANO_HELP_KEY, get_help_msg, - IFSCHELP(nano_help_msg, FALSE, NANO_NO_KEY), NANO_HELP_FKEY, - NANO_NO_KEY, VIEW, -#ifndef DISABLE_HELP - do_help_void -#else - nano_disabled_msg -#endif - ); - - sc_init_one(&writefile_list, NANO_CANCEL_KEY, cancel_msg, - IFSCHELP(nano_cancel_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); + add_to_funcs((void *) gototext_msg, MGOTOLINE, + gototext_msg, nano_whereis_msg, FALSE, VIEW); #ifndef DISABLE_BROWSER - /* If we're using restricted mode, the file browser is disabled. - * It's useless since inserting files is disabled. */ if (!ISSET(RESTRICTED)) - sc_init_one(&writefile_list, NANO_TOFILES_KEY, to_files_msg, - IFSCHELP(nano_tofiles_msg, FALSE, NANO_NO_KEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, NULL); + add_to_funcs((void *) to_files_msg, + (MGOTOLINE|MINSERTFILE), + to_files_msg, nano_tofiles_msg, FALSE, VIEW); #endif #ifndef NANO_TINY @@ -946,279 +867,225 @@ void shortcut_init(bool unjustify) * specified on the command line, and the fifth is useless since * backups are disabled. */ if (!ISSET(RESTRICTED)) - /* TRANSLATORS: Try to keep this at most 16 characters. */ - sc_init_one(&writefile_list, NANO_NO_KEY, N_("DOS Format"), - IFSCHELP(nano_dos_msg, FALSE, TOGGLE_DOS_KEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, NULL); + add_to_funcs((void *) dos_format_msg, MWRITEFILE, + dos_format_msg, nano_dos_msg, FALSE, NOVIEW); if (!ISSET(RESTRICTED)) - /* TRANSLATORS: Try to keep this at most 16 characters. */ - sc_init_one(&writefile_list, NANO_NO_KEY, N_("Mac Format"), - IFSCHELP(nano_mac_msg, FALSE, TOGGLE_MAC_KEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, NULL); -#endif + add_to_funcs((void *) mac_format_msg, MWRITEFILE, + mac_format_msg, nano_mac_msg, FALSE, NOVIEW); if (!ISSET(RESTRICTED)) - /* TRANSLATORS: Try to keep this at most 16 characters. */ - sc_init_one(&writefile_list, NANO_NO_KEY, N_("Append"), - IFSCHELP(nano_append_msg, FALSE, NANO_APPEND_KEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, NULL); + add_to_funcs((void *) append_msg, MWRITEFILE, + append_msg, nano_append_msg, FALSE, NOVIEW); if (!ISSET(RESTRICTED)) - /* TRANSLATORS: Try to keep this at most 16 characters. */ - sc_init_one(&writefile_list, NANO_NO_KEY, N_("Prepend"), - IFSCHELP(nano_prepend_msg, FALSE, NANO_PREPEND_KEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, NULL); + add_to_funcs((void *) prepend_msg, MWRITEFILE, + prepend_msg, nano_prepend_msg, FALSE, NOVIEW); -#ifndef NANO_TINY if (!ISSET(RESTRICTED)) - /* TRANSLATORS: Try to keep this at most 16 characters. */ - sc_init_one(&writefile_list, NANO_NO_KEY, N_("Backup File"), - IFSCHELP(nano_backup_msg, FALSE, TOGGLE_BACKUP_KEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, NULL); -#endif - - free_shortcutage(&insertfile_list); - - sc_init_one(&insertfile_list, NANO_HELP_KEY, get_help_msg, - IFSCHELP(nano_help_msg, FALSE, NANO_NO_KEY), NANO_HELP_FKEY, - NANO_NO_KEY, VIEW, -#ifndef DISABLE_HELP - do_help_void -#else - nano_disabled_msg -#endif - ); - - sc_init_one(&insertfile_list, NANO_CANCEL_KEY, cancel_msg, - IFSCHELP(nano_cancel_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - -#ifndef DISABLE_BROWSER - /* If we're using restricted mode, the file browser is disabled. - * It's useless since inserting files is disabled. */ - if (!ISSET(RESTRICTED)) - sc_init_one(&insertfile_list, NANO_TOFILES_KEY, to_files_msg, - IFSCHELP(nano_tofiles_msg, FALSE, NANO_NO_KEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, NULL); + add_to_funcs((void *) backup_file_msg, MWRITEFILE, + backup_file_msg, nano_backup_msg, FALSE, NOVIEW); #endif #ifndef NANO_TINY /* If we're using restricted mode, command execution is disabled. * It's useless since inserting files is disabled. */ if (!ISSET(RESTRICTED)) - sc_init_one(&insertfile_list, NANO_TOOTHERINSERT_KEY, - /* TRANSLATORS: Try to keep this at most 22 - * characters. */ - N_("Execute Command"), IFSCHELP(nano_execute_msg, FALSE, - NANO_NO_KEY), NANO_NO_KEY, NANO_NO_KEY, NOVIEW, NULL); + add_to_funcs((void *) ext_cmd_msg, MINSERTFILE, + ext_cmd_msg, nano_execute_msg, FALSE, NOVIEW); #ifdef ENABLE_MULTIBUFFER /* If we're using restricted mode, the multibuffer toggle is * disabled. It's useless since inserting files is disabled. */ if (!ISSET(RESTRICTED)) - sc_init_one(&insertfile_list, NANO_NO_KEY, new_buffer_msg, - IFSCHELP(nano_multibuffer_msg, FALSE, - TOGGLE_MULTIBUFFER_KEY), NANO_NO_KEY, NANO_NO_KEY, - NOVIEW, NULL); -#endif + add_to_funcs((void *) new_buffer_msg, MWRITEFILE, + new_buffer_msg, nano_multibuffer_msg, FALSE, NOVIEW); #endif -#ifndef NANO_TINY - free_shortcutage(&extcmd_list); - - sc_init_one(&extcmd_list, NANO_HELP_KEY, get_help_msg, - IFSCHELP(nano_help_msg, FALSE, NANO_NO_KEY), NANO_HELP_FKEY, - NANO_NO_KEY, VIEW, -#ifndef DISABLE_HELP - do_help_void -#else - nano_disabled_msg -#endif - ); - - sc_init_one(&extcmd_list, NANO_CANCEL_KEY, cancel_msg, - IFSCHELP(nano_cancel_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&extcmd_list, NANO_TOOTHERINSERT_KEY, N_("Insert File"), - IFSCHELP(nano_insert_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); + add_to_funcs((void *) insert_file_msg, MEXTCMD, + insert_file_msg, nano_insert_msg, FALSE, VIEW); #ifdef ENABLE_MULTIBUFFER - sc_init_one(&extcmd_list, NANO_NO_KEY, new_buffer_msg, - IFSCHELP(nano_multibuffer_msg, FALSE, TOGGLE_MULTIBUFFER_KEY), - NANO_NO_KEY, NANO_NO_KEY, NOVIEW, NULL); + add_to_funcs((void *) new_buffer_msg, MEXTCMD, + new_buffer_msg, nano_multibuffer_msg, FALSE, NOVIEW); #endif #endif #ifndef DISABLE_HELP - free_shortcutage(&help_list); - - sc_init_one(&help_list, NANO_REFRESH_KEY, refresh_msg, - IFSCHELP(nano_refresh_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&help_list, NANO_EXIT_KEY, exit_msg, - IFSCHELP(nano_exit_msg, FALSE, NANO_NO_KEY), NANO_EXIT_FKEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&help_list, NANO_PREVPAGE_KEY, prev_page_msg, - IFSCHELP(nano_prevpage_msg, FALSE, NANO_NO_KEY), - NANO_PREVPAGE_FKEY, NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&help_list, NANO_NEXTPAGE_KEY, next_page_msg, - IFSCHELP(nano_nextpage_msg, FALSE, NANO_NO_KEY), - NANO_NEXTPAGE_FKEY, NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&help_list, NANO_PREVLINE_KEY, N_("Prev Line"), - IFSCHELP(nano_prevline_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&help_list, NANO_NEXTLINE_KEY, N_("Next Line"), - IFSCHELP(nano_nextline_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&help_list, NANO_NO_KEY, first_line_msg, - IFSCHELP(nano_firstline_msg, FALSE, NANO_FIRSTLINE_METAKEY), - NANO_NO_KEY, NANO_FIRSTLINE_METAKEY2, VIEW, NULL); - - sc_init_one(&help_list, NANO_NO_KEY, last_line_msg, - IFSCHELP(nano_lastline_msg, TRUE, NANO_LASTLINE_METAKEY), - NANO_NO_KEY, NANO_LASTLINE_METAKEY2, VIEW, NULL); -#endif - -#ifndef DISABLE_SPELLER - free_shortcutage(&spell_list); - - sc_init_one(&spell_list, NANO_HELP_KEY, get_help_msg, - IFSCHELP(nano_help_msg, FALSE, NANO_NO_KEY), NANO_HELP_FKEY, - NANO_NO_KEY, VIEW, -#ifndef DISABLE_HELP - do_help_void -#else - nano_disabled_msg -#endif - ); - - sc_init_one(&spell_list, NANO_CANCEL_KEY, cancel_msg, - IFSCHELP(nano_cancel_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); + add_to_funcs((void *) refresh_msg, MHELP, + refresh_msg, nano_refresh_msg, FALSE, VIEW); #endif #ifndef DISABLE_BROWSER - free_shortcutage(&browser_list); - sc_init_one(&browser_list, NANO_HELP_KEY, get_help_msg, - IFSCHELP(nano_help_msg, FALSE, NANO_NO_KEY), NANO_HELP_FKEY, - NANO_NO_KEY, VIEW, NULL); + add_to_funcs((void *) first_file_msg, + (MBROWSER|MWHEREISFILE), + first_file_msg, nano_firstfile_msg, FALSE, VIEW); - sc_init_one(&browser_list, NANO_EXIT_KEY, exit_msg, - IFSCHELP(nano_exitbrowser_msg, FALSE, NANO_NO_KEY), - NANO_EXIT_FKEY, NANO_NO_KEY, VIEW, NULL); + add_to_funcs((void *) last_file_msg, + (MBROWSER|MWHEREISFILE), + last_file_msg, nano_lastfile_msg, FALSE, VIEW); - sc_init_one(&browser_list, NANO_WHEREIS_KEY, whereis_msg, - IFSCHELP(nano_whereis_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&browser_list, NANO_NO_KEY, whereis_next_msg, - IFSCHELP(nano_whereis_next_msg, FALSE, NANO_WHEREIS_NEXT_KEY), - NANO_WHEREIS_NEXT_FKEY, NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&browser_list, NANO_PREVPAGE_KEY, prev_page_msg, - IFSCHELP(nano_prevpage_msg, FALSE, NANO_NO_KEY), - NANO_PREVPAGE_FKEY, NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&browser_list, NANO_NEXTPAGE_KEY, next_page_msg, - IFSCHELP(nano_nextpage_msg, FALSE, NANO_NO_KEY), - NANO_NEXTPAGE_FKEY, NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&browser_list, NANO_NO_KEY, first_file_msg, - IFSCHELP(nano_firstfile_msg, FALSE, NANO_FIRSTFILE_METAKEY), - NANO_NO_KEY, NANO_FIRSTFILE_METAKEY2, VIEW, NULL); - - sc_init_one(&browser_list, NANO_NO_KEY, last_file_msg, - IFSCHELP(nano_lastfile_msg, FALSE, NANO_LASTFILE_METAKEY), - NANO_NO_KEY, NANO_LASTFILE_METAKEY2, VIEW, NULL); - - /* TRANSLATORS: Try to keep this at most 12 characters. */ - sc_init_one(&browser_list, NANO_GOTODIR_KEY, N_("Go To Dir"), - IFSCHELP(nano_gotodir_msg, FALSE, NANO_GOTODIR_METAKEY), - NANO_GOTODIR_FKEY, NANO_NO_KEY, VIEW, NULL); - - free_shortcutage(&whereis_file_list); - - sc_init_one(&whereis_file_list, NANO_HELP_KEY, get_help_msg, - IFSCHELP(nano_help_msg, FALSE, NANO_NO_KEY), NANO_HELP_FKEY, - NANO_NO_KEY, VIEW, -#ifndef DISABLE_HELP - do_browser_help -#else - nano_disabled_msg -#endif - ); - - sc_init_one(&whereis_file_list, NANO_CANCEL_KEY, cancel_msg, - IFSCHELP(nano_cancel_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&whereis_file_list, NANO_FIRSTFILE_KEY, first_file_msg, - IFSCHELP(nano_firstfile_msg, FALSE, NANO_FIRSTFILE_METAKEY), - NANO_FIRSTFILE_FKEY, NANO_FIRSTFILE_METAKEY2, VIEW, - do_first_file); - - sc_init_one(&whereis_file_list, NANO_LASTFILE_KEY, last_file_msg, - IFSCHELP(nano_lastfile_msg, FALSE, NANO_LASTFILE_METAKEY), - NANO_LASTFILE_FKEY, NANO_LASTFILE_METAKEY2, VIEW, do_last_file); - -#ifndef NANO_SMALL - sc_init_one(&whereis_file_list, NANO_NO_KEY, case_sens_msg, - IFSCHELP(nano_case_msg, FALSE, TOGGLE_CASE_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&whereis_file_list, NANO_NO_KEY, backwards_msg, - IFSCHELP(nano_reverse_msg, FALSE, TOGGLE_BACKWARDS_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, NULL); + add_to_funcs((void *) goto_dir_msg, MBROWSER, + goto_dir_msg, nano_gotodir_msg, FALSE, VIEW); #endif -#ifdef HAVE_REGEX_H - sc_init_one(&whereis_file_list, NANO_NO_KEY, regexp_msg, - IFSCHELP(nano_regexp_msg, FALSE, NANO_REGEXP_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); -#endif - -#ifndef NANO_SMALL - sc_init_one(&whereis_file_list, NANO_PREVLINE_KEY, prev_history_msg, - IFSCHELP(nano_prev_history_msg, FALSE, NANO_NO_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, NULL); - - sc_init_one(&whereis_file_list, NANO_NEXTLINE_KEY, next_history_msg, - IFSCHELP(nano_next_history_msg, FALSE, NANO_NO_KEY), - NANO_NO_KEY, NANO_NO_KEY, VIEW, NULL); -#endif - - free_shortcutage(&gotodir_list); - - sc_init_one(&gotodir_list, NANO_HELP_KEY, get_help_msg, - IFSCHELP(nano_help_msg, FALSE, NANO_NO_KEY), NANO_HELP_FKEY, - NANO_NO_KEY, VIEW, -#ifndef DISABLE_HELP - do_browser_help -#else - nano_disabled_msg -#endif - ); - - sc_init_one(&gotodir_list, NANO_CANCEL_KEY, cancel_msg, - IFSCHELP(nano_cancel_msg, FALSE, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, NULL); -#endif - - currshortcut = main_list; + currmenu = MMAIN; #ifndef NANO_TINY - toggle_init(); + add_to_sclist(MALL, "^G", do_help_void, 0, TRUE); + add_to_sclist(MALL, "F1", do_help_void, 0, TRUE); #endif + add_to_sclist(MMAIN, "^X", do_exit, 0, TRUE); + add_to_sclist(MMAIN, "F2", do_exit, 0, TRUE); + add_to_sclist(MHELP, "^X", do_exit, 0, TRUE); + add_to_sclist(MHELP, "F2", do_exit, 0, TRUE); + add_to_sclist(MMAIN, "^_", do_gotolinecolumn_void, 0, TRUE); + add_to_sclist(MMAIN, "F13", do_gotolinecolumn_void, 0, TRUE); + add_to_sclist(MMAIN, "^O", do_writeout_void, 0, TRUE); + add_to_sclist(MMAIN, "F3", do_writeout_void, 0, TRUE); +#ifndef NANO_TINY + 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); + add_to_sclist(MMAIN, "^W", do_search, 0, TRUE); + add_to_sclist(MMAIN, "F6", do_search, 0, TRUE); + add_to_sclist(MMAIN, "^Y", do_page_up, 0, TRUE); + add_to_sclist(MMAIN, "F7", do_page_up, 0, TRUE); + add_to_sclist(MMAIN, "^V", do_page_down, 0, TRUE); + add_to_sclist(MMAIN, "F8", do_page_down, 0, TRUE); + 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); +#ifndef NANO_TINY + add_to_sclist(MMAIN, "^T", do_spell, 0, TRUE); + add_to_sclist(MMAIN, "F12", do_spell, 0, TRUE); +#endif + add_to_sclist(MMAIN, "^_", do_gotolinecolumn_void, 0, TRUE); + add_to_sclist(MMAIN, "F13", do_gotolinecolumn_void, 0, TRUE); + add_to_sclist(MMAIN, "M-G", do_gotolinecolumn_void, 0, TRUE); + add_to_sclist(MMAIN, "^\\", do_replace, 0, TRUE); + add_to_sclist(MMAIN, "F14", do_replace, 0, TRUE); + add_to_sclist(MMAIN, "M-R", do_replace, 0, TRUE); + add_to_sclist(MWHEREIS, "^R", do_replace, 0, FALSE); + add_to_sclist(MREPLACE, "^R", (void *) no_replace_msg, 0, FALSE); + add_to_sclist(MWHEREIS, "^T", do_gotolinecolumn_void, 0, TRUE); +#ifndef NANO_TINY + add_to_sclist(MMAIN, "^^", do_mark, 0, TRUE); + add_to_sclist(MMAIN, "F15", do_mark, 0, TRUE); + add_to_sclist(MMAIN, "M-A", do_mark, 0, TRUE); + add_to_sclist(MALL, "F16", do_research, 0, TRUE); + add_to_sclist(MALL, "M-W", 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); + add_to_sclist(MMAIN|MBROWSER|MHELP, "^F", do_right, 0, TRUE); + add_to_sclist(MMAIN|MBROWSER|MHELP, "^B", do_left, 0, TRUE); + 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(MALL, "^Q", xon_complaint, 0, TRUE); + add_to_sclist(MALL, "^X", xoff_complaint, 0, TRUE); + add_to_sclist(MALL, "^P", do_up_void, 0, TRUE); + add_to_sclist(MALL, "^N", do_down_void, 0, TRUE); + add_to_sclist(MALL, "^A", do_home, 0, TRUE); + add_to_sclist(MALL, "^E", do_end, 0, TRUE); + add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2, + "^W", do_para_begin_void, 0, TRUE); + add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2, + "^O", do_para_end_void, 0, TRUE); + add_to_sclist(MALL, "M-(", do_para_begin_void, 0, TRUE); + add_to_sclist(MALL, "M-9", do_para_begin_void, 0, TRUE); + add_to_sclist(MALL, "M-)", do_para_end_void, 0, TRUE); + add_to_sclist(MALL, "M-0", do_para_end_void, 0, TRUE); + add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2, + "^Y", do_first_line, 0, TRUE); + add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2, + "^V", do_last_line, 0, TRUE); + + add_to_sclist(MWHEREIS, + "M-C", (void *) case_sens_msg, 0, FALSE); + add_to_sclist(MREPLACE, + "M-C", (void *) case_sens_msg, 0, FALSE); + add_to_sclist(MREPLACE2, + "M-C", (void *) case_sens_msg, 0, FALSE); + add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2, + "M-B", (void *) backwards_msg, 0, FALSE); + add_to_sclist(MWHEREIS|MREPLACE|MREPLACE2, + "M-R", (void *) regexp_msg, 0, FALSE); + + add_to_sclist(MMAIN, "M-\\", do_first_line, 0, TRUE); + add_to_sclist(MMAIN, "M-|", do_first_line, 0, TRUE); + add_to_sclist(MMAIN, "M-/", do_last_line, 0, TRUE); + add_to_sclist(MMAIN, "M-?", do_last_line, 0, TRUE); +#ifndef NANO_TINY + 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); +#endif + +#ifdef ENABLE_MULTIBUFFER + 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); +#endif + add_to_sclist(MMAIN, "M-V", do_verbatim_input, 0, TRUE); + add_to_sclist(MALL, "^I", do_tab, 0, TRUE); + add_to_sclist(MALL, "^M", do_enter, 0, TRUE); + add_to_sclist(MALL, "^D", do_delete, 0, TRUE); + add_to_sclist(MALL, "^H", do_backspace, 0, TRUE); + add_to_sclist(MALL, "M-T", do_cut_till_end, 0, TRUE); +#ifndef NANO_TINY + add_to_sclist(MALL, "M-J", do_full_justify, 0, TRUE); + add_to_sclist(MALL, "M-D", do_wordlinechar_count, 0, TRUE); + add_to_sclist(MMAIN, "M-X", do_toggle, NO_HELP, TRUE); + add_to_sclist(MMAIN, "M-C", do_toggle, CONST_UPDATE, TRUE); + add_to_sclist(MMAIN, "M-O", do_toggle, MORE_SPACE, TRUE); + add_to_sclist(MMAIN, "M-S", do_toggle, SMOOTH_SCROLL, TRUE); + add_to_sclist(MMAIN, "M-P", do_toggle, WHITESPACE_DISPLAY, TRUE); + add_to_sclist(MMAIN, "M-Y", do_toggle, NO_COLOR_SYNTAX, TRUE); + add_to_sclist(MMAIN, "M-H", do_toggle, SMART_HOME, TRUE); + add_to_sclist(MMAIN, "M-I", do_toggle, AUTOINDENT, TRUE); + add_to_sclist(MMAIN, "M-K", do_toggle, CUT_TO_END, TRUE); + add_to_sclist(MMAIN, "M-L", do_toggle, NO_WRAP, TRUE); + add_to_sclist(MMAIN, "M-Q", do_toggle, TABS_TO_SPACES, TRUE); + add_to_sclist(MMAIN, "M-B", do_toggle, BACKUP_FILE, TRUE); + add_to_sclist(MMAIN, "M-F", do_toggle, MULTIBUFFER, TRUE); + add_to_sclist(MMAIN, "M-M", do_toggle, USE_MOUSE, TRUE); + add_to_sclist(MMAIN, "M-N", do_toggle, NO_CONVERT, TRUE); + add_to_sclist(MMAIN, "M-Z", do_toggle, SUSPEND, TRUE); +#endif + add_to_sclist((MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE|MWRITEFILE|MINSERTFILE|MEXTCMD|MSPELL|MWHEREISFILE|MGOTODIR), + "^C", (void *) cancel_msg, 0, FALSE); + add_to_sclist(MHELP, "^Y", do_page_up, 0, TRUE); + add_to_sclist(MHELP, "F7", do_page_up, 0, TRUE); + add_to_sclist(MHELP, "^V", do_page_down, 0, TRUE); + add_to_sclist(MHELP, "F8", do_page_down, 0, TRUE); + add_to_sclist(MHELP, "^X", do_exit, 0, TRUE); + add_to_sclist(MHELP, "F2", do_exit, 0, TRUE); + add_to_sclist(MWRITEFILE, "M-D", (void *) dos_format_msg, 0, FALSE); + add_to_sclist(MWRITEFILE, "M-M", (void *) mac_format_msg, 0, FALSE); + add_to_sclist(MWRITEFILE, "M-A", (void *) append_msg, 0, FALSE); + add_to_sclist(MWRITEFILE, "M-P", (void *) prepend_msg, 0, FALSE); + add_to_sclist(MWRITEFILE, "M-B", (void *) backup_file_msg, 0, FALSE); + add_to_sclist(MWRITEFILE, "^T", (void *) to_files_msg, 0, FALSE); + add_to_sclist(MINSERTFILE, "^T", (void *) to_files_msg, 0, FALSE); + add_to_sclist(MINSERTFILE, "^X", (void *) ext_cmd_msg, 0, FALSE); + add_to_sclist(MMAIN, "^L", total_refresh, 0, TRUE); + +#ifdef DEBUG + print_sclist(); +#endif + } /* Free the given shortcut. */ @@ -1233,145 +1100,325 @@ void free_shortcutage(shortcut **shortcutage) } } -#ifndef NANO_TINY -/* Add a new toggle to the end of the global toggle list. */ -void toggle_init_one(int val -#ifndef DISABLE_HELP - , const char *desc, bool blank_after -#endif - , long flag) +const subnfunc *sctofunc(sc *s) { - toggle *u; + subnfunc *f; - if (toggles == NULL) { - toggles = (toggle *)nmalloc(sizeof(toggle)); - u = toggles; + for (f = allfuncs; f != NULL && s->scfunc != f->scfunc; f = f->next) + ; + + return f; +} + +#ifndef NANO_TINY +/* Now lets come up with a single (hopefully) + function to get a string for each flag */ +char *flagtostr(int flag) +{ + switch (flag) { + case NO_HELP: + 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: + return N_("Long line wrapping"); + 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 "?????"; + } +} + +/* Interpret the string given by the rc file and return a + shortcut struct, complete with proper value for execute */ +sc *strtosc(int menu, char *input) +{ + sc *s; + + s = (sc *)nmalloc(sizeof(sc)); + s->execute = TRUE; /* overridden as needed below */ + + if (!strcasecmp(input, "help")) + s->scfunc = do_help_void; + else if (!strcasecmp(input, "cancel")) { + s->scfunc = (void *) cancel_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "exit")) + s->scfunc = do_exit; + else if (!strcasecmp(input, "writeout")) + s->scfunc = do_writeout_void; + else if (!strcasecmp(input, "justify")) + s->scfunc = do_justify_void; + else if (!strcasecmp(input, "insert")) + s->scfunc = do_insertfile_void; + else if (!strcasecmp(input, "whereis")) + s->scfunc = do_search; + else if (!strcasecmp(input, "up")) + s->scfunc = do_page_up; + else if (!strcasecmp(input, "down")) + s->scfunc = do_page_down; + else if (!strcasecmp(input, "cut")) + s->scfunc = do_cut_text_void; + else if (!strcasecmp(input, "uncut")) + s->scfunc = do_uncut_text; + else if (!strcasecmp(input, "curpos") || + !strcasecmp(input, "cursorpos")) + s->scfunc = do_cursorpos_void; + else if (!strcasecmp(input, "firstline")) + s->scfunc = do_first_line; + else if (!strcasecmp(input, "lastline")) + s->scfunc = do_last_line; + else if (!strcasecmp(input, "gotoline")) + s->scfunc = do_gotolinecolumn_void; + else if (!strcasecmp(input, "replace")) + s->scfunc = do_replace; + else if (!strcasecmp(input, "mark")) + s->scfunc = do_mark; + else if (!strcasecmp(input, "searchagain") || + !strcasecmp(input, "research")) + s->scfunc = do_research; + else if (!strcasecmp(input, "copytext")) + s->scfunc = do_copy_text; + else if (!strcasecmp(input, "indent")) + s->scfunc = do_indent_void; + else if (!strcasecmp(input, "unindent")) + s->scfunc = do_unindent; + else if (!strcasecmp(input, "right") || + !strcasecmp(input, "forward")) + s->scfunc = do_right; + else if (!strcasecmp(input, "left") || + !strcasecmp(input, "back")) + s->scfunc = do_left; + else if (!strcasecmp(input, "nextword")) + s->scfunc = do_next_word_void; + else if (!strcasecmp(input, "prevword")) + s->scfunc = do_prev_word_void; + else if (!strcasecmp(input, "up") || + !strcasecmp(input, "prevline")) + s->scfunc = do_up_void; + else if (!strcasecmp(input, "down") || + !strcasecmp(input, "nextline")) + s->scfunc = do_down_void; + else if (!strcasecmp(input, "home")) + s->scfunc = do_home; + else if (!strcasecmp(input, "end")) + s->scfunc = do_end; + else if (!strcasecmp(input, "beginpara")) + s->scfunc = do_para_begin_void; + else if (!strcasecmp(input, "endpara")) + s->scfunc = do_para_end_void; + else if (!strcasecmp(input, "findbracket")) + s->scfunc = do_find_bracket; + else if (!strcasecmp(input, "scrollup")) + s->scfunc = do_scroll_up; + else if (!strcasecmp(input, "scrolldown")) + s->scfunc = do_scroll_down; +#ifdef ENABLE_MULTIBUFFER + else if (!strcasecmp(input, "prevbuf")) + s->scfunc = switch_to_prev_buffer_void; + else if (!strcasecmp(input, "nextbuf")) + s->scfunc = switch_to_next_buffer_void; +#endif + else if (!strcasecmp(input, "verbatim")) + s->scfunc = do_verbatim_input; + else if (!strcasecmp(input, "tab")) + s->scfunc = do_tab; + else if (!strcasecmp(input, "enter")) + s->scfunc = do_enter; + else if (!strcasecmp(input, "delete")) + s->scfunc = do_delete; + else if (!strcasecmp(input, "fulljustify")) + s->scfunc = do_full_justify; + else if (!strcasecmp(input, "wordcount")) + s->scfunc = do_wordlinechar_count; + else if (!strcasecmp(input, "refresh")) + s->scfunc = total_refresh; + else if (!strcasecmp(input, "casesens")) { + s->scfunc = (void *) case_sens_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "regexp") || + !strcasecmp(input, "regex")) { + s->scfunc = (void *) regexp_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "prevhistory")) { + s->scfunc = (void *) prev_history_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "nexthistory")) { + s->scfunc = (void *) next_history_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "dontreplace")) { + s->scfunc = (void *) no_replace_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "gototext")) { + s->scfunc = (void *) gototext_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "browser") || + !strcasecmp(input, "tofiles")) { + s->scfunc = (void *) to_files_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "dosformat")) { + s->scfunc = (void *) dos_format_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "macformat")) { + s->scfunc = (void *) mac_format_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "append")) { + s->scfunc = (void *) append_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "prepend")) { + s->scfunc = (void *) prepend_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "backup")) { + s->scfunc = (void *) backup_file_msg; + s->execute = FALSE; +#ifdef ENABLE_MULTIBUFFER + } else if (!strcasecmp(input, "newbuffer")) { + s->scfunc = (void *) new_buffer_msg; + s->execute = FALSE; +#endif + } else if (!strcasecmp(input, "firstfile")) { + s->scfunc = (void *) first_file_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "lastfile")) { + s->scfunc = (void *) last_file_msg; + s->execute = FALSE; + } else if (!strcasecmp(input, "nohelp") || + !strcasecmp(input, "nohelp")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = NO_HELP; + } else if (!strcasecmp(input, "constupdate")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = CONST_UPDATE; + } else if (!strcasecmp(input, "morespace")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = MORE_SPACE; + } else if (!strcasecmp(input, "smoothscroll")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = SMOOTH_SCROLL; + } else if (!strcasecmp(input, "whitesplacedisplay")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = WHITESPACE_DISPLAY; + } else if (!strcasecmp(input, "nosyntax")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = NO_COLOR_SYNTAX; + } else if (!strcasecmp(input, "smarthome")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = SMART_HOME; + } else if (!strcasecmp(input, "autoindent")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = AUTOINDENT; + } else if (!strcasecmp(input, "cuttoend")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = CUT_TO_END; + } else if (!strcasecmp(input, "nowrap")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = NO_WRAP; + } else if (!strcasecmp(input, "tabstospaces")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = TABS_TO_SPACES; + } else if (!strcasecmp(input, "backupfile")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = BACKUP_FILE; + } else if (!strcasecmp(input, "mutlibuffer")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = MULTIBUFFER; + } else if (!strcasecmp(input, "mouse")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = USE_MOUSE; + } else if (!strcasecmp(input, "noconvert")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = NO_CONVERT; + } else if (!strcasecmp(input, "suspend")) { + s->scfunc = (void *) do_toggle; + s->execute = FALSE; + s->toggle = SUSPEND; } else { - for (u = toggles; u->next != NULL; u = u->next) - ; - u->next = (toggle *)nmalloc(sizeof(toggle)); - u = u->next; + free(s); + return NULL; } - u->val = val; -#ifndef DISABLE_HELP - u->desc = (desc == NULL) ? "" : _(desc); - u->blank_after = blank_after; -#endif - u->flag = flag; - u->next = NULL; + return s; + } -/* Initialize the global toggle list. */ -void toggle_init(void) +/* Same thing as abnove but for the menu */ +int strtomenu(char *input) { - /* There is no need to reinitialize the toggles. They can't - * change. */ - if (toggles != NULL) - return; + if (!strcasecmp(input, "all")) + return MALL; + 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") || + !strcasecmp(input, "replacewith")) + return MREPLACE2; + 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") || + !strcasecmp(input, "extcmd")) + return MEXTCMD; + else if (!strcasecmp(input, "help")) + return MHELP; + else if (!strcasecmp(input, "spell")) + return MSPELL; + else if (!strcasecmp(input, "browser")) + return MBROWSER; + else if (!strcasecmp(input, "whereisfile")) + return MWHEREISFILE; + else if (!strcasecmp(input, "gotodir")) + return MGOTODIR; -/* The following macro is to be used in calling toggle_init_one(). The - * point is that toggle_init_one() takes 4 arguments, unless - * DISABLE_HELP is defined, when the 2nd and 3rd ones should not be - * there. */ -#ifndef DISABLE_HELP -#define IFTHELP(help, blank, nextvar) help, blank, nextvar -#else -#define IFTHELP(help, blank, nextvar) nextvar -#endif - - toggle_init_one(TOGGLE_NOHELP_KEY, IFTHELP(N_("Help mode"), FALSE, - NO_HELP)); - - toggle_init_one(TOGGLE_CONST_KEY, - IFTHELP(N_("Constant cursor position display"), FALSE, - CONST_UPDATE)); - - toggle_init_one(TOGGLE_MORESPACE_KEY, - IFTHELP(N_("Use of one more line for editing"), FALSE, - MORE_SPACE)); - - toggle_init_one(TOGGLE_SMOOTH_KEY, -#ifdef ENABLE_NANORC - IFTHELP(N_("Smooth scrolling"), FALSE, SMOOTH_SCROLL) -#else - IFTHELP(N_("Smooth scrolling"), TRUE, SMOOTH_SCROLL) -#endif - ); - -#ifdef ENABLE_NANORC - toggle_init_one(TOGGLE_WHITESPACE_KEY, -#ifdef ENABLE_COLOR - IFTHELP(N_("Whitespace display"), FALSE, WHITESPACE_DISPLAY) -#else - IFTHELP(N_("Whitespace display"), TRUE, WHITESPACE_DISPLAY) -#endif - ); -#endif - -#ifdef ENABLE_COLOR - toggle_init_one(TOGGLE_SYNTAX_KEY, - IFTHELP(N_("Color syntax highlighting"), TRUE, NO_COLOR_SYNTAX)); -#endif - - toggle_init_one(TOGGLE_SMARTHOME_KEY, IFTHELP(N_("Smart home key"), - FALSE, SMART_HOME)); - - toggle_init_one(TOGGLE_AUTOINDENT_KEY, IFTHELP(N_("Auto indent"), - FALSE, AUTOINDENT)); - - toggle_init_one(TOGGLE_CUTTOEND_KEY, IFTHELP(N_("Cut to end"), - FALSE, CUT_TO_END)); - -#ifndef DISABLE_WRAPPING - toggle_init_one(TOGGLE_WRAP_KEY, IFTHELP(N_("Long line wrapping"), - FALSE, NO_WRAP)); -#endif - - toggle_init_one(TOGGLE_TABSTOSPACES_KEY, -#ifndef DISABLE_MOUSE - IFTHELP(N_("Conversion of typed tabs to spaces"), TRUE, - TABS_TO_SPACES) -#else - IFTHELP(N_("Conversion of typed tabs to spaces"), - !ISSET(RESTRICTED) ? TRUE : FALSE, TABS_TO_SPACES) -#endif - ); - - /* If we're using restricted mode, the backup toggle is disabled. - * It's useless since backups are disabled. */ - if (!ISSET(RESTRICTED)) - toggle_init_one(TOGGLE_BACKUP_KEY, IFTHELP(N_("Backup files"), - FALSE, BACKUP_FILE)); - -#ifdef ENABLE_MULTIBUFFER - /* If we're using restricted mode, the multibuffer toggle is - * disabled. It's useless since inserting files is disabled. */ - if (!ISSET(RESTRICTED)) - toggle_init_one(TOGGLE_MULTIBUFFER_KEY, - IFTHELP(N_("Multiple file buffers"), FALSE, - MULTIBUFFER)); -#endif - -#ifndef DISABLE_MOUSE - toggle_init_one(TOGGLE_MOUSE_KEY, IFTHELP(N_("Mouse support"), - FALSE, USE_MOUSE)); -#endif - - /* If we're using restricted mode, the DOS/Mac conversion toggle is - * disabled. It's useless since inserting files is disabled. */ - if (!ISSET(RESTRICTED)) - toggle_init_one(TOGGLE_NOCONVERT_KEY, - IFTHELP(N_("No conversion from DOS/Mac format"), FALSE, - NO_CONVERT)); - - /* If we're using restricted mode, the suspend toggle is disabled. - * It's useless since suspending is disabled. */ - if (!ISSET(RESTRICTED)) - toggle_init_one(TOGGLE_SUSPEND_KEY, IFTHELP(N_("Suspension"), - FALSE, SUSPEND)); + return -1; } -#endif /* !NANO_TINY */ + + +#endif #ifdef DEBUG /* This function is used to gracefully return all the memory we've used. @@ -1419,26 +1466,6 @@ void thanks_for_all_the_fish(void) #ifndef DISABLE_JUSTIFY if (jusbuffer != NULL) free_filestruct(jusbuffer); -#endif - free_shortcutage(&main_list); - free_shortcutage(&whereis_list); - free_shortcutage(&replace_list); - free_shortcutage(&replace_list_2); - free_shortcutage(&gotoline_list); - free_shortcutage(&writefile_list); - free_shortcutage(&insertfile_list); -#ifndef NANO_TINY - free_shortcutage(&extcmd_list); -#endif -#ifndef DISABLE_HELP - free_shortcutage(&help_list); -#endif -#ifndef DISABLE_SPELLER - free_shortcutage(&spell_list); -#endif -#ifndef DISABLE_BROWSER - free_shortcutage(&browser_list); - free_shortcutage(&gotodir_list); #endif #ifndef NANO_TINY /* Free the memory associated with each toggle. */ @@ -1504,3 +1531,4 @@ void thanks_for_all_the_fish(void) #endif } #endif /* DEBUG */ + diff --git a/src/help.c b/src/help.c index 803cf122..3e21e66f 100644 --- a/src/help.c +++ b/src/help.c @@ -47,13 +47,15 @@ void do_help(void (*refresh_func)(void)) /* The line number in help_text of the last help line. This * variable is zero-based. */ #ifndef DISABLE_MOUSE - const shortcut *oldshortcut = currshortcut; /* The current shortcut list. */ + int oldmenu = currmenu; #endif const char *ptr; /* The current line of the help text. */ size_t old_line = (size_t)-1; /* The line we were on before the current line. */ + const sc *s; + const subnfunc *f; curs_set(0); blank_edit(); @@ -66,9 +68,9 @@ void do_help(void (*refresh_func)(void)) assert(help_text != NULL); #ifndef DISABLE_MOUSE - /* Set currshortcut to allow clicking on the help screen's shortcut + /* Set currmenu to allow clicking on the help screen's shortcut * list, after help_init() is called. */ - currshortcut = help_list; + currmenu = MHELP; #endif if (ISSET(NO_HELP)) { @@ -78,7 +80,7 @@ void do_help(void (*refresh_func)(void)) window_init(); } - bottombars(help_list); + bottombars(MHELP); wnoutrefresh(bottomwin); /* Get the last line of the help text. */ @@ -127,57 +129,57 @@ void do_help(void (*refresh_func)(void)) kbinput = get_kbinput(edit, &meta_key, &func_key); parse_help_input(&kbinput, &meta_key, &func_key); - switch (kbinput) { + s = get_shortcut(MMAIN, &kbinput, &meta_key, &func_key); + if (!s) + continue; + f = sctofunc(s); + if (!f) + continue; + + + if (f->scfunc == (void *) do_mouse) { #ifndef DISABLE_MOUSE - case KEY_MOUSE: - { int mouse_x, mouse_y; get_mouseinput(&mouse_x, &mouse_y, TRUE); - } - break; #endif /* Redraw the screen. */ - case NANO_REFRESH_KEY: + } else if (f->scfunc == total_refresh) { total_redraw(); break; - case NANO_PREVPAGE_KEY: + } else if (f->scfunc == do_page_up) { if (line > editwinrows - 2) line -= editwinrows - 2; else line = 0; - break; - case NANO_NEXTPAGE_KEY: + } else if (f->scfunc == do_page_down) { if (line + (editwinrows - 1) < last_line) line += editwinrows - 2; - break; - case NANO_PREVLINE_KEY: + } else if (f->scfunc == do_up_void) { if (line > 0) line--; - break; - case NANO_NEXTLINE_KEY: + } else if (f->scfunc == do_down_void) { if (line + (editwinrows - 1) < last_line) line++; - break; - case NANO_FIRSTLINE_METAKEY: + } else if (f->scfunc == do_first_line) { if (meta_key) line = 0; break; - case NANO_LASTLINE_METAKEY: + } else if (f->scfunc == do_last_line) { if (meta_key) { if (line + (editwinrows - 1) < last_line) line = last_line - (editwinrows - 1); } break; /* Abort the help browser. */ - case NANO_EXIT_KEY: + } else if (f->scfunc == do_exit) { abort = TRUE; break; } } #ifndef DISABLE_MOUSE - currshortcut = oldshortcut; + currmenu = oldmenu; #endif if (old_no_help) { @@ -186,7 +188,7 @@ void do_help(void (*refresh_func)(void)) SET(NO_HELP); window_init(); } else - bottombars(currshortcut); + bottombars(currmenu); curs_set(1); refresh_func(); @@ -222,9 +224,11 @@ void help_init(void) * full string is too long for the * compiler to handle. */ char *ptr; - const shortcut *s; + const subnfunc *f; + const sc *s; + int scsfound = 0; + #ifndef NANO_TINY - const toggle *t; #ifdef ENABLE_NANORC bool old_whitespace = ISSET(WHITESPACE_DISPLAY); @@ -233,8 +237,7 @@ void help_init(void) #endif /* First, set up the initial help text for the current function. */ - if (currshortcut == whereis_list || currshortcut == replace_list || - currshortcut == replace_list_2) { + if (currmenu == MWHEREIS || currmenu == MREPLACE || currmenu == MREPLACE2) { htx[0] = N_("Search Command Help Text\n\n " "Enter the words or characters you would like to " "search for, and then press Enter. If there is a " @@ -249,7 +252,7 @@ void help_init(void) "will be replaced.\n\n The following function keys are " "available in Search mode:\n\n"); htx[2] = NULL; - } else if (currshortcut == gotoline_list) { + } else if (currmenu == MGOTOLINE) { htx[0] = N_("Go To Line Help Text\n\n " "Enter the line number that you wish to go to and hit " "Enter. If there are fewer lines of text than the " @@ -258,7 +261,7 @@ void help_init(void) "available in Go To Line mode:\n\n"); htx[1] = NULL; htx[2] = NULL; - } else if (currshortcut == insertfile_list) { + } else if (currmenu == MINSERTFILE) { htx[0] = N_("Insert File Help Text\n\n " "Type in the name of a file to be inserted into the " "current file buffer at the current cursor " @@ -273,7 +276,7 @@ void help_init(void) "the prompt and press Enter.\n\n The following " "function keys are available in Insert File mode:\n\n"); htx[2] = NULL; - } else if (currshortcut == writefile_list) { + } else if (currmenu == MWRITEFILE) { htx[0] = N_("Write File Help Text\n\n " "Type the name that you wish to save the current file " "as and press Enter to save the file.\n\n If you have " @@ -287,7 +290,7 @@ void help_init(void) htx[2] = NULL; } #ifndef DISABLE_BROWSER - else if (currshortcut == browser_list) { + else if (currmenu == MBROWSER) { htx[0] = N_("File Browser Help Text\n\n " "The file browser is used to visually browse the " "directory structure to select a file for reading " @@ -300,7 +303,7 @@ void help_init(void) "in the file browser:\n\n"); htx[1] = NULL; htx[2] = NULL; - } else if (currshortcut == whereis_file_list) { + } else if (currmenu == MWHEREISFILE) { htx[0] = N_("Browser Search Command Help Text\n\n " "Enter the words or characters you would like to " "search for, and then press Enter. If there is a " @@ -313,7 +316,7 @@ void help_init(void) htx[1] = N_(" The following function keys are available in " "Browser Search mode:\n\n"); htx[2] = NULL; - } else if (currshortcut == gotodir_list) { + } else if (currmenu == MGOTODIR) { htx[0] = N_("Browser Go To Directory Help Text\n\n " "Enter the name of the directory you would like to " "browse to.\n\n If tab completion has not been " @@ -326,7 +329,7 @@ void help_init(void) } #endif /* !DISABLE_BROWSER */ #ifndef DISABLE_SPELLER - else if (currshortcut == spell_list) { + else if (currmenu == MSPELL) { htx[0] = N_("Spell Check Help Text\n\n " "The spell checker checks the spelling of all text in " "the current file. When an unknown word is " @@ -341,7 +344,7 @@ void help_init(void) } #endif /* !DISABLE_SPELLER */ #ifndef NANO_TINY - else if (currshortcut == extcmd_list) { + else if (currmenu == MEXTCMD) { htx[0] = N_("Execute Command Help Text\n\n " "This mode allows you to insert the output of a " "command run by the shell into the current buffer (or " @@ -397,18 +400,21 @@ void help_init(void) /* Count the shortcut help text. Each entry has up to three keys, * which fill 24 columns, plus translated text, plus one or two * \n's. */ - for (s = currshortcut; s != NULL; s = s->next) - allocsize += (24 * mb_cur_max()) + strlen(s->help) + 2; + for (f = allfuncs; f != NULL; f = f->next) + if (f->menus & currmenu) + allocsize += (24 * mb_cur_max()) + strlen(f->help) + 2; #ifndef NANO_TINY /* If we're on the main list, we also count the toggle help text. * Each entry has "M-%c\t\t\t", which fills 24 columns, plus a * space, plus translated text, plus one or two '\n's. */ - if (currshortcut == main_list) { + if (currmenu == MMAIN) { size_t endis_len = strlen(_("enable/disable")); - for (t = toggles; t != NULL; t = t->next) - allocsize += strlen(t->desc) + endis_len + 9; + for (s = sclist; s != NULL; s = s->next) + if (s->scfunc == (void *) do_toggle) + allocsize += strlen(flagtostr(s->toggle)) + endis_len + 9; + } #endif @@ -429,131 +435,55 @@ void help_init(void) ptr = help_text + strlen(help_text); - /* Now add our shortcut info. Assume that each shortcut has, at the - * very least, an equivalent control key, an equivalent primary meta - * key sequence, or both. Also assume that the meta key values are - * not control characters. We can display a maximum of three - * shortcut entries. */ - for (s = currshortcut; s != NULL; s = s->next) { - int entries = 0; + /* Now add our shortcut info. */ + for (f = allfuncs; f != NULL; f = f->next) { - /* Control key. */ - if (s->ctrlval != NANO_NO_KEY) { - entries++; - /* Yucky sentinel values that we can't handle a better - * way. */ - if (s->ctrlval == NANO_CONTROL_SPACE) { - char *space_ptr = display_string(_("Space"), 0, 14, - FALSE); + if ((f->menus & currmenu) == 0) + continue; - if (s->funcval == NANO_NO_KEY && (s->metaval == - NANO_NO_KEY || s->miscval == NANO_NO_KEY)) { - /* If we're here, we have at least two entries worth - * of blank space. If this entry takes up more than - * one entry's worth of space, use two to display - * it. */ - if (mbstrlen(space_ptr) > 6) - entries++; - } else - /* Otherwise, truncate it so that it takes up only - * one entry's worth of space. */ - space_ptr[6] = '\0'; + if (!f->desc || !strcmp(f->desc, "")) + continue; - ptr += sprintf(ptr, "^%s", space_ptr); + /* Lets just try and use the first 3 shortcuts + from the new struct... */ + for (s = sclist, scsfound = 0; s != NULL; s = s->next) { - free(space_ptr); - } else if (s->ctrlval == NANO_CONTROL_8) - ptr += sprintf(ptr, "^?"); - /* Normal values. */ - else - ptr += sprintf(ptr, "^%c", s->ctrlval + 64); - *(ptr++) = '\t'; - } + if (scsfound == 3) + continue; - /* Function key. */ - if (s->funcval != NANO_NO_KEY) { - entries++; - /* If this is the first entry, put it in the middle. */ - if (entries == 1) { - entries++; + if ((s->menu & currmenu) == 0) + continue; + + if (s->scfunc == f->scfunc) { + scsfound++; + + if (scsfound == 1) + ptr += sprintf(ptr, "%s", s->keystr); + else + ptr += sprintf(ptr, "(%s)", s->keystr); *(ptr++) = '\t'; } - ptr += sprintf(ptr, "(F%d)", s->funcval - KEY_F0); - *(ptr++) = '\t'; } - - /* Primary meta key sequence. If it's the first entry, don't - * put parentheses around it. */ - if (s->metaval != NANO_NO_KEY) { - entries++; - /* If this is the last entry, put it at the end. */ - if (entries == 2 && s->miscval == NANO_NO_KEY) { - entries++; - *(ptr++) = '\t'; - } - /* Yucky sentinel values that we can't handle a better - * way. */ - if (s->metaval == NANO_META_SPACE && entries == 1) { - char *space_ptr = display_string(_("Space"), 0, 13, - FALSE); - - /* If we're here, we have at least two entries worth of - * blank space. If this entry takes up more than one - * entry's worth of space, use two to display it. */ - if (mbstrlen(space_ptr) > 5) - entries++; - - ptr += sprintf(ptr, "M-%s", space_ptr); - - free(space_ptr); - } else - /* Normal values. */ - ptr += sprintf(ptr, (entries == 1) ? "M-%c" : "(M-%c)", - toupper(s->metaval)); + /* Pad with tabs if we didnt find 3 */ + for (; scsfound < 3; scsfound++) { *(ptr++) = '\t'; } - /* Miscellaneous meta key sequence. */ - if (entries < 3 && s->miscval != NANO_NO_KEY) { - entries++; - /* If this is the last entry, put it at the end. */ - if (entries == 2) { - entries++; - *(ptr++) = '\t'; - } - ptr += sprintf(ptr, "(M-%c)", toupper(s->miscval)); - *(ptr++) = '\t'; - } - - /* If this entry isn't blank, make sure all the help text starts - * at the same place. */ - if (s->ctrlval != NANO_NO_KEY || s->funcval != NANO_NO_KEY || - s->metaval != NANO_NO_KEY || s->miscval != - NANO_NO_KEY) { - while (entries < 3) { - entries++; - *(ptr++) = '\t'; - } - } - /* The shortcut's help text. */ - ptr += sprintf(ptr, "%s\n", s->help); + ptr += sprintf(ptr, "%s\n", f->help); - if (s->blank_after) + if (f->blank_after) ptr += sprintf(ptr, "\n"); } #ifndef NANO_TINY /* And the toggles... */ - if (currshortcut == main_list) { - for (t = toggles; t != NULL; t = t->next) { - ptr += sprintf(ptr, "M-%c\t\t\t%s %s\n", - toupper(t->val), t->desc, _("enable/disable")); + if (currmenu == MMAIN) + for (s = sclist; s != NULL; s = s->next) + if (s->scfunc == (void *) do_toggle) + ptr += sprintf(ptr, "(%s)\t\t\t%s %s\n", + s->keystr, flagtostr(s->toggle), _("enable/disable")); - if (t->blank_after) - ptr += sprintf(ptr, "\n"); - } - } #ifdef ENABLE_NANORC if (old_whitespace) @@ -573,7 +503,7 @@ void help_init(void) * shortcut keys. */ void parse_help_input(int *kbinput, bool *meta_key, bool *func_key) { - get_shortcut(help_list, kbinput, meta_key, func_key); + get_shortcut(MHELP, kbinput, meta_key, func_key); if (!*meta_key) { switch (*kbinput) { diff --git a/src/nano.c b/src/nano.c index b676fc93..38af9b2b 100644 --- a/src/nano.c +++ b/src/nano.c @@ -1174,7 +1174,7 @@ RETSIGTYPE handle_sigwinch(int signal) /* Redraw the contents of the windows that need it. */ blank_statusbar(); wnoutrefresh(bottomwin); - currshortcut = main_list; + currmenu = MMAIN; total_refresh(); /* Jump back to either main() or the unjustify routine in @@ -1196,52 +1196,54 @@ void allow_pending_sigwinch(bool allow) #ifndef NANO_TINY /* Handle the global toggle specified in which. */ -void do_toggle(const toggle *which) +void do_toggle(int flag) { bool enabled; + char *desc; - TOGGLE(which->flag); + TOGGLE(flag); - switch (which->val) { + switch (flag) { #ifndef DISABLE_MOUSE - case TOGGLE_MOUSE_KEY: + case USE_MOUSE: mouse_init(); break; #endif - case TOGGLE_MORESPACE_KEY: - case TOGGLE_NOHELP_KEY: + case MORE_SPACE: + case NO_HELP: window_init(); total_refresh(); break; - case TOGGLE_SUSPEND_KEY: + case SUSPEND: signal_init(); break; #ifdef ENABLE_NANORC - case TOGGLE_WHITESPACE_KEY: + case WHITESPACE_DISPLAY: titlebar(NULL); edit_refresh(); break; #endif #ifdef ENABLE_COLOR - case TOGGLE_SYNTAX_KEY: + case NO_COLOR_SYNTAX: edit_refresh(); break; #endif } - enabled = ISSET(which->flag); + enabled = ISSET(flag); - if (which->val == TOGGLE_NOHELP_KEY + if (flag == NO_HELP #ifndef DISABLE_WRAPPING - || which->val == TOGGLE_WRAP_KEY + || flag == NO_WRAP #endif #ifdef ENABLE_COLOR - || which->val == TOGGLE_SYNTAX_KEY + || flag == NO_COLOR_SYNTAX #endif ) enabled = !enabled; - statusbar("%s %s", which->desc, enabled ? _("enabled") : + desc = flagtostr(flag); + statusbar("%s %s", desc, enabled ? _("enabled") : _("disabled")); } #endif /* !NANO_TINY */ @@ -1368,12 +1370,8 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool /* The length of the input buffer. */ bool cut_copy = FALSE; /* Are we cutting or copying text? */ - const shortcut *s; + const sc *s; bool have_shortcut; -#ifndef NANO_TINY - const toggle *t; - bool have_toggle; -#endif *s_or_t = FALSE; *ran_func = FALSE; @@ -1399,32 +1397,15 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool #endif /* Check for a shortcut in the main list. */ - s = get_shortcut(main_list, &input, meta_key, func_key); + s = get_shortcut(MMAIN, &input, meta_key, func_key); /* If we got a shortcut from the main list, or a "universal" * edit window shortcut, set have_shortcut to TRUE. */ - have_shortcut = (s != NULL || input == NANO_XON_KEY || - input == NANO_XOFF_KEY || input == NANO_SUSPEND_KEY); - -#ifndef NANO_TINY - /* Check for a toggle in the main list. */ - t = get_toggle(input, *meta_key); - - /* If we got a toggle from the main list, set have_toggle to - * TRUE. */ - have_toggle = (t != NULL); -#endif - - /* Set s_or_t to TRUE if we got a shortcut or toggle. */ - *s_or_t = (have_shortcut -#ifndef NANO_TINY - || have_toggle -#endif - ); + have_shortcut = (s != NULL || input == NANO_SUSPEND_KEY); /* If we got a non-high-bit control key, a meta key sequence, or a * function key, and it's not a shortcut or toggle, throw it out. */ - if (!*s_or_t) { + if (!have_shortcut) { if (is_ascii_cntrl_char(input) || *meta_key || *func_key) { statusbar(_("Unknown Command")); beep(); @@ -1439,7 +1420,7 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool * it's a normal text character. Display the warning if we're * in view mode, or add the character to the input buffer if * we're not. */ - if (input != ERR && !*s_or_t) { + if (input != ERR && !have_shortcut) { if (ISSET(VIEW_MODE)) print_view_warning(); else { @@ -1455,12 +1436,12 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool * output all the characters in the input buffer if it isn't * empty. Note that it should be empty if we're in view * mode. */ - if (*s_or_t || get_key_buffer_len() == 0) { + if (have_shortcut || get_key_buffer_len() == 0) { #ifndef DISABLE_WRAPPING /* If we got a shortcut or toggle, and it's not the shortcut * for verbatim input, turn off prepending of wrapped * text. */ - if (*s_or_t && (!have_shortcut || s == NULL || s->func != + if (have_shortcut && (!have_shortcut || s == NULL || s->scfunc != do_verbatim_input)) wrap_reset(); #endif @@ -1489,12 +1470,6 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool if (have_shortcut) { switch (input) { /* Handle the "universal" edit window shortcuts. */ - case NANO_XON_KEY: - statusbar(_("XON ignored, mumble mumble")); - break; - case NANO_XOFF_KEY: - statusbar(_("XOFF ignored, mumble mumble")); - break; case NANO_SUSPEND_KEY: if (ISSET(SUSPEND)) do_suspend(0); @@ -1507,32 +1482,31 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool default: /* If the function associated with this shortcut is * cutting or copying text, indicate this. */ - if (s->func == do_cut_text_void + if (s->scfunc == do_cut_text_void #ifndef NANO_TINY - || s->func == do_copy_text || s->func == + || s->scfunc == do_copy_text || s->scfunc == do_cut_till_end #endif ) cut_copy = TRUE; - if (s->func != NULL) { + if (s->scfunc != NULL) { + const subnfunc *f = sctofunc((sc *) s); *ran_func = TRUE; - if (ISSET(VIEW_MODE) && !s->viewok) + if (ISSET(VIEW_MODE) && f && !f->viewok) print_view_warning(); else - s->func(); +#ifndef NANO_TINY + if (s->scfunc == (void *) do_toggle) + do_toggle(s->toggle); + else +#endif + s->scfunc(); } *finished = TRUE; break; } } -#ifndef NANO_TINY - else if (have_toggle) { - /* Toggle the flag associated with this shortcut. */ - if (allow_funcs) - do_toggle(t); - } -#endif } /* If we aren't cutting or copying text, blow away the text in the @@ -1543,6 +1517,17 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool return input; } +void xon_complaint(void) +{ + statusbar(_("XON ignored, mumble mumble")); +} + +void xoff_complaint(void) +{ + statusbar(_("XOFF ignored, mumble mumble")); +} + + #ifndef DISABLE_MOUSE /* Handle a mouse click on the edit window or the shortcut list. */ int do_mouse(void) @@ -1991,6 +1976,11 @@ int main(int argc, char **argv) #endif } + + /* Set up the shortcut lists. + Need to do this before the rcfile */ + shortcut_init(FALSE); + /* We've read through the command line options. Now back up the flags * and values that are set, and read the rcfile(s). If the values * haven't changed afterward, restore the backed-up values. */ @@ -2029,6 +2019,11 @@ int main(int argc, char **argv) do_rcfile(); +#ifdef DEBUG + fprintf(stderr, "After rebinding keys...\n"); + print_sclist(); +#endif + #ifndef DISABLE_OPERATINGDIR if (operating_dir_cpy != NULL) { free(operating_dir); @@ -2191,9 +2186,6 @@ int main(int argc, char **argv) /* Set up the signal handlers. */ signal_init(); - /* Set up the shortcut lists. */ - shortcut_init(FALSE); - #ifndef DISABLE_MOUSE /* Initialize mouse support. */ mouse_init(); @@ -2302,7 +2294,7 @@ int main(int argc, char **argv) if (ISSET(CONST_UPDATE) && get_key_buffer_len() == 0) do_cursorpos(TRUE); - currshortcut = main_list; + currmenu = MMAIN; /* Read in and interpret characters. */ do_input(&meta_key, &func_key, &s_or_t, &ran_func, &finished, diff --git a/src/nano.h b/src/nano.h index 370d6d33..2688e9ba 100644 --- a/src/nano.h +++ b/src/nano.h @@ -165,6 +165,10 @@ typedef enum { CENTER, NONE } update_type; +typedef enum { + CONTROL, META, FKEY, RAW +} function_type; + /* Structure types. */ typedef struct filestruct { char *data; @@ -340,8 +344,52 @@ typedef struct rcoption { long flag; /* The flag associated with it, if any. */ } rcoption; + #endif +typedef struct sc { + char *keystr; + /* The shortcut key for a function, ASCII version */ + function_type type; + /* What kind of function key is it for convenience later */ + int seq; + /* The actual sequence to check on the the type is determined */ + int menu; + /* What list does this apply to */ + void (*scfunc)(void); + /* The function we're going to run */ + int toggle; + /* If a toggle, what we're toggling */ + bool execute; + /* Whether to execute the function in question or just return + so the sequence can be caught by the calling code */ + struct sc *next; + /* Next in the list */ +} sc; + +typedef struct subnfunc { + void (*scfunc)(void); + /* What function is this */ + int menus; + /* In what menus does this function applu */ + const char *desc; + /* The function's description, e.g. "Page Up". */ +#ifndef DISABLE_HELP + const char *help; + /* The help file entry text for this function. */ + bool blank_after; + /* Whether there should be a blank line after the help entry + * text for this function. */ +#endif + bool viewok; + /* Is this function allowed when in view mode? */ + long toggle; + /* If this is a toggle, if nonzero what toggle to set */ + struct subnfunc *next; + /* next item in the list */ +} subnfunc; + + /* Bitwise flags so that we can save space (or, more correctly, not * waste it). */ #define CASE_SENSITIVE (1<<0) @@ -376,6 +424,23 @@ typedef struct rcoption { #define NO_NEWLINES (1<<29) #define BOLD_TEXT (1<<30) +/* Flags for which menus in which a given function should be present */ +#define MMAIN (1<<0) +#define MWHEREIS (1<<1) +#define MREPLACE (1<<2) +#define MREPLACE2 (1<<3) +#define MGOTOLINE (1<<4) +#define MWRITEFILE (1<<5) +#define MINSERTFILE (1<<6) +#define MEXTCMD (1<<7) +#define MHELP (1<<8) +#define MSPELL (1<<9) +#define MBROWSER (1<<10) +#define MWHEREISFILE (1<<11) +#define MGOTODIR (1<<12) +/* This really isnt all but close enough */ +#define MALL (MMAIN|MWHEREIS|MREPLACE|MREPLACE2|MGOTOLINE|MWRITEFILE|MINSERTFILE|MEXTCMD|MSPELL|MBROWSER|MWHEREISFILE|MGOTODIR|MHELP) + /* Control key sequences. Changing these would be very, very bad. */ #define NANO_CONTROL_SPACE 0 #define NANO_CONTROL_A 1 diff --git a/src/prompt.c b/src/prompt.c index d32c7cb7..083174dc 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -61,7 +61,8 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t, /* The input buffer. */ static size_t kbinput_len = 0; /* The length of the input buffer. */ - const shortcut *s; + const sc *s; + const subnfunc *f; bool have_shortcut; *s_or_t = FALSE; @@ -88,7 +89,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t, #endif /* Check for a shortcut in the current list. */ - s = get_shortcut(currshortcut, &input, meta_key, func_key); + s = get_shortcut(currmenu, &input, meta_key, func_key); /* If we got a shortcut from the current list, or a "universal" * statusbar prompt shortcut, set have_shortcut to TRUE. */ @@ -131,7 +132,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t, * and we're at the "Write File" prompt, disable text * input. */ if (!ISSET(RESTRICTED) || openfile->filename[0] == '\0' || - currshortcut != writefile_list) { + currmenu != MWRITEFILE) { kbinput_len++; kbinput = (int *)nrealloc(kbinput, kbinput_len * sizeof(int)); @@ -181,7 +182,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t, * isn't blank, and we're at the "Write File" * prompt, disable Cut. */ if (!ISSET(RESTRICTED) || openfile->filename[0] == - '\0' || currshortcut != writefile_list) + '\0' || currmenu != MWRITEFILE) do_statusbar_cut_text(); break; case NANO_FORWARD_KEY: @@ -218,7 +219,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t, * prompt, disable verbatim input. */ if (!ISSET(RESTRICTED) || openfile->filename[0] == '\0' || - currshortcut != writefile_list) { + currmenu != MWRITEFILE) { bool got_enter; /* Whether we got the Enter key. */ @@ -241,7 +242,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t, * isn't blank, and we're at the "Write File" * prompt, disable Delete. */ if (!ISSET(RESTRICTED) || openfile->filename[0] == - '\0' || currshortcut != writefile_list) + '\0' || currmenu != MWRITEFILE) do_statusbar_delete(); break; case NANO_BACKSPACE_KEY: @@ -249,7 +250,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t, * isn't blank, and we're at the "Write File" * prompt, disable Backspace. */ if (!ISSET(RESTRICTED) || openfile->filename[0] == - '\0' || currshortcut != writefile_list) + '\0' || currmenu != MWRITEFILE) do_statusbar_backspace(); break; /* Handle the normal statusbar prompt shortcuts, setting @@ -258,10 +259,11 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t, * that we're done after running or trying to run their * associated functions. */ default: - if (s->func != NULL) { + f = sctofunc((sc *) s); + if (s->scfunc != NULL && s->execute == TRUE) { *ran_func = TRUE; - if (!ISSET(VIEW_MODE) || s->viewok) - s->func(); + if (!ISSET(VIEW_MODE) || f->viewok) + f->scfunc(); } *finished = TRUE; } @@ -933,7 +935,7 @@ int get_prompt_string(bool allow_tabs, #ifndef NANO_TINY filestruct **history_list, #endif - void (*refresh_func)(void), const shortcut *s + void (*refresh_func)(void), int menu #ifndef DISABLE_TABCOMP , bool *list #endif @@ -982,7 +984,11 @@ int get_prompt_string(bool allow_tabs, statusbar_pww = statusbar_xplustabs(); } - currshortcut = s; + currmenu = menu; + +#ifdef DEBUG +fprintf(stderr, "get_prompt_string: answer = \"%s\", statusbar_x = %d\n", answer, statusbar_x); +#endif update_statusbar_line(answer, statusbar_x); @@ -1118,6 +1124,7 @@ int get_prompt_string(bool allow_tabs, wnoutrefresh(bottomwin); } + #ifndef NANO_TINY /* Set the current position in the history list to the bottom and * free magichistory, if we need to. */ @@ -1129,6 +1136,7 @@ int get_prompt_string(bool allow_tabs, } #endif + /* We've finished putting in an answer or run a normal shortcut's * associated function, so reset statusbar_x and statusbar_pww. If * we've finished putting in an answer, reset the statusbar cursor @@ -1165,7 +1173,7 @@ int do_prompt(bool allow_tabs, #ifndef DISABLE_TABCOMP bool allow_files, #endif - const shortcut *s, const char *curranswer, + int menu, const char *curranswer, #ifndef NANO_TINY filestruct **history_list, #endif @@ -1184,7 +1192,7 @@ int do_prompt(bool allow_tabs, prompt = charalloc(((COLS - 4) * mb_cur_max()) + 1); - bottombars(s); + bottombars(menu); va_start(ap, msg); vsnprintf(prompt, (COLS - 4) * mb_cur_max(), msg, ap); @@ -1199,7 +1207,7 @@ int do_prompt(bool allow_tabs, #ifndef NANO_TINY history_list, #endif - refresh_func, s + refresh_func, menu #ifndef DISABLE_TABCOMP , &list #endif @@ -1224,6 +1232,7 @@ int do_prompt(bool allow_tabs, break; } + blank_statusbar(); wnoutrefresh(bottomwin); diff --git a/src/proto.h b/src/proto.h index 43b8746c..ab44188a 100644 --- a/src/proto.h +++ b/src/proto.h @@ -91,34 +91,15 @@ extern char *full_operating_dir; extern char *alt_speller; #endif -extern shortcut *main_list; -extern shortcut *whereis_list; -extern shortcut *replace_list; -extern shortcut *replace_list_2; -extern shortcut *gotoline_list; -extern shortcut *writefile_list; -extern shortcut *insertfile_list; -#ifndef NANO_TINY -extern shortcut *extcmd_list; -#endif -#ifndef DISABLE_HELP -extern shortcut *help_list; -#endif -#ifndef DISABLE_SPELLER -extern shortcut *spell_list; -#endif -#ifndef DISABLE_BROWSER -extern shortcut *browser_list; -extern shortcut *whereis_file_list; -extern shortcut *gotodir_list; -#endif - +extern sc *sclist; +extern subnfunc *allfuncs; #ifdef ENABLE_COLOR extern syntaxtype *syntaxes; extern char *syntaxstr; #endif extern const shortcut *currshortcut; +extern int currmenu; #ifndef NANO_TINY extern toggle *toggles; #endif @@ -341,7 +322,7 @@ void save_history(void); #endif /* All functions in global.c. */ -size_t length_of_list(const shortcut *s); +size_t length_of_list(int menu); #ifndef NANO_TINY void toggle_init_one(int val #ifndef DISABLE_HELP @@ -472,7 +453,7 @@ RETSIGTYPE handle_sigwinch(int signal); void allow_pending_sigwinch(bool allow); #endif #ifndef NANO_TINY -void do_toggle(const toggle *which); +void do_toggle(int flag); #endif void disable_extended_io(void); #ifdef USE_SLANG @@ -531,7 +512,7 @@ int get_prompt_string(bool allow_tabs, #ifndef NANO_TINY filestruct **history_list, #endif - void (*refresh_func)(void), const shortcut *s + void (*refresh_func)(void), int menu #ifndef DISABLE_TABCOMP , bool *list #endif @@ -540,7 +521,7 @@ int do_prompt(bool allow_tabs, #ifndef DISABLE_TABCOMP bool allow_files, #endif - const shortcut *s, const char *curranswer, + int menu, const char *curranswer, #ifndef NANO_TINY filestruct **history_list, #endif @@ -753,8 +734,9 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *kbinput_len); #ifndef DISABLE_MOUSE int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts); #endif -const shortcut *get_shortcut(const shortcut *s_list, int *kbinput, bool +const sc *get_shortcut(int menu, int *kbinput, bool *meta_key, bool *func_key); +const sc *first_sc_for(int menu, void *func); #ifndef NANO_TINY const toggle *get_toggle(int kbinput, bool meta_key); #endif @@ -770,7 +752,7 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool void titlebar(const char *path); void set_modified(void); void statusbar(const char *msg, ...); -void bottombars(const shortcut *s); +void bottombars(int menu); void onekey(const char *keystroke, const char *desc, size_t len); void reset_cursor(void); void edit_draw(const filestruct *fileptr, const char *converted, int @@ -788,6 +770,30 @@ void display_main_list(void); void do_cursorpos(bool constant); void do_cursorpos_void(void); void do_replace_highlight(bool highlight, const char *word); +char *flagtostr(int flag); +const subnfunc *sctofunc(sc *s); +void print_sclist(void); +sc *strtosc(int menu, char *input); +function_type strtokeytype(char *str); +int strtomenu(char *input); +void assign_keyinfo(sc *s); +void xon_complaint(void); +void xoff_complaint(void); + + +const char *cancel_msg; +#ifndef NANO_TINY +const char *case_sens_msg; +const char *backwards_msg; +#endif +const char *replace_msg; +const char *no_replace_msg; +const char *go_to_line_msg; + +#ifdef HAVE_REGEX_H +const char *regexp_msg; +#endif + #ifdef NANO_EXTRA void do_credits(void); #endif diff --git a/src/rcfile.c b/src/rcfile.c index 7a4bf26e..c88bc40a 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -347,6 +347,95 @@ void parse_syntax(char *ptr) } } +void parse_keybinding(char *ptr) +{ + char *keyptr = NULL, *keycopy = NULL, *funcptr = NULL, *menuptr = NULL; + sc *s, *newsc; + int i, menu; + + assert(ptr != NULL); + + if (*ptr == '\0') { + rcfile_error(N_("Missing key name")); + return; + } + + keyptr = ptr; + ptr = parse_next_word(ptr); + keycopy = mallocstrcpy(NULL, keyptr); + for (i = 0; i < strlen(keycopy); i++) + keycopy[i] = toupper(keycopy[i]); + + if (keycopy[0] != 'M' && keycopy[0] != '^' && keycopy[0] != 'F') { + rcfile_error( + N_("keybindings must begin with \"^\", \"M\", or \"F\"\n")); + return; + } + + funcptr = ptr; + ptr = parse_next_word(ptr); + + if (funcptr == NULL) { + rcfile_error( + N_("Must specify function to bind key to\n")); + return; + } + + menuptr = ptr; + ptr = parse_next_word(ptr); + + if (menuptr == NULL) { + rcfile_error( + /* Note to translators, do not translate the word "all" + in the sentence below, everything else is fine */ + N_("Must specify menu bind key to (or \"all\")\n")); + return; + } + + menu = strtomenu(menuptr); + if (menu < 1) { + rcfile_error( + N_("Could not map name \"%s\" to a menu\n"), menuptr); + return; + } + + newsc = strtosc(menu, funcptr); +#ifdef DEBUG + fprintf(stderr, "newsc now address %d, menu func assigned = %d, menu = %d\n", + (int) newsc, (int) newsc->scfunc, menu); +#endif + + if (newsc == NULL) { + rcfile_error( + N_("Could not map name \"%s\" to a function\n"), funcptr); + return; + } + newsc->keystr = keycopy; + newsc->menu = menu; + newsc->type = strtokeytype(newsc->keystr); + assign_keyinfo(newsc); +#ifdef DEBUG + fprintf(stderr, "s->keystr = \"%s\"\n", newsc->keystr); + fprintf(stderr, "s->seq = \"%d\"\n", newsc->seq); +#endif + + /* now let's have some fun. Try and delete the other entries + we found for the same menu, then make this new new + beginning */ + for (s = sclist; s != NULL; s = s->next) { + if (((s->menu & newsc->menu) || newsc->menu == MALL) && + (s->seq == newsc->seq)) { + s->menu &= ~newsc->menu; +#ifdef DEBUG + fprintf(stderr, "replaced menu entry %d\n", s->menu); +#endif + } + } + newsc->next = sclist; + sclist = newsc; +} + + /* Read and parse additional syntax files. */ void parse_include(char *ptr) { @@ -674,6 +763,8 @@ void parse_rcfile(FILE *rcstream parse_colors(ptr, FALSE); else if (strcasecmp(keyword, "icolor") == 0) parse_colors(ptr, TRUE); + else if (strcasecmp(keyword, "bind") == 0) + parse_keybinding(ptr); #endif /* ENABLE_COLOR */ else rcfile_error(N_("Command \"%s\" not understood"), keyword); diff --git a/src/search.c b/src/search.c index e80d59a0..29f3c68c 100644 --- a/src/search.c +++ b/src/search.c @@ -136,6 +136,8 @@ int search_init(bool replacing, bool use_answer) { int i = 0; char *buf; + sc *s; + void *func = NULL; static char *backupstring = NULL; /* The search string we'll be using. */ @@ -173,7 +175,7 @@ int search_init(bool replacing, bool use_answer) #ifndef DISABLE_TABCOMP TRUE, #endif - replacing ? replace_list : whereis_list, backupstring, + replacing ? MREPLACE : MWHEREIS, backupstring, #ifndef NANO_TINY &search_history, #endif @@ -201,6 +203,8 @@ int search_init(bool replacing, bool use_answer) #endif _(" (to replace)") : "", buf); + fflush(stderr); + /* Release buf now that we don't need it anymore. */ free(buf); @@ -213,9 +217,13 @@ int search_init(bool replacing, bool use_answer) statusbar(_("Cancelled")); return -1; } else { - switch (i) { - case -2: /* It's an empty string. */ - case 0: /* It's a new string. */ + for (s = sclist; s != NULL; s = s->next) + if ((s->menu & currmenu) && i == s->seq) { + func = s->scfunc; + break; + } + + if (i == -2 || i == 0 ) { #ifdef HAVE_REGEX_H /* Use last_search if answer is an empty string, or * answer if it isn't. */ @@ -223,33 +231,34 @@ int search_init(bool replacing, bool use_answer) last_search : answer)) return -1; #endif - break; + ; #ifndef NANO_TINY - case TOGGLE_CASE_KEY: + } else if (func == (void *) case_sens_msg) { TOGGLE(CASE_SENSITIVE); backupstring = mallocstrcpy(backupstring, answer); return 1; - case TOGGLE_BACKWARDS_KEY: + } else if (func == (void *) backwards_msg) { TOGGLE(BACKWARDS_SEARCH); backupstring = mallocstrcpy(backupstring, answer); return 1; #endif #ifdef HAVE_REGEX_H - case NANO_REGEXP_KEY: + } else if (func == (void *) regexp_msg) { TOGGLE(USE_REGEXP); backupstring = mallocstrcpy(backupstring, answer); return 1; #endif - case NANO_TOOTHERSEARCH_KEY: + } else if (func == (void *) do_replace || + func == (void *) no_replace_msg) { backupstring = mallocstrcpy(backupstring, answer); return -2; /* Call the opposite search function. */ - case NANO_TOGOTOLINE_KEY: + } else if (func == (void *) go_to_line_msg) { do_gotolinecolumn(openfile->current->lineno, openfile->placewewant + 1, TRUE, TRUE, FALSE, TRUE); /* Put answer up on the statusbar and * fall through. */ - default: + } else { return -1; } } @@ -915,7 +924,7 @@ void do_replace(void) #ifndef DISABLE_TABCOMP TRUE, #endif - replace_list_2, last_replace, + MREPLACE2, last_replace, #ifndef NANO_TINY &replace_history, #endif @@ -983,7 +992,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer, #ifndef DISABLE_TABCOMP TRUE, #endif - gotoline_list, use_answer ? ans : "", + MGOTOLINE, use_answer ? ans : "", #ifndef NANO_TINY NULL, #endif diff --git a/src/text.c b/src/text.c index 166c182e..d152a97f 100644 --- a/src/text.c +++ b/src/text.c @@ -1854,7 +1854,7 @@ bool do_int_spell_fix(const char *word) #ifndef DISABLE_TABCOMP TRUE, #endif - spell_list, word, + MSPELL, word, #ifndef NANO_TINY NULL, #endif @@ -2337,7 +2337,7 @@ void do_spell(void) unlink(temp); free(temp); - currshortcut = main_list; + currmenu = MMAIN; /* If the spell-checker printed any error messages onscreen, make * sure that they're cleared off. */ diff --git a/src/winio.c b/src/winio.c index b205b1df..77e6172e 100644 --- a/src/winio.c +++ b/src/winio.c @@ -1,3 +1,4 @@ + /* $Id$ */ /************************************************************************** * winio.c * @@ -328,6 +329,7 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key) *meta_key = FALSE; *func_key = FALSE; + const sc *s; /* Read in a character. */ while ((kbinput = get_input(win, 1)) == NULL); @@ -492,49 +494,100 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key) NANO_BACKSPACE_KEY; break; case KEY_DOWN: - retval = NANO_NEXTLINE_KEY; +#ifdef KEY_SDOWN + /* ncurses and Slang don't support KEY_SDOWN. */ + case KEY_SDOWN: +#endif + s = first_sc_for(currmenu, (void *) do_down_void); + if (s) + retval = s->seq; break; case KEY_UP: - retval = NANO_PREVLINE_KEY; +#ifdef KEY_SUP + /* ncurses and Slang don't support KEY_SUP. */ + case KEY_SUP: +#endif + s = first_sc_for(currmenu, (void *) do_up_void); + if (s) + retval = s->seq; break; case KEY_LEFT: - retval = NANO_BACK_KEY; +#ifdef KEY_SLEFT + /* Slang doesn't support KEY_SLEFT. */ + case KEY_SLEFT: +#endif + s = first_sc_for(currmenu, (void *) do_up_void); + if (s) + retval = s->seq; break; case KEY_RIGHT: - retval = NANO_FORWARD_KEY; +#ifdef KEY_SRIGHT + /* Slang doesn't support KEY_SRIGHT. */ + case KEY_SRIGHT: +#endif + s = first_sc_for(currmenu, (void *) do_right); + if (s) + retval = s->seq; break; #ifdef KEY_HOME /* HP-UX 10-11 doesn't support KEY_HOME. */ case KEY_HOME: - retval = NANO_HOME_KEY; - break; #endif - case KEY_BACKSPACE: - retval = NANO_BACKSPACE_KEY; - break; - case KEY_DC: - retval = ISSET(REBIND_DELETE) ? NANO_BACKSPACE_KEY : - NANO_DELETE_KEY; - break; - case KEY_IC: - retval = NANO_INSERTFILE_KEY; - break; - case KEY_NPAGE: - retval = NANO_NEXTPAGE_KEY; - break; - case KEY_PPAGE: - retval = NANO_PREVPAGE_KEY; - break; - case KEY_ENTER: - retval = NANO_ENTER_KEY; - break; +#ifdef KEY_SHOME + /* HP-UX 10-11 and Slang don't support KEY_SHOME. */ + case KEY_SHOME: +#endif case KEY_A1: /* Home (7) on numeric keypad with * NumLock off. */ - retval = NANO_HOME_KEY; + s = first_sc_for(currmenu, (void *) do_home); + if (s) + retval = s->seq; break; + case KEY_BACKSPACE: + s = first_sc_for(currmenu, (void *) do_backspace); + if (s) + retval = s->seq; + break; + case KEY_DC: +#ifdef KEY_SDC + /* Slang doesn't support KEY_SDC. */ + case KEY_SDC: +#endif + if (ISSET(REBIND_DELETE)) + s = first_sc_for(currmenu, (void *) do_delete); + else + s = first_sc_for(currmenu, (void *) do_backspace); + + if (s) + retval = s->seq; + break; + case KEY_IC: +#ifdef KEY_SIC + /* Slang doesn't support KEY_SIC. */ + case KEY_SIC: +#endif + s = first_sc_for(currmenu, (void *) do_insertfile_void); + if (s) + retval = s->seq; + break; + case KEY_NPAGE: + case KEY_C3: /* PageDown (4) on numeric keypad with + * NumLock off. */ + s = first_sc_for(currmenu, (void *) do_page_down); + if (s) + retval = s->seq; + break; + case KEY_PPAGE: case KEY_A3: /* PageUp (9) on numeric keypad with * NumLock off. */ - retval = NANO_PREVPAGE_KEY; + s = first_sc_for(currmenu, (void *) do_page_up); + if (s) + retval = s->seq; + break; + case KEY_ENTER: + s = first_sc_for(currmenu, (void *) do_enter); + if (s) + retval = s->seq; break; case KEY_B2: /* Center (5) on numeric keypad with * NumLock off. */ @@ -542,11 +595,17 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key) break; case KEY_C1: /* End (1) on numeric keypad with * NumLock off. */ - retval = NANO_END_KEY; - break; - case KEY_C3: /* PageDown (4) on numeric keypad with - * NumLock off. */ - retval = NANO_NEXTPAGE_KEY; +#ifdef KEY_END + /* HP-UX 10-11 doesn't support KEY_END. */ + case KEY_END: +#endif +#ifdef KEY_SEND + /* HP-UX 10-11 and Slang don't support KEY_SEND. */ + case KEY_SEND: +#endif + s = first_sc_for(currmenu, (void *) do_end); + if (s) + retval = s->seq; break; #ifdef KEY_BEG /* Slang doesn't support KEY_BEG. */ @@ -558,13 +617,11 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key) #ifdef KEY_CANCEL /* Slang doesn't support KEY_CANCEL. */ case KEY_CANCEL: - retval = NANO_CANCEL_KEY; - break; +#ifdef KEY_SCANCEL + /* Slang doesn't support KEY_SCANCEL. */ + case KEY_SCANCEL: #endif -#ifdef KEY_END - /* HP-UX 10-11 doesn't support KEY_END. */ - case KEY_END: - retval = NANO_END_KEY; + retval = first_sc_for(currmenu, (void *) cancel_msg)->seq; break; #endif #ifdef KEY_SBEG @@ -574,61 +631,6 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key) retval = ERR; break; #endif -#ifdef KEY_SCANCEL - /* Slang doesn't support KEY_SCANCEL. */ - case KEY_SCANCEL: - retval = NANO_CANCEL_KEY; - break; -#endif -#ifdef KEY_SDC - /* Slang doesn't support KEY_SDC. */ - case KEY_SDC: - retval = ISSET(REBIND_DELETE) ? NANO_BACKSPACE_KEY : - NANO_DELETE_KEY; - break; -#endif -#ifdef KEY_SEND - /* HP-UX 10-11 and Slang don't support KEY_SEND. */ - case KEY_SEND: - retval = NANO_END_KEY; - break; -#endif -#ifdef KEY_SHOME - /* HP-UX 10-11 and Slang don't support KEY_SHOME. */ - case KEY_SHOME: - retval = NANO_HOME_KEY; - break; -#endif -#ifdef KEY_SIC - /* Slang doesn't support KEY_SIC. */ - case KEY_SIC: - retval = NANO_INSERTFILE_KEY; - break; -#endif -#ifdef KEY_SDOWN - /* ncurses and Slang don't support KEY_SDOWN. */ - case KEY_SDOWN: - retval = NANO_NEXTLINE_KEY; - break; -#endif -#ifdef KEY_SUP - /* ncurses and Slang don't support KEY_SUP. */ - case KEY_SUP: - retval = NANO_PREVLINE_KEY; - break; -#endif -#ifdef KEY_SLEFT - /* Slang doesn't support KEY_SLEFT. */ - case KEY_SLEFT: - retval = NANO_BACK_KEY; - break; -#endif -#ifdef KEY_SRIGHT - /* Slang doesn't support KEY_SRIGHT. */ - case KEY_SRIGHT: - retval = NANO_FORWARD_KEY; - break; -#endif #ifdef KEY_SSUSPEND /* Slang doesn't support KEY_SSUSPEND. */ case KEY_SSUSPEND: @@ -1639,6 +1641,7 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts) { MEVENT mevent; bool in_bottomwin; + subnfunc *f; *mouse_x = -1; *mouse_y = -1; @@ -1670,9 +1673,6 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts) size_t currslen; /* The number of shortcuts in the current shortcut * list. */ - const shortcut *s; - /* The actual shortcut we released on, starting at the - * first one in the current shortcut list. */ /* Translate the mouse event coordinates so that they're * relative to bottomwin. */ @@ -1694,10 +1694,10 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts) j = *mouse_y - 1; /* Get the shortcut lists' length. */ - if (currshortcut == main_list) + if (currmenu == MMAIN) currslen = MAIN_VISIBLE; else { - currslen = length_of_list(currshortcut); + currslen = length_of_list(currmenu); /* We don't show any more shortcuts than the main list * does. */ @@ -1730,20 +1730,16 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts) /* Go through the shortcut list to determine which shortcut * we released/clicked on. */ - s = currshortcut; + f = allfuncs; for (; j > 0; j--) - s = s->next; + while (f != NULL && (f->menus & currmenu) != 0) + f = f->next; - /* And put back the equivalent key. Assume that each - * shortcut has, at the very least, an equivalent control - * key, an equivalent primary meta key sequence, or both. */ - if (s->ctrlval != NANO_NO_KEY) { - unget_kbinput(s->ctrlval, FALSE, FALSE); - return 1; - } else if (s->metaval != NANO_NO_KEY) { - unget_kbinput(s->metaval, TRUE, FALSE); - return 1; + /* And put back the equivalent key. */ + if (f != NULL) { + const sc *s = first_sc_for(currmenu, (void *) f->scfunc); + unget_kbinput(s->seq, s->type == META, FALSE); } } else /* Handle releases/clicks of the first mouse button that @@ -1795,53 +1791,29 @@ int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts) * example, passing in a meta key sequence that corresponds to a * function with a control key, a function key, and a meta key sequence * will return the control key corresponding to that function. */ -const shortcut *get_shortcut(const shortcut *s_list, int *kbinput, bool +const sc *get_shortcut(int menu, int *kbinput, bool *meta_key, bool *func_key) { - const shortcut *s = s_list; - size_t slen = length_of_list(s_list); + sc *s; #ifdef DEBUG fprintf(stderr, "get_shortcut(): kbinput = %d, meta_key = %s, func_key = %s\n", *kbinput, *meta_key ? "TRUE" : "FALSE", *func_key ? "TRUE" : "FALSE"); #endif /* Check for shortcuts. */ - for (; slen > 0; slen--) { - /* We've found a shortcut if: - * - * 1. The key exists. - * 2. The key is a control key in the shortcut list. - * 3. meta_key is TRUE and the key is the primary or - * miscellaneous meta sequence in the shortcut list. - * 4. func_key is TRUE and the key is a function key in the - * shortcut list. */ - - if (*kbinput != NANO_NO_KEY && (*kbinput == s->ctrlval || - (*meta_key && (*kbinput == s->metaval || *kbinput == - s->miscval)) || (*func_key && *kbinput == - s->funcval))) { - break; - } - - s = s->next; - } - - /* Translate the shortcut to either its control key or its meta key - * equivalent. Assume that the shortcut has an equivalent control - * key, an equivalent primary meta key sequence, or both. */ - if (slen > 0) { - if (s->ctrlval != NANO_NO_KEY) { - *meta_key = FALSE; - *func_key = FALSE; - *kbinput = s->ctrlval; - return s; - } else if (s->metaval != NANO_NO_KEY) { - *meta_key = TRUE; - *func_key = FALSE; - *kbinput = s->metaval; + for (s = sclist; s != NULL; s = s->next) { + if ((menu & s->menu) + && ((s->type == META && *meta_key == TRUE && *kbinput == s->seq) + || (s->type != META && *kbinput == s->seq))) { +#ifdef DEBUG + fprintf (stderr, "matched seq \"%s\" and btw meta was %d (menus %d = %d)\n", s->keystr, *meta_key, menu, s->menu); +#endif return s; } } +#ifdef DEBUG + fprintf (stderr, "matched nothing btw meta was %d\n", *meta_key); +#endif return NULL; } @@ -2375,19 +2347,21 @@ void statusbar(const char *msg, ...) /* Display the shortcut list in s on the last two rows of the bottom * portion of the window. */ -void bottombars(const shortcut *s) +void bottombars(int menu) { size_t i, colwidth, slen; + subnfunc *f; + const sc *s; if (ISSET(NO_HELP)) return; - if (s == main_list) { + if (menu == MMAIN) { slen = MAIN_VISIBLE; - assert(slen <= length_of_list(s)); + assert(slen <= length_of_list(menu)); } else { - slen = length_of_list(s); + slen = length_of_list(menu); /* Don't show any more shortcuts than the main list does. */ if (slen > MAIN_VISIBLE) @@ -2402,26 +2376,34 @@ void bottombars(const shortcut *s) blank_bottombars(); - for (i = 0; i < slen; i++, s = s->next) { - const char *keystr; - char foo[4] = ""; +#ifdef DEBUG + fprintf(stderr, "In bottombars, and slen == \"%d\"\n", (int) slen); +#endif - /* Yucky sentinel values that we can't handle a better way. */ - if (s->ctrlval == NANO_CONTROL_SPACE) - strcpy(foo, "^ "); - else if (s->ctrlval == NANO_CONTROL_8) - strcpy(foo, "^?"); - /* Normal values. Assume that the shortcut has an equivalent - * control key, meta key sequence, or both. */ - else if (s->ctrlval != NANO_NO_KEY) - sprintf(foo, "^%c", s->ctrlval + 64); - else if (s->metaval != NANO_NO_KEY) - sprintf(foo, "M-%c", toupper(s->metaval)); + for (f = allfuncs, i = 0; i < slen && f != NULL; f = f->next) { - keystr = foo; +#ifdef DEBUG + fprintf(stderr, "Checking menu items...."); +#endif + if ((f->menus & menu) == 0) + continue; +#ifdef DEBUG + fprintf(stderr, "found one! f->menus = %d\n", f->menus); +#endif + s = first_sc_for(menu, f->scfunc); + if (s == NULL) { +#ifdef DEBUG + fprintf(stderr, "Whoops, guess not, no shortcut key found for func!\n"); +#endif + continue; + } wmove(bottomwin, 1 + i % 2, (i / 2) * colwidth); - onekey(keystr, s->desc, colwidth + (COLS % colwidth)); +#ifdef DEBUG + fprintf(stderr, "Calling onekey with keystr \"%s\" and desc \"%s\"\n", s->keystr, f->desc); +#endif + onekey(s->keystr, f->desc, colwidth + (COLS % colwidth)); + i++; } wnoutrefresh(bottomwin); @@ -3184,14 +3166,14 @@ void total_refresh(void) total_redraw(); titlebar(NULL); edit_refresh(); - bottombars(currshortcut); + bottombars(currmenu); } /* Display the main shortcut list on the last two rows of the bottom * portion of the window. */ void display_main_list(void) { - bottombars(main_list); + bottombars(MMAIN); } /* If constant is TRUE, we display the current cursor position only if