]> git.wh0rd.org Git - nano.git/commitdiff
the last of the low-level input overhaul: make the global shortcut list
authorDavid Lawrence Ramsey <pooka109@gmail.com>
Wed, 24 Dec 2003 03:33:09 +0000 (03:33 +0000)
committerDavid Lawrence Ramsey <pooka109@gmail.com>
Wed, 24 Dec 2003 03:33:09 +0000 (03:33 +0000)
use NANO_NO_KEY to represent no key value, add the NANO_HISTORY_KEY
sentinel value, add support for many more escape sequences for those
terminals that generate them, add DB's extensibility tweaks to
do_yesno(), make ASCII 128 act like Backspace when -d is used, add
various cleanups to the low-level input functions, and make the last of
the low-level input routines use the new low-level input functions

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1599 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
doc/nanorc.sample
src/files.c
src/global.c
src/nano.c
src/nano.h
src/proto.h
src/search.c
src/winio.c

index d3fcc6bb6795e781d45bf794620ac097dead7beb..a9eb0e12174af5c7b22a40925f5a37eff8da1bab 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,7 +4,7 @@ CVS code -
          input, mostly adapted from the code in do_mouse() that handles
          clicking on the shortcut list.  New function do_mouseinput();
          changes to do_mouse(). (DLR)  David Benbennick: Add a few
-         efficiency tweaks.
+         efficiency/extensibility tweaks.
        - Modify the shortcut structure so that instead of having two
          miscellaneous key values (misc1 and misc2), there is one key
          value reserved for function keys (func_key) and one
@@ -18,18 +18,44 @@ CVS code -
          readability, and eliminate use of adding 32 to values when
          testing for toggles, as get_kbinput_accepted() converts toggle
          values to lowercase before returning them. (DLR)
+       - Remove the workarounds for missing KEY_UP and KEY_DOWN, as
+         they appear to be holdovers of the old way of denoting the
+         search history shortcuts; if they aren't defined, KEY_LEFT and
+         KEY_RIGHT probably shouldn't work either, and all four appear
+         to be standard keys in termcap/terminfo in any case.  Add new
+         special sentinel key values NANO_NO_KEY (for no shortcut key)
+         and NANO_HISTORY_KEY (for search history keys, both Up and
+         Down), modify the shortcut list to use them, and modify the
+         shortcut display routines to handle them.  Also modify the
+         shortcut list code to not treat non-control character values
+         of val as Meta-sequences, and fix dependencies on that
+         behavior. (DLR)
        - Hook up the verbatim input functions so that verbatim input
          can be used in the edit window.  New function
          do_verbatim_input(); changes to do_char(). (DLR)  Additional
          minor tweaks to do_char() by David Benbennick.
+       - Clarify the description of the --rebinddelete option. (DLR)
 - files.c:
   do_writeout()
        - Prompt the user if we're trying to save an existing file (and
          not just a selection of it) under a different name. (DLR;
          suggested by Jean-Philippe GuĂ©rard)
+  open_prevfile(), open_nextfile()
+       - For consistency with the rest of the multibuffer code, change
+         "No more open files" to "No more open file buffers". (DLR)
+  do_browser()
+       - Allow '?' to open the help browser, and readd the ability of
+         'G'/'g' to open the "Go to Directory" prompt (which was
+         erroneously removed before), for compatibility with Pico.
+         (DLR)
 - global.c:
   shortcut_init()
        - Allow WHEREIS_NEXT_KEY to be used in view mode. (DLR)
+- nano,c:
+  do_para_operation()
+       - Convert to use the new low-level input functions. (DLR)
+  main()
+       - Remove unused variable option_index. (DLR)
 - search.c:
   findnextstr(), do_replace_loop()
        - Fix potential infinite loops and other misbehavior when doing
@@ -39,9 +65,40 @@ CVS code -
          that such regexes are only found once per line. (DLR; found by
          Mike Frysinger and DLR)
 - winio.c:
+  get_kbinput(), get_accepted_kbinput()
+       - Don't pass in the value of the REBIND_DELETE flag anymore.
+         Instead, handle it directly inside the functions. (DLR)
   get_accepted_kbinput()
-       - Translate Ctrl-8 into NANO_DELETE_KEY, since it apparently is
-         generated at the statusbar prompt sometimes on Linux. (DLR)
+       - Translate Ctrl-8 into NANO_DELETE_KEY (or NANO_BACKSPACE_KEY
+         if REBIND_DELETE is set), since it apparently is generated
+         sometimes even when keypad() is TRUE. (DLR)
+       - Translate KEY_SLEFT into NANO_BACK_KEY and KEY_SRIGHT into
+         NANO_FORWARD_KEY, since they are sometimes generated by
+         Shift-Left and Shift-Right. (DLR)
+  get_ascii_kbinput()
+       - Tweak to make it slightly more readable. (DLR)
+  get_verbatim_kbinput()
+       - Modify to take an extra parameter indicating if we should
+         interpret ASCII codes or not. (DLR)
+  get_escape_seq_kbinput()
+       - Expand to deal with more broken terminals that don't generate
+         keypad values.  Support the escape sequences for Insert,
+         Delete, Home, End, PageUp, and PageDown, [arrow key],
+         Ctrl-[arrow key], and Shift-[arrow key] when needed in the
+         Linux console, the FreeBSD console, the Hurd console, xterm,
+         rxvt, and Eterm.  Also, use get_verbatim_kbinput(), with ASCII
+         interpretation disabled, to read in the sequences. (DLR)
+  get_skip_tilde_kbinput()
+       - Removed, as it is unneeded due to the expansion of
+         get_escape_seq_kbinput(). (DLR)
+  get_mouseinput()
+       - Modify to take an extra parameter indicating if we should
+         ungetch() the key equivalents of shortcuts we click on or not.
+         (DLR)
+  do_yesno()
+       - Add a few efficiency/extensibility tweaks. (David Benbennick)
+       - Convert to use the new low-level input functions, and remove
+         two last hardcoded widths left after the above tweaks. (DLR)
 - configure.ac:
        - Check for glib 2.x and then 1.2.x if we need glib. (DLR)
 - nano.spec.in:
index a1fdf61c350b334e8759a9cc5a5bea36ea3524a5..eee7cdb36621c554a4ffc479b2ba7494d7f5c63d 100644 (file)
@@ -66,7 +66,7 @@
 ## You can get old nano quoted-justify behavior via:
 # set quotestr "(> )+"
 
-## Fix Backspace if it acts like Delete
+## Fix Backspace/Delete confusion problem
 # set rebinddelete
 
 ## Do extended regular expression searches by default 
index 452cd66032d658461435f37730689a67ecaa5cf5..46422a105cfee771864fc581ae56f5f627ca45c3 100644 (file)
@@ -878,7 +878,7 @@ int open_prevfile(int closing_file)
 
        /* only one file open */
        if (!closing_file)
-           statusbar(_("No more open files"));
+           statusbar(_("No more open file buffers"));
        return 1;
     }
 
@@ -941,7 +941,7 @@ int open_nextfile(int closing_file)
 
        /* only one file open */
        if (!closing_file)
-           statusbar(_("No more open files"));
+           statusbar(_("No more open file buffers"));
        return 1;
     }
 
@@ -1835,7 +1835,7 @@ int do_writeout(const char *path, int exiting, int append)
            struct stat st;
 
            if (!stat(answer, &st)) {
-               i = do_yesno(0, 0, _("File exists, OVERWRITE ?"));
+               i = do_yesno(0, _("File exists, OVERWRITE ?"));
                if (i == 0 || i == -1)
                    continue;
            } else if (filename[0] != '\0'
@@ -1843,7 +1843,7 @@ int do_writeout(const char *path, int exiting, int append)
                && (!ISSET(MARK_ISSET) || exiting)
 #endif
                ) {
-               i = do_yesno(0, 0, _("Save file under DIFFERENT NAME ?"));
+               i = do_yesno(0, _("Save file under DIFFERENT NAME ?"));
                if (i == 0 || i == -1)
                    continue;
            }
@@ -2599,7 +2599,7 @@ char *do_browser(const char *inpath)
            break;
        case NANO_PREVPAGE_KEY:
        case NANO_PREVPAGE_FKEY:
-       case '-':
+       case '-': /* Pico compatibility */
            if (selected >= (editwinrows + lineno % editwinrows) * width)
                selected -= (editwinrows + lineno % editwinrows) * width; 
            else
@@ -2607,18 +2607,19 @@ char *do_browser(const char *inpath)
            break;
        case NANO_NEXTPAGE_KEY:
        case NANO_NEXTPAGE_FKEY:
-       case ' ':
+       case ' ': /* Pico compatibility */
            selected += (editwinrows - lineno % editwinrows) * width;
            if (selected >= numents)
                selected = numents - 1;
            break;
        case NANO_HELP_KEY:
        case NANO_HELP_FKEY:
+       case '?': /* Pico compatibility */
             do_help();
             break;
        case NANO_ENTER_KEY:
-       case 's': /* More Pico compatibility */
-       case 'S':
+       case 'S': /* Pico compatibility */
+       case 's':
            /* You can't cd up from / */
            if (!strcmp(filelist[selected], "/..") && !strcmp(path, "/")) {
                statusbar(_("Can't move up a directory"));
@@ -2627,10 +2628,9 @@ char *do_browser(const char *inpath)
            }
 
 #ifndef DISABLE_OPERATINGDIR
-           /*
-            *  Note: the selected file can be outside the operating
-            *  directory if it is .. or if it is a symlink to a directory
-            *  outside the opdir. */
+           /* Note: the selected file can be outside the operating
+            * directory if it is .. or if it is a symlink to 
+            * directory outside the operating directory. */
            if (check_operating_dir(filelist[selected], FALSE)) {
                statusbar(_("Can't go outside of %s in restricted mode"), operating_dir);
                beep();
@@ -2680,6 +2680,8 @@ char *do_browser(const char *inpath)
        /* Goto a specific directory */
        case NANO_GOTO_KEY:
        case NANO_GOTO_FKEY:
+       case 'G': /* Pico compatibility */
+       case 'g':
            curs_set(1);
            j = statusq(0, gotodir_list, "",
 #ifndef NANO_SMALL
@@ -2724,11 +2726,11 @@ char *do_browser(const char *inpath)
            return do_browser(path);
 
        /* Stuff we want to abort the browser */
-       case 'e':       /* Pico compatibility, yeech */
-       case 'E':
        case NANO_CANCEL_KEY:
        case NANO_EXIT_KEY:
        case NANO_EXIT_FKEY:
+       case 'E': /* Pico compatibility */
+       case 'e':
            abort = 1;
            break;
        }
@@ -2803,7 +2805,7 @@ char *do_browser(const char *inpath)
            }
        }
        wrefresh(edit);
-    } while ((kbinput = get_kbinput(edit, &meta, ISSET(REBIND_DELETE))) != NANO_EXIT_KEY && kbinput != NANO_EXIT_FKEY);
+    } while ((kbinput = get_kbinput(edit, &meta)) != NANO_EXIT_KEY && kbinput != NANO_EXIT_FKEY);
     curs_set(1);
     blank_edit();
     titlebar(NULL);
index 34a6589e8e982011b3898fd13bbe8c1d7421df50..78da209c3f684581731ab6c0e1bf6276f6c44928 100644 (file)
@@ -432,38 +432,38 @@ void shortcut_init(int unjustify)
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&main_list, NANO_HELP_KEY, _("Get Help"),
-               IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
-               0, VIEW, do_help);
+               IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY,
+               NANO_NO_KEY, VIEW, do_help);
 
 #ifdef ENABLE_MULTIBUFFER
     if (open_files != NULL && (open_files->prev != NULL || open_files->next != NULL))
     /* Translators: try to keep this string under 10 characters long */
        sc_init_one(&main_list, NANO_EXIT_KEY, _("Close"),
-               IFHELP(nano_exit_msg, 0), NANO_EXIT_FKEY,
-               0, VIEW, do_exit);
+               IFHELP(nano_exit_msg, NANO_NO_KEY), NANO_EXIT_FKEY,
+               NANO_NO_KEY, VIEW, do_exit);
     else
 #endif
 
     /* Translators: try to keep this string under 10 characters long */
        sc_init_one(&main_list, NANO_EXIT_KEY, _("Exit"),
-               IFHELP(nano_exit_msg, 0), NANO_EXIT_FKEY,
-               0, VIEW, do_exit);
+               IFHELP(nano_exit_msg, NANO_NO_KEY), NANO_EXIT_FKEY,
+               NANO_NO_KEY, VIEW, do_exit);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&main_list, NANO_WRITEOUT_KEY, _("WriteOut"),
-                   IFHELP(nano_writeout_msg, 0), NANO_WRITEOUT_FKEY,
-                   0, NOVIEW, do_writeout_void);
+               IFHELP(nano_writeout_msg, NANO_NO_KEY), NANO_WRITEOUT_FKEY,
+               NANO_NO_KEY, NOVIEW, do_writeout_void);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&main_list, NANO_JUSTIFY_KEY, _("Justify"),
-                   IFHELP(nano_justify_msg, 0), NANO_JUSTIFY_FKEY,
-                   0, NOVIEW, do_justify);
+               IFHELP(nano_justify_msg, NANO_NO_KEY),
+               NANO_JUSTIFY_FKEY, NANO_NO_KEY, NOVIEW, do_justify);
 
     /* this is so we can view multiple files */
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&main_list, NANO_INSERTFILE_KEY, _("Read File"),
-               IFHELP(nano_insert_msg, 0), NANO_INSERTFILE_FKEY,
-               0,
+               IFHELP(nano_insert_msg, NANO_NO_KEY), NANO_INSERTFILE_FKEY,
+               NANO_NO_KEY,
 #ifdef ENABLE_MULTIBUFFER
                VIEW
 #else
@@ -473,178 +473,201 @@ void shortcut_init(int unjustify)
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&main_list, NANO_WHEREIS_KEY, _("Where Is"),
-               IFHELP(nano_whereis_msg, 0), NANO_WHEREIS_FKEY,
-               0, VIEW, do_search);
+               IFHELP(nano_whereis_msg, NANO_NO_KEY), NANO_WHEREIS_FKEY,
+               NANO_NO_KEY, VIEW, do_search);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&main_list, NANO_PREVPAGE_KEY, _("Prev Page"),
-               IFHELP(nano_prevpage_msg, 0), NANO_PREVPAGE_FKEY,
-               0, VIEW, do_page_up);
+               IFHELP(nano_prevpage_msg, NANO_NO_KEY), NANO_PREVPAGE_FKEY,
+               NANO_NO_KEY, VIEW, do_page_up);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&main_list, NANO_NEXTPAGE_KEY, _("Next Page"),
-               IFHELP(nano_nextpage_msg, 0), NANO_NEXTPAGE_FKEY,
-               0, VIEW, do_page_down);
+               IFHELP(nano_nextpage_msg, NANO_NO_KEY), NANO_NEXTPAGE_FKEY,
+               NANO_NO_KEY, VIEW, do_page_down);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&main_list, NANO_CUT_KEY, _("Cut Text"),
-               IFHELP(nano_cut_msg, 0), NANO_CUT_FKEY, 0, NOVIEW, do_cut_text);
+               IFHELP(nano_cut_msg, NANO_NO_KEY), NANO_CUT_FKEY,
+               NANO_NO_KEY, NOVIEW, do_cut_text);
 
     if (unjustify)
     /* Translators: try to keep this string under 10 characters long */
        sc_init_one(&main_list, NANO_UNJUSTIFY_KEY, _("UnJustify"),
-               IFHELP(nano_unjustify_msg, 0), 0, 0, NOVIEW, do_uncut_text);
+               IFHELP(nano_unjustify_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, do_uncut_text);
     else
     /* Translators: try to keep this string under 10 characters long */
        sc_init_one(&main_list, NANO_UNCUT_KEY, _("UnCut Txt"),
-               IFHELP(nano_uncut_msg, 0), NANO_UNCUT_FKEY,
-               0, NOVIEW, do_uncut_text);
+               IFHELP(nano_uncut_msg, NANO_NO_KEY), NANO_UNCUT_FKEY,
+               NANO_NO_KEY, NOVIEW, do_uncut_text);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&main_list, NANO_CURSORPOS_KEY, _("Cur Pos"),
-               IFHELP(nano_cursorpos_msg, 0), NANO_CURSORPOS_FKEY,
-               0, VIEW, do_cursorpos_void);
+               IFHELP(nano_cursorpos_msg, NANO_NO_KEY), NANO_CURSORPOS_FKEY,
+               NANO_NO_KEY, VIEW, do_cursorpos_void);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&main_list, NANO_SPELL_KEY, _("To Spell"),
-               IFHELP(nano_spell_msg, 0), NANO_SPELL_FKEY,
-               0, NOVIEW, do_spell);
+               IFHELP(nano_spell_msg, NANO_NO_KEY), NANO_SPELL_FKEY,
+               NANO_NO_KEY, NOVIEW, do_spell);
 
     sc_init_one(&main_list, NANO_GOTO_KEY, _("Go To Line"),
-               IFHELP(nano_goto_msg, NANO_ALT_GOTO_KEY),
-               NANO_GOTO_FKEY, 0, VIEW, do_gotoline_void);
+               IFHELP(nano_goto_msg, NANO_ALT_GOTO_KEY), NANO_GOTO_FKEY,
+               NANO_NO_KEY, VIEW, do_gotoline_void);
 
     sc_init_one(&main_list, NANO_REPLACE_KEY, _("Replace"),
-               IFHELP(nano_replace_msg, NANO_ALT_REPLACE_KEY),
-               NANO_REPLACE_FKEY, 0, NOVIEW, do_replace);
+               IFHELP(nano_replace_msg, NANO_ALT_REPLACE_KEY), NANO_REPLACE_FKEY,
+               NANO_NO_KEY, NOVIEW, do_replace);
 
     sc_init_one(&main_list, NANO_UP_KEY, _("Up"),
-               IFHELP(nano_up_msg, 0), 0, 0, VIEW, do_up);
+               IFHELP(nano_up_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_up);
 
     sc_init_one(&main_list, NANO_DOWN_KEY, _("Down"),
-               IFHELP(nano_down_msg, 0), 0, 0, VIEW, do_down);
+               IFHELP(nano_down_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_down);
 
     sc_init_one(&main_list, NANO_FORWARD_KEY, _("Forward"),
-               IFHELP(nano_forward_msg, 0), 0, 0, VIEW, do_right);
+               IFHELP(nano_forward_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_right);
 
     sc_init_one(&main_list, NANO_BACK_KEY, _("Back"),
-               IFHELP(nano_back_msg, 0), 0, 0, VIEW, do_left);
+               IFHELP(nano_back_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_left);
 
     sc_init_one(&main_list, NANO_HOME_KEY, _("Home"),
-               IFHELP(nano_home_msg, 0), 0, 0, VIEW, do_home);
+               IFHELP(nano_home_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_home);
 
     sc_init_one(&main_list, NANO_END_KEY, _("End"),
-               IFHELP(nano_end_msg, 0), 0, 0, VIEW, do_end);
+               IFHELP(nano_end_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_end);
 
     sc_init_one(&main_list, NANO_REFRESH_KEY, _("Refresh"),
-               IFHELP(nano_refresh_msg, 0), 0, 0, VIEW, total_refresh);
+               IFHELP(nano_refresh_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, total_refresh);
 
     sc_init_one(&main_list, NANO_MARK_KEY, _("Mark Text"),
                IFHELP(nano_mark_msg, NANO_ALT_MARK_KEY),
-               0, 0, NOVIEW, do_mark);
+               NANO_NO_KEY, NANO_NO_KEY, NOVIEW, do_mark);
 
     sc_init_one(&main_list, NANO_DELETE_KEY, _("Delete"),
-               IFHELP(nano_delete_msg, 0), 0, 0, NOVIEW, do_delete);
+               IFHELP(nano_delete_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, do_delete);
 
     sc_init_one(&main_list, NANO_BACKSPACE_KEY, _("Backspace"),
-               IFHELP(nano_backspace_msg, 0), 0, 0, NOVIEW, do_backspace);
+               IFHELP(nano_backspace_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, do_backspace);
 
     sc_init_one(&main_list, NANO_TAB_KEY, _("Tab"),
-               IFHELP(nano_tab_msg, 0), 0, 0, NOVIEW, do_tab);
+               IFHELP(nano_tab_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, do_tab);
 
     sc_init_one(&main_list, NANO_ENTER_KEY, _("Enter"),
-               IFHELP(nano_enter_msg, 0), 0, 0, NOVIEW, do_enter);
+               IFHELP(nano_enter_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, do_enter);
 
 #ifndef NANO_SMALL
     sc_init_one(&main_list, NANO_NEXTWORD_KEY, _("Next Word"),
-               IFHELP(nano_nextword_msg, 0), 0, 0, VIEW, do_next_word);
+               IFHELP(nano_nextword_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_next_word);
 
-    sc_init_one(&main_list, -1, _("Prev Word"),
-               IFHELP(nano_prevword_msg, NANO_PREVWORD_KEY),
-               0, 0, VIEW, do_prev_word);
+    sc_init_one(&main_list, NANO_NO_KEY, _("Prev Word"),
+               IFHELP(nano_prevword_msg, NANO_PREVWORD_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_prev_word);
 #endif
 
-    sc_init_one(&main_list, -1, _("Verbatim Input"),
-               IFHELP(nano_verbatim_msg, NANO_VERBATIM_KEY),
-               0, 0, VIEW, do_verbatim_input);
+    sc_init_one(&main_list, NANO_NO_KEY, _("Verbatim Input"),
+               IFHELP(nano_verbatim_msg, NANO_VERBATIM_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_verbatim_input);
 
 #ifdef ENABLE_MULTIBUFFER
-    sc_init_one(&main_list, -1, _("Previous File"),
-               IFHELP(nano_openprev_msg, NANO_OPENPREV_KEY),
-               0, NANO_OPENPREV_ALTKEY, VIEW, open_prevfile_void);
+    sc_init_one(&main_list, NANO_NO_KEY, _("Previous File"),
+               IFHELP(nano_openprev_msg, NANO_OPENPREV_KEY), NANO_NO_KEY,
+               NANO_OPENPREV_ALTKEY, VIEW, open_prevfile_void);
 
-    sc_init_one(&main_list, -1, _("Next File"),
-               IFHELP(nano_opennext_msg, NANO_OPENNEXT_KEY),
-               0, NANO_OPENNEXT_ALTKEY, VIEW, open_nextfile_void);
+    sc_init_one(&main_list, NANO_NO_KEY, _("Next File"),
+               IFHELP(nano_opennext_msg, NANO_OPENNEXT_KEY), NANO_NO_KEY,
+               NANO_OPENNEXT_ALTKEY, VIEW, open_nextfile_void);
 #endif
 
 #if !defined(NANO_SMALL) && defined(HAVE_REGEX_H)
-    sc_init_one(&main_list, -1, _("Find Other Bracket"),
-               IFHELP(nano_bracket_msg, NANO_BRACKET_KEY),
-               0, 0, VIEW, do_find_bracket);
+    sc_init_one(&main_list, NANO_NO_KEY, _("Find Other Bracket"),
+               IFHELP(nano_bracket_msg, NANO_BRACKET_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_find_bracket);
 #endif
 
-    sc_init_one(&main_list, -1, _("Where Is Next"),
+    sc_init_one(&main_list, NANO_NO_KEY, _("Where Is Next"),
                IFHELP(nano_whereis_next_msg, NANO_WHEREIS_NEXT_KEY),
-               0, 0, VIEW, do_research);
+               NANO_NO_KEY, NANO_NO_KEY, VIEW, do_research);
 
     free_shortcutage(&whereis_list);
 
     sc_init_one(&whereis_list, NANO_HELP_KEY, _("Get Help"),
-               IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
-               0, VIEW, do_help);
+               IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY,
+               NANO_NO_KEY, VIEW, do_help);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&whereis_list, NANO_CANCEL_KEY, _("Cancel"),
-               IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
+               IFHELP(nano_cancel_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&whereis_list, NANO_FIRSTLINE_KEY, _("First Line"),
-               IFHELP(nano_firstline_msg, 0), 0, 0, VIEW, do_first_line);
+               IFHELP(nano_firstline_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_first_line);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&whereis_list, NANO_LASTLINE_KEY, _("Last Line"),
-               IFHELP(nano_lastline_msg, 0), 0, 0, VIEW, do_last_line);
+               IFHELP(nano_lastline_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_last_line);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&whereis_list, NANO_OTHERSEARCH_KEY, _("Replace"),
-               IFHELP(nano_replace_msg, 0), NANO_REPLACE_FKEY,
-               0, VIEW, do_replace);
+               IFHELP(nano_replace_msg, NANO_NO_KEY), NANO_REPLACE_FKEY,
+               NANO_NO_KEY, VIEW, do_replace);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&whereis_list, NANO_FROMSEARCHTOGOTO_KEY, _("Go To Line"),
-               IFHELP(nano_goto_msg, 0), NANO_GOTO_FKEY,
-               0, VIEW, do_gotoline_void);
+               IFHELP(nano_goto_msg, NANO_NO_KEY), NANO_GOTO_FKEY,
+               NANO_NO_KEY, VIEW, do_gotoline_void);
 
 #ifndef DISABLE_JUSTIFY
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&whereis_list, NANO_PARABEGIN_KEY, _("Beg of Par"),
-               IFHELP(nano_parabegin_msg, 0), 0, 0, VIEW, do_para_begin);
+               IFHELP(nano_parabegin_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_para_begin);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&whereis_list, NANO_PARAEND_KEY, _("End of Par"),
-               IFHELP(nano_paraend_msg, 0), 0, 0, VIEW, do_para_end);
+               IFHELP(nano_paraend_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_para_end);
 #endif
 
 #ifndef NANO_SMALL
     /* Translators: try to keep this string under 10 characters long */
-    sc_init_one(&whereis_list, TOGGLE_CASE_KEY, _("Case Sens"),
-               IFHELP(nano_case_msg, 0), 0, 0, VIEW, 0);
+    sc_init_one(&whereis_list, NANO_NO_KEY, _("Case Sens"),
+               IFHELP(nano_case_msg, TOGGLE_CASE_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 
     /* Translators: try to keep this string under 10 characters long */
-    sc_init_one(&whereis_list, TOGGLE_BACKWARDS_KEY, _("Direction"),
-               IFHELP(nano_reverse_msg, 0), 0, 0, VIEW, 0);
+    sc_init_one(&whereis_list, NANO_NO_KEY, _("Direction"),
+               IFHELP(nano_reverse_msg, TOGGLE_BACKWARDS_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 
 #ifdef HAVE_REGEX_H
     /* Translators: try to keep this string under 10 characters long */
-    sc_init_one(&whereis_list, TOGGLE_REGEXP_KEY, _("Regexp"),
-               IFHELP(nano_regexp_msg, 0), 0, 0, VIEW, 0);
+    sc_init_one(&whereis_list, NANO_NO_KEY, _("Regexp"),
+               IFHELP(nano_regexp_msg, TOGGLE_REGEXP_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 #endif
 
 #ifndef NANO_SMALL
     /* Translators: try to keep this string under 10 characters long */
-    sc_init_one(&whereis_list, NANO_UP_KEY, _("History"),
-               IFHELP(nano_editstr_msg, 0), 0, NANO_DOWN_KEY, VIEW, 0);
+    sc_init_one(&whereis_list, NANO_HISTORY_KEY, _("History"),
+               IFHELP(nano_editstr_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 #endif
 
 #endif /* !NANO_SMALL */
@@ -652,156 +675,181 @@ void shortcut_init(int unjustify)
     free_shortcutage(&replace_list);
 
     sc_init_one(&replace_list, NANO_HELP_KEY, _("Get Help"),
-               IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
-               0, VIEW, do_help);
+               IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY,
+               NANO_NO_KEY, VIEW, do_help);
 
     sc_init_one(&replace_list, NANO_CANCEL_KEY, _("Cancel"),
-               IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
+               IFHELP(nano_cancel_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 
     sc_init_one(&replace_list, NANO_FIRSTLINE_KEY, _("First Line"),
-               IFHELP(nano_firstline_msg, 0), 0, 0, VIEW, do_first_line);
+               IFHELP(nano_firstline_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_first_line);
 
     sc_init_one(&replace_list, NANO_LASTLINE_KEY, _("Last Line"),
-               IFHELP(nano_lastline_msg, 0), 0, 0, VIEW, do_last_line);
+               IFHELP(nano_lastline_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_last_line);
 
     /* Translators: try to keep this string under 12 characters long */
     sc_init_one(&replace_list, NANO_OTHERSEARCH_KEY, _("No Replace"),
-               IFHELP(nano_whereis_msg, 0), NANO_REPLACE_FKEY,
-               0, VIEW, do_search);
+               IFHELP(nano_whereis_msg, NANO_NO_KEY), NANO_REPLACE_FKEY,
+               NANO_NO_KEY, VIEW, do_search);
 
     sc_init_one(&replace_list, NANO_FROMSEARCHTOGOTO_KEY, _("Go To Line"), 
-               IFHELP(nano_goto_msg, 0), NANO_GOTO_FKEY,
-               0, VIEW, do_gotoline_void);
+               IFHELP(nano_goto_msg, NANO_NO_KEY), NANO_GOTO_FKEY,
+               NANO_NO_KEY, VIEW, do_gotoline_void);
 
 #ifndef NANO_SMALL
-    sc_init_one(&replace_list, TOGGLE_CASE_KEY, _("Case Sens"),
-               IFHELP(nano_case_msg, 0), 0, 0, VIEW, 0);
+    sc_init_one(&replace_list, NANO_NO_KEY, _("Case Sens"),
+               IFHELP(nano_case_msg, TOGGLE_CASE_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 
-    sc_init_one(&replace_list, TOGGLE_BACKWARDS_KEY, _("Direction"),
-               IFHELP(nano_reverse_msg, 0), 0, 0, VIEW, 0);
+    sc_init_one(&replace_list, NANO_NO_KEY, _("Direction"),
+               IFHELP(nano_reverse_msg, TOGGLE_BACKWARDS_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 
 #ifdef HAVE_REGEX_H
-    sc_init_one(&replace_list, TOGGLE_REGEXP_KEY, _("Regexp"),
-               IFHELP(nano_regexp_msg, 0), 0, 0, VIEW, 0);
+    sc_init_one(&replace_list, NANO_NO_KEY, _("Regexp"),
+               IFHELP(nano_regexp_msg, TOGGLE_REGEXP_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 #endif
 
-    sc_init_one(&replace_list, NANO_UP_KEY, _("History"),
-               IFHELP(nano_editstr_msg, 0), 0, NANO_DOWN_KEY, VIEW, 0);
+    sc_init_one(&replace_list, NANO_HISTORY_KEY, _("History"),
+               IFHELP(nano_editstr_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_DOWN_KEY, VIEW, 0);
 #endif /* !NANO_SMALL */
 
     free_shortcutage(&replace_list_2);
 
     sc_init_one(&replace_list_2, NANO_HELP_KEY, _("Get Help"),
-               IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
-               0, VIEW, do_help);
+               IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY,
+               NANO_NO_KEY, VIEW, do_help);
 
     sc_init_one(&replace_list_2, NANO_CANCEL_KEY, _("Cancel"),
-               IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
+               IFHELP(nano_cancel_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 
     sc_init_one(&replace_list_2, NANO_FIRSTLINE_KEY, _("First Line"),
-               IFHELP(nano_firstline_msg, 0), 0, 0, VIEW, do_first_line);
+               IFHELP(nano_firstline_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_first_line);
 
     sc_init_one(&replace_list_2, NANO_LASTLINE_KEY, _("Last Line"),
-               IFHELP(nano_lastline_msg, 0), 0, 0, VIEW, do_last_line);
+               IFHELP(nano_lastline_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_last_line);
 
 #ifndef NANO_SMALL
     sc_init_one(&replace_list_2, NANO_UP_KEY, _("History"),
-               IFHELP(nano_editstr_msg, 0), 0, NANO_DOWN_KEY, VIEW, 0);
+               IFHELP(nano_editstr_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_DOWN_KEY, VIEW, 0);
 #endif
 
     free_shortcutage(&goto_list);
 
     sc_init_one(&goto_list, NANO_HELP_KEY, _("Get Help"),
-               IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
-               0, VIEW, do_help);
+               IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY,
+               NANO_NO_KEY, VIEW, do_help);
 
     sc_init_one(&goto_list, NANO_CANCEL_KEY, _("Cancel"),
-               IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
+               IFHELP(nano_cancel_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 
     sc_init_one(&goto_list, NANO_FIRSTLINE_KEY, _("First Line"),
-               IFHELP(nano_firstline_msg, 0), 0, 0, VIEW, do_first_line);
+               IFHELP(nano_firstline_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_first_line);
 
     sc_init_one(&goto_list, NANO_LASTLINE_KEY, _("Last Line"),
-               IFHELP(nano_lastline_msg, 0), 0, 0, VIEW, do_last_line);
+               IFHELP(nano_lastline_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, do_last_line);
 
 #ifndef DISABLE_HELP
     free_shortcutage(&help_list);
 
     sc_init_one(&help_list, NANO_PREVPAGE_KEY, _("Prev Page"),
-               IFHELP(nano_prevpage_msg, 0), NANO_PREVPAGE_FKEY,
-               0, VIEW, do_page_up);
+               IFHELP(nano_prevpage_msg, NANO_NO_KEY), NANO_PREVPAGE_FKEY,
+               NANO_NO_KEY, VIEW, do_page_up);
 
     sc_init_one(&help_list, NANO_NEXTPAGE_KEY, _("Next Page"),
-               IFHELP(nano_nextpage_msg, 0), NANO_NEXTPAGE_FKEY,
-               0, VIEW, do_page_down);
+               IFHELP(nano_nextpage_msg, NANO_NO_KEY), NANO_NEXTPAGE_FKEY,
+               NANO_NO_KEY, VIEW, do_page_down);
 
     sc_init_one(&help_list, NANO_EXIT_KEY, _("Exit"),
-               IFHELP(nano_exit_msg, 0), NANO_EXIT_FKEY,
-               0, VIEW, do_exit);
+               IFHELP(nano_exit_msg, NANO_NO_KEY), NANO_EXIT_FKEY,
+               NANO_NO_KEY, VIEW, do_exit);
 #endif
 
     free_shortcutage(&writefile_list);
 
     sc_init_one(&writefile_list, NANO_HELP_KEY, _("Get Help"),
-               IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
-               0, VIEW, do_help);
+               IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY,
+               NANO_NO_KEY, VIEW, do_help);
 
 #ifndef DISABLE_BROWSER
     /* Translators: try to keep this string under 16 characters long */
     sc_init_one(&writefile_list, NANO_TOFILES_KEY, _("To Files"),
-               IFHELP(nano_tofiles_msg, 0), 0, 0, NOVIEW, 0);
+               IFHELP(nano_tofiles_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, 0);
 #endif
 
 #ifndef NANO_SMALL
     /* Translators: try to keep this string under 16 characters long */
-    sc_init_one(&writefile_list, TOGGLE_DOS_KEY, _("DOS Format"),
-               IFHELP(nano_dos_msg, 0), 0, 0, NOVIEW, 0);
+    sc_init_one(&writefile_list, NANO_NO_KEY, _("DOS Format"),
+               IFHELP(nano_dos_msg, TOGGLE_DOS_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, 0);
 
     /* Translators: try to keep this string under 16 characters long */
-    sc_init_one(&writefile_list, TOGGLE_MAC_KEY, _("Mac Format"),
-               IFHELP(nano_mac_msg, 0), 0, 0, NOVIEW, 0);
+    sc_init_one(&writefile_list, NANO_NO_KEY, _("Mac Format"),
+               IFHELP(nano_mac_msg, TOGGLE_MAC_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, 0);
 #endif
 
     /* Translators: try to keep this string under 16 characters long */
-    sc_init_one(&writefile_list, NANO_APPEND_KEY, _("Append"),
-               IFHELP(nano_append_msg, 0), 0, 0, NOVIEW, 0);
+    sc_init_one(&writefile_list, NANO_NO_KEY, _("Append"),
+               IFHELP(nano_append_msg, NANO_APPEND_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, 0);
 
     /* Translators: try to keep this string under 16 characters long */
-    sc_init_one(&writefile_list, NANO_PREPEND_KEY, _("Prepend"),
-               IFHELP(nano_prepend_msg, 0), 0, 0, NOVIEW, 0);
+    sc_init_one(&writefile_list, NANO_NO_KEY, _("Prepend"),
+               IFHELP(nano_prepend_msg, NANO_PREPEND_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, 0);
 
 #ifndef NANO_SMALL
     /* Translators: try to keep this string under 16 characters long */
-    sc_init_one(&writefile_list, TOGGLE_BACKUP_KEY, _("Backup File"),
-               IFHELP(nano_backup_msg, 0), 0, 0, NOVIEW, 0);
+    sc_init_one(&writefile_list, NANO_NO_KEY, _("Backup File"),
+               IFHELP(nano_backup_msg, TOGGLE_BACKUP_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, 0);
 #endif
 
     sc_init_one(&writefile_list, NANO_CANCEL_KEY, _("Cancel"),
-               IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
+               IFHELP(nano_cancel_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 
     free_shortcutage(&insertfile_list);
 
     sc_init_one(&insertfile_list, NANO_HELP_KEY, _("Get Help"),
-               IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
-               0, VIEW, do_help);
+               IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY,
+               NANO_NO_KEY, VIEW, do_help);
 
     sc_init_one(&insertfile_list, NANO_CANCEL_KEY, _("Cancel"),
-               IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
+               IFHELP(nano_cancel_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 
 #ifndef DISABLE_BROWSER
     sc_init_one(&insertfile_list, NANO_TOFILES_KEY, _("To Files"),
-               IFHELP(nano_tofiles_msg, 0), 0, 0, NOVIEW, 0);
+               IFHELP(nano_tofiles_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, 0);
 #endif
 
 #ifndef NANO_SMALL
     /* Translators: try to keep this string under 22 characters long */
     sc_init_one(&insertfile_list, NANO_EXTCMD_KEY, _("Execute Command"),
-               IFHELP(nano_execute_msg, 0), 0, 0, NOVIEW, 0);
+               IFHELP(nano_execute_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, 0);
 
 #ifdef ENABLE_MULTIBUFFER
     /* Translators: try to keep this string under 22 characters long */
-    sc_init_one(&insertfile_list, TOGGLE_MULTIBUFFER_KEY, _("New Buffer"),
-               IFHELP(nano_multibuffer_msg, 0), 0, 0, NOVIEW, 0);
+    sc_init_one(&insertfile_list, NANO_NO_KEY, _("New Buffer"),
+               IFHELP(nano_multibuffer_msg, TOGGLE_MULTIBUFFER_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, NOVIEW, 0);
 #endif
 #endif
 
@@ -809,55 +857,59 @@ void shortcut_init(int unjustify)
     free_shortcutage(&spell_list);
 
     sc_init_one(&spell_list, NANO_HELP_KEY, _("Get Help"),
-               IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
-               0, VIEW, do_help);
+               IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY,
+               NANO_NO_KEY, VIEW, do_help);
 
     sc_init_one(&spell_list, NANO_CANCEL_KEY, _("Cancel"),
-               IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
+               IFHELP(nano_cancel_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 #endif
 
 #ifndef NANO_SMALL
     free_shortcutage(&extcmd_list);
 
     sc_init_one(&extcmd_list, NANO_HELP_KEY, _("Get Help"),
-               IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
-               0, VIEW, do_help);
+               IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY,
+               NANO_NO_KEY, VIEW, do_help);
 
     sc_init_one(&extcmd_list, NANO_CANCEL_KEY, _("Cancel"),
-               IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
+               IFHELP(nano_cancel_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 #endif
 
 #ifndef DISABLE_BROWSER
     free_shortcutage(&browser_list);
 
     sc_init_one(&browser_list, NANO_HELP_KEY, _("Get Help"),
-               IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
-               0, VIEW, do_help);
+               IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY,
+               NANO_NO_KEY, VIEW, do_help);
 
     sc_init_one(&browser_list, NANO_CANCEL_KEY, _("Cancel"),
-               IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
+               IFHELP(nano_cancel_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 
     sc_init_one(&browser_list, NANO_PREVPAGE_KEY, _("Prev Page"),
-               IFHELP(nano_prevpage_msg, 0), NANO_PREVPAGE_FKEY,
-               0, VIEW, 0);
+               IFHELP(nano_prevpage_msg, NANO_NO_KEY), NANO_PREVPAGE_FKEY,
+               NANO_NO_KEY, VIEW, 0);
 
     sc_init_one(&browser_list, NANO_NEXTPAGE_KEY, _("Next Page"),
-               IFHELP(nano_nextpage_msg, 0), NANO_NEXTPAGE_FKEY,
-               0, VIEW, 0);
+               IFHELP(nano_nextpage_msg, NANO_NO_KEY), NANO_NEXTPAGE_FKEY,
+               NANO_NO_KEY, VIEW, 0);
 
     /* Translators: try to keep this string under 22 characters long */
     sc_init_one(&browser_list, NANO_GOTO_KEY, _("Go To Dir"),
-               IFHELP(nano_gotodir_msg, NANO_ALT_GOTO_KEY),
-               NANO_GOTO_FKEY, 0, VIEW, 0);
+               IFHELP(nano_gotodir_msg, NANO_ALT_GOTO_KEY), NANO_GOTO_FKEY,
+               NANO_NO_KEY, VIEW, 0);
 
     free_shortcutage(&gotodir_list);
 
     sc_init_one(&gotodir_list, NANO_HELP_KEY, _("Get Help"),
-               IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
-               0, VIEW, do_help);
+               IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY,
+               NANO_NO_KEY, VIEW, do_help);
 
     sc_init_one(&gotodir_list, NANO_CANCEL_KEY, _("Cancel"),
-               IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
+               IFHELP(nano_cancel_msg, NANO_NO_KEY), NANO_NO_KEY,
+               NANO_NO_KEY, VIEW, 0);
 #endif
 
 #if !defined(DISABLE_BROWSER) || !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE)
index ef64e59ce9a9f04f13c7286793bd68e9ed4c172e..cce32695386dbf4639ae321855a2a057a20b7c1b 100644 (file)
@@ -406,43 +406,39 @@ void help_init(void)
        /* true if the character in s->altval is shown in first column */
        int meta_shortcut = 0;
 
+       if (s->val != NANO_NO_KEY) {
 #ifndef NANO_SMALL
-       if (s->val == NANO_UP_KEY && s->misc == NANO_DOWN_KEY)
-           ptr += sprintf(ptr, "%.2s", _("Up"));
-       else
+           if (s->val == NANO_HISTORY_KEY)
+               ptr += sprintf(ptr, "%.2s", _("Up"));
+           else
 #endif
-       if (is_cntrl_char(s->val)) {
            if (s->val == NANO_CONTROL_SPACE)
-               ptr += sprintf(ptr, "^%.6s", _("Space"));
+               ptr += sprintf(ptr, "^%.5s", _("Space"));
            else if (s->val == NANO_CONTROL_8)
                ptr += sprintf(ptr, "^?");
            else
                ptr += sprintf(ptr, "^%c", s->val + 64);
        }
 #ifndef NANO_SMALL
-       else if (s->altval == NANO_ALT_SPACE) {
+       else if (s->altval != NANO_NO_KEY) {
            meta_shortcut = 1;
-           ptr += sprintf(ptr, "M-%.5s", _("Space"));
+           if (s->altval == NANO_ALT_SPACE)
+               ptr += snprintf(ptr, 8, "M-%.5s", _("Space"));
+           else
+               ptr += sprintf(ptr, "M-%c", toupper(s->altval));
        }
 #endif
-       else if (s->val > 0) {
-           meta_shortcut = 1;
-           ptr += sprintf(ptr, "M-%c", toupper(s->val));
-       } else if (s->altval > 0) {
-           meta_shortcut = 1;
-           ptr += sprintf(ptr, "M-%c", toupper(s->altval));
-       }
 
        *(ptr++) = '\t';
 
-       if (s->func_key > KEY_F0 && s->func_key <= KEY_F(64))
+       if (s->func_key != NANO_NO_KEY)
            ptr += sprintf(ptr, "(F%d)", s->func_key - KEY_F0);
 
        *(ptr++) = '\t';
 
-       if (!meta_shortcut && s->altval > 0)
+       if (!meta_shortcut && s->altval != NANO_NO_KEY)
            ptr += sprintf(ptr, "(M-%c)", toupper(s->altval));
-       else if (meta_shortcut && s->misc > 0)
+       else if (meta_shortcut && s->misc != NANO_NO_KEY)
            ptr += sprintf(ptr, "(M-%c)", toupper(s->misc));
 
        *(ptr++) = '\t';
@@ -663,7 +659,7 @@ void usage(void)
 #endif
     print1opt("-c", "--const", _("Constantly show cursor position"));
 #ifndef NANO_SMALL
-    print1opt("-d", "--rebinddelete", _("Fix Backspace if it acts like Delete"));
+    print1opt("-d", "--rebinddelete", _("Fix Backspace/Delete confusion problem"));
     print1opt("-i", "--autoindent", _("Automatically indent new lines"));
     print1opt("-k", "--cut", _("Let ^K cut from cursor to end of line"));
 #endif
@@ -896,7 +892,7 @@ void do_mouse(void)
 {
     int mouse_x, mouse_y;
 
-    if (get_mouseinput(&mouse_x, &mouse_y) == 0) {
+    if (get_mouseinput(&mouse_x, &mouse_y, 1) == 0) {
 
        /* Click in the edit window to move the cursor, but only when
           we're not in a subfunction. */
@@ -1019,7 +1015,7 @@ int do_verbatim_input(void)
        signal_init();
 
     statusbar(_("Verbatim input"));
-    verbatim_kbinput = get_verbatim_kbinput(edit, &verbatim_len);
+    verbatim_kbinput = get_verbatim_kbinput(edit, &verbatim_len, 1);
 
     /* Turn on DISABLE_CURPOS while inserting character(s) and turn it
      * off afterwards, so that if constant cursor position display is
@@ -2238,8 +2234,7 @@ int do_para_operation(int operation)
  *
  *   A contiguous set of lines is a "paragraph" if each line is part of
  *   a paragraph and only the first line is the beginning of a
- *   paragraph.
- */
+ *   paragraph. */
 
     size_t quote_len;
        /* Length of the initial quotation of the paragraph we
@@ -2656,17 +2651,22 @@ int do_para_operation(int operation)
     /* Now get a keystroke and see if it's unjustify; if not, unget the
      * keystroke and return. */
 
+    {
+       int meta;
+       i = get_kbinput(edit, &meta);
 #ifndef DISABLE_MOUSE
-    /* If it was a mouse click, parse it with do_mouse() and it might
-     * become the unjustify key.  Else give it back to the input
-     * stream. */
-    if ((i = wgetch(edit)) == KEY_MOUSE)
-       do_mouse();
-    else
-       ungetch(i);
+       /* If it was a mouse click, parse it with do_mouse() and it
+        * might become the unjustify key.  Else give it back to the
+        * input stream. */
+       if (i == KEY_MOUSE)
+           do_mouse();
+       else
+           ungetch(i);
+       i = get_kbinput(edit, &meta);
 #endif
+    }
 
-    if ((i = wgetch(edit)) != NANO_UNJUSTIFY_KEY) {
+    if (i != NANO_UNJUSTIFY_KEY) {
        ungetch(i);
        /* Did we back up anything at all? */
        if (cutbuffer != cutbuffer_save)
@@ -2761,14 +2761,11 @@ int do_exit(void)
            finish(0);
     }
 
-    if (ISSET(TEMP_OPT)) {
+    if (ISSET(TEMP_OPT))
        i = 1;
-    } else {
-       i = do_yesno(0, 0,
-                    _
-                    ("Save modified buffer (ANSWERING \"No\" WILL DESTROY CHANGES) ? "));
-    }
-
+    else
+       i = do_yesno(0, _("Save modified buffer (ANSWERING \"No\" WILL DESTROY CHANGES) ? "));
+    
 #ifdef DEBUG
     dump_buffer(fileage);
 #endif
@@ -3066,7 +3063,6 @@ int main(int argc, char *argv[])
     struct termios term;
 #endif
 #ifdef HAVE_GETOPT_LONG
-    int option_index = 0;
     const struct option long_options[] = {
        {"help", 0, 0, 'h'},
 #ifdef ENABLE_MULTIBUFFER
@@ -3140,7 +3136,7 @@ int main(int argc, char *argv[])
 
 #ifdef HAVE_GETOPT_LONG
     while ((optchr = getopt_long(argc, argv, "h?BDFHIMNQ:RST:VY:abcdefgijklmo:pr:s:tvwxz",
-                                long_options, &option_index)) != -1) {
+                                long_options, NULL)) != -1) {
 #else
     while ((optchr =
            getopt(argc, argv, "h?BDFHIMNQ:RST:VY:abcdefgijklmo:pr:s:tvwxz")) != -1) {
@@ -3515,7 +3511,7 @@ int main(int argc, char *argv[])
        raw();
 #endif
 
-       kbinput = get_kbinput(edit, &meta, ISSET(REBIND_DELETE));
+       kbinput = get_kbinput(edit, &meta);
 #ifdef DEBUG
        fprintf(stderr, "AHA!  %c (%d)\n", kbinput, kbinput);
 #endif
@@ -3558,8 +3554,8 @@ int main(int argc, char *argv[])
 #else
            for (s = main_list; s != NULL && !keyhandled; s = s->next) {
 #endif
-               if ((s->val >= 0 && kbinput == s->val) ||
-                   (s->func_key > 0 && kbinput == s->func_key)) {
+               if ((s->val != NANO_NO_KEY && kbinput == s->val) ||
+                   (s->func_key != NANO_NO_KEY && kbinput == s->func_key)) {
                    if (ISSET(VIEW_MODE) && !s->viewok)
                        print_view_warning();
                    else {
index eaf1b8f310d874e0edf66c3f9511d201a1904e9c..44c23196a1a052b8783059b9889d56fb576e75c1 100644 (file)
@@ -90,8 +90,9 @@
 #endif
 
 /* Assume ERR is defined as -1.  To avoid duplicate case values when
-   some key definitions are missing, we have to set these all to
-   different negative values other than -1. */
+   some key definitions are missing, we have to set all of these, and
+   all of the special sentinel values below, to different negative
+   values other than -1. */
 
 /* HP-UX 10 & 11 do not seem to support KEY_HOME and KEY_END */
 #ifndef KEY_HOME
 #define KEY_RESIZE -4
 #endif
 
-/* Slang does not seem to support KEY_SUSPEND */
+/* Slang does not seem to support KEY_SUSPEND, KEY_SLEFT, or
+   KEY_SRIGHT */
 #ifndef KEY_SUSPEND
 #define KEY_SUSPEND -5
 #endif
 
-/* Non-ncurses may not support KEY_UP and KEY_DOWN */
-#ifndef KEY_UP
-#define KEY_UP -6
+#ifndef KEY_SLEFT
+#define KEY_SLEFT -6
 #endif
 
-#ifndef KEY_DOWN
-#define KEY_DOWN -7
+#ifndef KEY_SRIGHT
+#define KEY_SRIGHT -7
 #endif
 
 #define VERMSG "GNU nano " VERSION
@@ -168,18 +169,19 @@ typedef struct openfilestruct {
 #endif
 
 typedef struct shortcut {
-   int val;            /* Actual sequence that generates the keystroke,
-                          or -1 for none */
-   int altval;         /* Alt key for this function, or 0 for none */
-   int func_key;       /* Function key we want bound */
-   int misc;           /* Other Alt key we want bound, or 0 for none */
-   int viewok;         /* is this function legal in view mode? */
-   int (*func) (void); /* Function to call when we catch this key */
-   const char *desc;   /* Description, e.g. "Page Up" */
+    /* Key values that aren't used should be set to NANO_NO_KEY */
+    int val;           /* Special sentinel key or control key we want
+                        * bound */
+    int altval;                /* Alt key we want bound */
+    int func_key;      /* Function key we want bound */
+    int misc;          /* Other Alt key we want bound */
+    int viewok;                /* Is this function legal in view mode? */
+    int (*func) (void);        /* Function to call when we catch this key */
+    const char *desc;  /* Description, e.g. "Page Up" */
 #ifndef DISABLE_HELP
-   const char *help;   /* Help file entry text */
+    const char *help;  /* Help file entry text */
 #endif
-   struct shortcut *next;
+    struct shortcut *next;
 } shortcut;
 
 #ifndef NANO_SMALL
@@ -348,10 +350,17 @@ typedef struct historyheadtype {
 /* Some semi-changeable keybindings; don't play with unless you're sure
    you know what you're doing */
 
+/* No key at all. */
+#define NANO_NO_KEY            -8
+
+/* Special sentinel key. */
+#define NANO_HISTORY_KEY       -9
+
+/* Normal keys. */
 #define NANO_INSERTFILE_KEY    NANO_CONTROL_R
 #define NANO_INSERTFILE_FKEY   KEY_F(5)
-#define NANO_EXIT_KEY          NANO_CONTROL_X
-#define NANO_EXIT_FKEY                 KEY_F(2)
+#define NANO_EXIT_KEY          NANO_CONTROL_X
+#define NANO_EXIT_FKEY         KEY_F(2)
 #define NANO_WRITEOUT_KEY      NANO_CONTROL_O
 #define NANO_WRITEOUT_FKEY     KEY_F(3)
 #define NANO_GOTO_KEY          NANO_CONTROL_7
index ea59974d391d68b83e9f3bed75d9b8aedb6ec8a3..097588a5c0cd84e2d1cad602c0263ec4815f9afb 100644 (file)
@@ -436,15 +436,15 @@ int check_wildcard_match(const char *text, const char *pattern);
 #endif
 
 /* Public functions in winio.c */
-int get_kbinput(WINDOW *win, int *meta, int rebind_delete);
-char *get_verbatim_kbinput(WINDOW *win, int *kbinput_len);
+int get_kbinput(WINDOW *win, int *meta);
+char *get_verbatim_kbinput(WINDOW *win, int *kbinput_len,
+       int allow_ascii);
 int get_ignored_kbinput(WINDOW *win);
-int get_accepted_kbinput(WINDOW *win, int kbinput, int *meta,
-       int rebind_delete);
+int get_accepted_kbinput(WINDOW *win, int kbinput, int *meta);
 int get_ascii_kbinput(WINDOW *win, int kbinput);
-int get_escape_seq_kbinput(WINDOW *win, int kbinput);
-int get_skip_tilde_kbinput(WINDOW *win, int errval, int retval);
-int get_mouseinput(int *mouse_x, int *mouse_y);
+int get_escape_seq_kbinput(WINDOW *win, char *escape_seq, int
+       escape_seq_len);
+int get_mouseinput(int *mouse_x, int *mouse_y, int shortcut);
 int do_first_line(void);
 int do_last_line(void);
 int xpt(const filestruct *fileptr, int index);
@@ -493,7 +493,7 @@ int statusq(int tabs, const shortcut *s, const char *def,
                historyheadtype *history_list,
 #endif
                const char *msg, ...);
-int do_yesno(int all, int leavecursor, const char *msg, ...);
+int do_yesno(int all, const char *msg);
 int total_refresh(void);
 void display_main_list(void);
 void statusbar(const char *msg, ...);
index cbfa29861a30a51f81f679f770ecdb1e7063afc5..ef1ea8f1541e5507ff1d7357229424d250ef0ed0 100644 (file)
@@ -711,7 +711,7 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin,
            curs_set(0);
            do_replace_highlight(TRUE, exp_word);
 
-           *i = do_yesno(1, 1, _("Replace this instance?"));
+           *i = do_yesno(1, _("Replace this instance?"));
 
            do_replace_highlight(FALSE, exp_word);
            free(exp_word);
index 3428c0ba88fd2fb397a78616c3d9b0532c8c242d..24fec70c4367c5ee35f54d98e378fdc7af17b641 100644 (file)
@@ -37,12 +37,12 @@ static int statblank = 0;   /* Number of keystrokes left after
 /* Read in a single input character.  If it's ignored, swallow it and go
  * on.  Otherwise, try to translate it from ASCII and extended (keypad)
  * input.  Assume nodelay(win) is FALSE. */
-int get_kbinput(WINDOW *win, int *meta, int rebind_delete)
+int get_kbinput(WINDOW *win, int *meta)
 {
     int kbinput, retval;
 
     kbinput = get_ignored_kbinput(win);
-    retval = get_accepted_kbinput(win, kbinput, meta, rebind_delete);
+    retval = get_accepted_kbinput(win, kbinput, meta);
 
     return retval;
 }
@@ -50,7 +50,8 @@ int get_kbinput(WINDOW *win, int *meta, int rebind_delete)
 /* Read in a string of input characters (e. g. an escape sequence)
  * verbatim, and return the length of the string in kbinput_len.  Assume
  * nodelay(win) is FALSE. */
-char *get_verbatim_kbinput(WINDOW *win, int *kbinput_len)
+char *get_verbatim_kbinput(WINDOW *win, int *kbinput_len,
+       int allow_ascii)
 {
     char *verbatim_kbinput;
     int kbinput = wgetch(win);
@@ -59,7 +60,7 @@ char *get_verbatim_kbinput(WINDOW *win, int *kbinput_len)
     verbatim_kbinput[0] = kbinput;
     *kbinput_len = 1;
 
-    if (kbinput >= '0' && kbinput <= '2')
+    if (allow_ascii && kbinput >= '0' && kbinput <= '2')
        /* Entering a three-digit decimal ASCII code from 000-255 in
         * verbatim mode will produce the corresponding ASCII
         * character. */
@@ -111,8 +112,7 @@ int get_ignored_kbinput(WINDOW *win)
 
 /* Translate acceptable ASCII and extended (keypad) input.  Set meta to
  * 1 if we get a Meta sequence.  Assume nodelay(win) is FALSE. */
-int get_accepted_kbinput(WINDOW *win, int kbinput, int *meta,
-       int rebind_delete)
+int get_accepted_kbinput(WINDOW *win, int kbinput, int *meta)
 {
     *meta = 0;
 
@@ -143,23 +143,33 @@ int get_accepted_kbinput(WINDOW *win, int kbinput, int *meta,
                    else if (kbinput >= 'a' && kbinput <= '~')
                        kbinput -= 96;
                    break;
+               case 'O':
+               case 'o':
                /* Terminal breakage, part 1: We shouldn't get an escape
                 * sequence here for terminals that support Delete, but
                 * we do sometimes on FreeBSD.  Thank you, Wouter van
                 * Hemel. */
                case '[':
+               {
+                   int old_kbinput = kbinput, escape_seq_len;
+                   char *escape_seq;
                    nodelay(win, TRUE);
                    kbinput = wgetch(win);
                    switch (kbinput) {
                        case ERR:
-                           kbinput = '[';
+                           kbinput = tolower(old_kbinput);
                            *meta = 1;
                            break;
                        default:
-                           kbinput = get_escape_seq_kbinput(win, kbinput);
+                           ungetch(kbinput);
+                           ungetch(old_kbinput);
+                           escape_seq = get_verbatim_kbinput(win, &escape_seq_len, 0);
+                           kbinput = get_escape_seq_kbinput(win, escape_seq, escape_seq_len);
+                           free(escape_seq);
                    }
                    nodelay(win, FALSE);
                    break;
+               }
                default:
                    /* Esc [character] == Meta-[character] */
                    kbinput = tolower(kbinput);
@@ -168,8 +178,8 @@ int get_accepted_kbinput(WINDOW *win, int kbinput, int *meta,
            break;
        case NANO_CONTROL_8:
            /* Terminal breakage, part 2: We shouldn't get Ctrl-8
-            * (Ctrl-?) for Backspace, but we do sometimes on Linux. */
-           kbinput = NANO_BACKSPACE_KEY;
+            * (Ctrl-?) for Backspace or Delete, but we do sometimes. */
+           kbinput = ISSET(REBIND_DELETE) ? NANO_DELETE_KEY : NANO_BACKSPACE_KEY;
            break;
        case KEY_DOWN:
            kbinput = NANO_DOWN_KEY;
@@ -193,7 +203,7 @@ int get_accepted_kbinput(WINDOW *win, int kbinput, int *meta,
            /* Terminal breakage, part 3: We should only get KEY_DC when
             * hitting Delete, but we get it when hitting Backspace
             * sometimes on FreeBSD.  Thank you, Lee Nelson. */
-           kbinput = (rebind_delete) ? NANO_BACKSPACE_KEY : NANO_DELETE_KEY;
+           kbinput = ISSET(REBIND_DELETE) ? NANO_BACKSPACE_KEY : NANO_DELETE_KEY;
            break;
        case KEY_IC:
            kbinput = NANO_INSERTFILE_KEY;
@@ -213,6 +223,12 @@ int get_accepted_kbinput(WINDOW *win, int kbinput, int *meta,
        case KEY_SUSPEND:
            kbinput = NANO_SUSPEND_KEY;
            break;
+       case KEY_SLEFT:
+           kbinput = NANO_BACK_KEY;
+           break;
+       case KEY_SRIGHT:
+           kbinput = NANO_FORWARD_KEY;
+           break;
     }
 #ifdef DEBUG
     fprintf(stderr, "get_accepted_kbinput(): kbinput = %d, meta = %d\n", kbinput, *meta);
@@ -230,7 +246,7 @@ int get_ascii_kbinput(WINDOW *win, int kbinput)
        case '0':
        case '1':
        case '2':
-           retval = (kbinput - 48) * 100;
+           retval = (kbinput - '0') * 100;
            break;
        default:
            return kbinput;
@@ -244,14 +260,14 @@ int get_ascii_kbinput(WINDOW *win, int kbinput)
        case '3':
        case '4':
        case '5':
-           retval += (kbinput - 48) * 10;
+           retval += (kbinput - '0') * 10;
            break;
        case '6':
        case '7':
        case '8':
        case '9':
            if (retval < 200) {
-               retval += (kbinput - 48) * 10;
+               retval += (kbinput - '0') * 10;
                break;
            }
        default:
@@ -266,14 +282,14 @@ int get_ascii_kbinput(WINDOW *win, int kbinput)
        case '3':
        case '4':
        case '5':
-           retval += kbinput - 48;
+           retval += kbinput - '0';
            break;
        case '6':
        case '7':
        case '8':
        case '9':
            if (retval < 250) {
-               retval += kbinput - 48;
+               retval += kbinput - '0';
                break;
            }
        default:
@@ -287,45 +303,243 @@ int get_ascii_kbinput(WINDOW *win, int kbinput)
 }
 
 /* Translate common escape sequences for some keys.  These are generated
- * when the terminal doesn't support those keys.  Assume nodelay(win) is
- * TRUE. */
-int get_escape_seq_kbinput(WINDOW *win, int kbinput)
+ * when the terminal doesn't support those keys.  Assume that Escape has
+ * already been read in, and that nodelay(win) is TRUE. */
+int get_escape_seq_kbinput(WINDOW *win, char *escape_seq, int
+       escape_seq_len)
 {
-    switch (kbinput) {
-       case '3':
-           /* Esc [ 3 ~ == kdch1 on many terminals. */
-           kbinput = get_skip_tilde_kbinput(win, kbinput, NANO_DELETE_KEY);
-           break;
+    int kbinput = -1;
+
+    if (escape_seq_len > 1) {
+       switch (escape_seq[0]) {
+           case 'O':
+               switch (escape_seq[1]) {
+                   case 'A': /* Esc O A == Up on xterm. */
+                       kbinput = NANO_UP_KEY;
+                       break;
+                   case 'B': /* Esc O B == Down on xterm. */
+                       kbinput = NANO_DOWN_KEY;
+                       break;
+                   case 'C': /* Esc O C == Right on xterm. */
+                       kbinput = NANO_FORWARD_KEY;
+                       break;
+                   case 'D': /* Esc O D == Left on xterm. */
+                       kbinput = NANO_BACK_KEY;
+                       break;
+                   case 'F': /* Esc O F == End on xterm. */
+                       kbinput = NANO_END_KEY;
+                       break;
+                   case 'H': /* Esc O H == Home on xterm. */
+                       kbinput = NANO_HOME_KEY;
+                       break;
+                   case 'a': /* Esc O a == Ctrl-Up on rxvt. */
+                       kbinput = NANO_UP_KEY;
+                       break;
+                   case 'b': /* Esc O b == Ctrl-Down on rxvt. */
+                       kbinput = NANO_DOWN_KEY;
+                       break;
+                   case 'c': /* Esc O c == Ctrl-Right on rxvt. */
+                       kbinput = NANO_FORWARD_KEY;
+                       break;
+                   case 'd': /* Esc O d == Ctrl-Left on rxvt. */
+                       kbinput = NANO_BACK_KEY;
+                       break;
+               }
+               break;
+           case 'o':
+               switch (escape_seq[1]) {
+                   case 'a': /* Esc o a == Ctrl-Up on Eterm. */
+                       kbinput = NANO_UP_KEY;
+                       break;
+                   case 'b': /* Esc o b == Ctrl-Down on Eterm. */
+                       kbinput = NANO_DOWN_KEY;
+                       break;
+                   case 'c': /* Esc o c == Ctrl-Right on Eterm. */
+                       kbinput = NANO_FORWARD_KEY;
+                       break;
+                   case 'd': /* Esc o d == Ctrl-Left on Eterm. */
+                       kbinput = NANO_BACK_KEY;
+                       break;
+               }
+               break;
+           case '[':
+               switch (escape_seq[1]) {
+                   case '1':
+                       if (escape_seq_len >= 5) {
+                           if (!strncmp(escape_seq, "[1;2", 4)) {
+                               switch (escape_seq[4]) {
+                                   case 'A':
+                                       /* Esc [ 1 ; 2 A == Shift-Up on
+                                        * xterm. */
+                                       kbinput = NANO_UP_KEY;
+                                       break;
+                                   case 'B':
+                                       /* Esc [ 1 ; 2 B == Shift-Down
+                                        * on xterm. */
+                                       kbinput = NANO_DOWN_KEY;
+                                       break;
+                                   case 'C':
+                                       /* Esc [ 1 ; 2 C == Shift-Right
+                                        * on xterm. */
+                                       kbinput = NANO_FORWARD_KEY;
+                                       break;
+                                   case 'D':
+                                       /* Esc [ 1 ; 2 D == Shift-Left
+                                        * on xterm. */
+                                       kbinput = NANO_BACK_KEY;
+                                       break;
+                               }
+                           } else if (!strncmp(escape_seq, "[1;5", 4)) {
+                               switch (escape_seq[4]) {
+                                   case 'A':
+                                       /* Esc [ 1 ; 5 A == Ctrl-Up on
+                                        * xterm. */
+                                       kbinput = NANO_UP_KEY;
+                                       break;
+                                   case 'B':
+                                       /* Esc [ 1 ; 5 B == Ctrl-Down on
+                                        * xterm. */
+                                       kbinput = NANO_DOWN_KEY;
+                                       break;
+                                   case 'C':
+                                       /* Esc [ 1 ; 5 C == Ctrl-Right
+                                        * on xterm. */
+                                       kbinput = NANO_FORWARD_KEY;
+                                       break;
+                                   case 'D':
+                                       /* Esc [ 1 ; 5 D == Ctrl-Left on
+                                        * xterm. */
+                                       kbinput = NANO_BACK_KEY;
+                                       break;
+                               }
+                           }
+                           break;
+                       } else {
+                           /* Esc [ 1 ~ == Home on Linux console. */
+                           kbinput = NANO_HOME_KEY;
+                           break;
+                       }
+                   case '2': /* Esc [ 2 ~ == Insert on Linux
+                              * console/xterm. */
+                       kbinput = NANO_INSERTFILE_KEY;
+                       break;
+                   case '3': /* Esc [ 3 ~ == Delete on Linux
+                              * console/xterm. */
+                       kbinput = NANO_DELETE_KEY;
+                       break;
+                   case '4': /* Esc [ 4 ~ == End on Linux
+                              * console/xterm. */
+                       kbinput = NANO_END_KEY;
+                       break;
+                   case '5': /* Esc [ 5 ~ == PageUp on Linux
+                              * console/xterm, Esc [ 5 ^ == PageUp on
+                              * Eterm. */
+                       kbinput = NANO_PREVPAGE_KEY;
+                       break;
+                   case '6': /* Esc [ 6 ~ == PageDown on Linux
+                              * console/xterm, Esc [ 6 ^ == PageDown on
+                              * Eterm. */
+                       kbinput = NANO_NEXTPAGE_KEY;
+                       break;
+                   case '7': /* Esc [ 7 ~ == Home on rxvt. */
+                       kbinput = NANO_HOME_KEY;
+                       break;
+                   case '8': /* Esc [ 8 ~ == End on rxvt. */
+                       kbinput = NANO_END_KEY;
+                       break;
+                   case '9': /* Esc [ 9 == Delete on Hurd console. */
+                       kbinput = NANO_DELETE_KEY;
+                       break;
+                   case '@': /* Esc [ @ == Insert on Hurd console. */
+                       kbinput = NANO_INSERTFILE_KEY;
+                       break;
+                   case 'A': /* Esc [ A == Up on Linux console/FreeBSD
+                              * console/Hurd console/rxvt/Eterm. */
+                       kbinput = NANO_UP_KEY;
+                       break;
+                   case 'B': /* Esc [ B == Down on Linux
+                              * console/FreeBSD console/Hurd
+                              * console/rxvt/Eterm. */
+                       kbinput = NANO_DOWN_KEY;
+                       break;
+                   case 'C': /* Esc [ C == Right on Linux
+                              * console/FreeBSD console/Hurd
+                              * console/rxvt/Eterm. */
+                       kbinput = NANO_FORWARD_KEY;
+                       break;
+                   case 'D': /* Esc [ D == Left on Linux
+                              * console/FreeBSD console/Hurd
+                              * console/rxvt/Eterm. */
+                       kbinput = NANO_BACK_KEY;
+                       break;
+                   case 'F': /* Esc [ F == End on FreeBSD
+                              * console/Eterm. */
+                       kbinput = NANO_END_KEY;
+                       break;
+                   case 'G': /* Esc [ G == PageDown on FreeBSD
+                                  * console. */
+                       kbinput = NANO_NEXTPAGE_KEY;
+                       break;
+                   case 'H': /* Esc [ H == Home on FreeBSD
+                              * console/Hurd console/Eterm. */
+                       kbinput = NANO_HOME_KEY;
+                       break;
+                   case 'I': /* Esc [ I == PageUp on FreeBSD
+                              * console. */
+                       kbinput = NANO_PREVPAGE_KEY;
+                       break;
+                   case 'L': /* Esc [ L == Insert on FreeBSD
+                              * console. */
+                       kbinput = NANO_INSERTFILE_KEY;
+                       break;
+                   case 'U': /* Esc [ U == PageDown on Hurd console. */
+                       kbinput = NANO_NEXTPAGE_KEY;
+                       break;
+                   case 'V': /* Esc [ V == PageUp on Hurd console. */
+                       kbinput = NANO_PREVPAGE_KEY;
+                       break;
+                   case 'Y': /* Esc [ Y == End on Hurd console. */
+                       kbinput = NANO_END_KEY;
+                       break;
+                   case 'a': /* Esc [ a == Shift-Up on rxvt and
+                              * Eterm. */
+                       kbinput = NANO_UP_KEY;
+                       break;
+                   case 'b': /* Esc [ b == Shift-Down on rxvt and
+                              * Eterm. */
+                       kbinput = NANO_DOWN_KEY;
+                       break;
+                   case 'c': /* Esc [ c == Shift-Right on rxvt. */
+                       kbinput = NANO_FORWARD_KEY;
+                       break;
+                   case 'd': /* Esc [ d == Shift-Left on rxvt. */
+                       kbinput = NANO_BACK_KEY;
+                       break;
+               }
+               break;
+       }
     }
-    return kbinput;
-}
 
-/* If there is no next character, return the passed-in error value.  If
- * the next character's a tilde, eat it and return the passed-in
- * return value.  Otherwise, return the next character.  Assume
- * nodelay(win) is TRUE. */
-int get_skip_tilde_kbinput(WINDOW *win, int errval, int retval)
-{
-    int kbinput = wgetch(win);
-    switch (kbinput) {
-       case ERR:
-           return errval;
-       case '~':
-           return retval;
-       default:
-           return kbinput;
+    if (kbinput == -1) {
+       /* This escape sequence is unrecognized; send it back. */
+       for (; escape_seq_len > 1; escape_seq_len--)
+           ungetch(escape_seq[escape_seq_len - 1]);
+       kbinput = escape_seq[0];
     }
+
+    return kbinput;
 }
 
 #ifndef DISABLE_MOUSE
-/* Check for a mouse event.  If it took place on the shortcut list on
- * the bottom two lines of the screen (assuming that the shortcut list is
- * visible), figure out which shortcut was clicked and ungetch() the
- * equivalent keystroke(s), otherwise do nothing.  Return 0 if no
- * keystrokes were ungetch()ed, or 1 if at least one was.  Also, return
- * the screen coordinates where the mouse event took place in *mouse_x
- * and *mouse_y.  Assume that KEY_MOUSE has already been read in. */
-int get_mouseinput(int *mouse_x, int *mouse_y)
+/* Check for a mouse event, and if one's taken place, save the
+ * coordinates where it took place in mouse_x and mouse_y.  After that,
+ * if allow_shortcuts is zero, return 0.  Otherwise, if the mouse event
+ * took place on the shortcut list on the bottom two lines of the screen
+ * (assuming that the shortcut list is visible), figure out which
+ * shortcut was clicked and ungetch() the equivalent keystroke(s).
+ * Return 0 if no keystrokes were ungetch()ed, or 1 if at least one was.
+ * Assume that KEY_MOUSE has already been read in. */
+int get_mouseinput(int *mouse_x, int *mouse_y, int allow_shortcuts)
 {
     MEVENT mevent;
 
@@ -340,10 +554,14 @@ int get_mouseinput(int *mouse_x, int *mouse_y)
     *mouse_x = mevent.x;
     *mouse_y = mevent.y;
 
-    /* If the current shortcut list is being displayed on the last two
-     * lines of the screen and the mouse event took place inside it,
-     * we need to figure out which shortcut was clicked and ungetch()
-     * the equivalent keystroke(s) for it. */
+    /* If we're not allowing shortcuts' we're done now. */
+    if (!allow_shortcuts)
+       return 0;
+
+    /* Otherwise, if the current shortcut list is being displayed on the
+     * last two lines of the screen and the mouse event took place
+     * inside it, we need to figure out which shortcut was clicked and
+     * ungetch() the equivalent keystroke(s) for it. */
     if (!ISSET(NO_HELP) && wenclose(bottomwin, *mouse_y, *mouse_x)) {
        int i, j;
        int currslen;
@@ -679,7 +897,7 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
        input */
     wrefresh(edit);
 
-    while ((kbinput = get_kbinput(bottomwin, &meta, ISSET(REBIND_DELETE))) != NANO_ENTER_KEY) {
+    while ((kbinput = get_kbinput(bottomwin, &meta)) != NANO_ENTER_KEY) {
        for (t = s; t != NULL; t = t->next) {
 #ifdef DEBUG
            fprintf(stderr, "Aha! \'%c\' (%d)\n", kbinput, kbinput);
@@ -872,12 +1090,12 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
                    fprintf(stderr, "Aha! \'%c\' (%d)\n", kbinput,
                            kbinput);
 #endif
-                   if (meta == 1 && kbinput == t->val)
+                   if (meta == 1 && kbinput == t->altval)
                        /* We hit an Alt key.  Do like above.  We don't
                           just ungetch() the letter and let it get
                           caught above cause that screws the
                           keypad... */
-                       return t->val;
+                       return t->altval;
                }
 
            if (is_cntrl_char(kbinput))
@@ -993,19 +1211,20 @@ void bottombars(const shortcut *s)
            wmove(bottomwin, 1 + j, i * (COLS / numcols));
 
            /* Yucky sentinel values we can't handle a better way */
-           if (s->val == NANO_CONTROL_SPACE)
-               strcpy(keystr, "^ ");
+           if (s->val != NANO_NO_KEY) {
 #ifndef NANO_SMALL
-           else if (s->val == NANO_UP_KEY && s->misc == NANO_DOWN_KEY)
-               strncpy(keystr, _("Up"), 8);
-#endif /* NANO_SMALL */
-           else if (s->val > 0) {
-               if (s->val < 64)
-                   sprintf(keystr, "^%c", s->val + 64);
+               if (s->val == NANO_HISTORY_KEY)
+                   strncpy(keystr, _("Up"), 8);
+               else
+#endif
+               if (s->val == NANO_CONTROL_SPACE)
+                   strcpy(keystr, "^ ");
+               else if (s->val == NANO_CONTROL_8)
+                   strcpy(keystr, "^?");
                else
-                   sprintf(keystr, "M-%c", toupper(s->val));
-           } else if (s->altval > 0)
-               sprintf(keystr, "M-%c", s->altval);
+                   sprintf(keystr, "^%c", s->val + 64);
+           } else if (s->altval != NANO_NO_KEY)
+               sprintf(keystr, "M-%c", toupper(s->altval));
 
            onekey(keystr, s->desc, COLS / numcols);
 
@@ -1632,11 +1851,9 @@ int statusq(int tabs, const shortcut *s, const char *def,
 /* Ask a simple yes/no question on the statusbar.  Returns 1 for Y, 0
  * for N, 2 for All (if all is nonzero when passed in) and -1 for abort
  * (^C). */
-int do_yesno(int all, int leavecursor, const char *msg, ...)
+int do_yesno(int all, const char *msg)
 {
-    va_list ap;
-    char *foo;
-    int ok = -2;
+    int ok = -2, width = 16;
     const char *yesstr;                /* String of yes characters accepted */
     const char *nostr;         /* Same for no */
     const char *allstr;                /* And all, surprise! */
@@ -1653,70 +1870,75 @@ int do_yesno(int all, int leavecursor, const char *msg, ...)
     if (!ISSET(NO_HELP)) {
        char shortstr[3];               /* Temp string for Y, N, A. */
 
+       if (COLS < 32)
+           width = COLS / 2;
+
        /* Write the bottom of the screen. */
        blank_bottombars();
 
        sprintf(shortstr, " %c", yesstr[0]);
        wmove(bottomwin, 1, 0);
-       onekey(shortstr, _("Yes"), 16);
+       onekey(shortstr, _("Yes"), width);
 
        if (all) {
-           wmove(bottomwin, 1, 16);
+           wmove(bottomwin, 1, width);
            shortstr[1] = allstr[0];
-           onekey(shortstr, _("All"), 16);
+           onekey(shortstr, _("All"), width);
        }
 
        wmove(bottomwin, 2, 0);
        shortstr[1] = nostr[0];
-       onekey(shortstr, _("No"), 16);
+       onekey(shortstr, _("No"), width);
 
        wmove(bottomwin, 2, 16);
-       onekey("^C", _("Cancel"), 16);
+       onekey("^C", _("Cancel"), width);
     }
 
-    foo = charalloc(COLS);
-    va_start(ap, msg);
-    vsnprintf(foo, COLS, msg, ap);
-    va_end(ap);
-    foo[COLS - 1] = '\0';
-
     wattron(bottomwin, A_REVERSE);
 
     blank_statusbar();
-    mvwaddstr(bottomwin, 0, 0, foo);
-    free(foo);
+    mvwaddnstr(bottomwin, 0, 0, msg, COLS - 1);
 
     wattroff(bottomwin, A_REVERSE);
 
     wrefresh(bottomwin);
 
     do {
-       int kbinput = wgetch(edit);
+       int kbinput;
+       int meta;
 #ifndef DISABLE_MOUSE
-       MEVENT mevent;
+       int mouse_x, mouse_y;
 #endif
 
-       if (kbinput == NANO_CONTROL_C)
+       kbinput = get_kbinput(edit, &meta);
+
+       if (kbinput == NANO_CANCEL_KEY)
            ok = -1;
 #ifndef DISABLE_MOUSE
-       /* Look ma!  We get to duplicate lots of code from do_mouse!! */
-       else if (kbinput == KEY_MOUSE && getmouse(&mevent) != ERR &&
-               wenclose(bottomwin, mevent.y, mevent.x) &&
-               !ISSET(NO_HELP) && mevent.x < 32 &&
-               mevent.y >= editwinrows + 3) {
-           int x = mevent.x /= 16;
-               /* Did we click in the first column of shortcuts, or the
-                * second? */
-           int y = mevent.y - editwinrows - 3;
-               /* Did we click in the first row of shortcuts? */
-
-           assert(0 <= x && x <= 1 && 0 <= y && y <= 1);
-           /* x = 0 means they clicked Yes or No.
-            * y = 0 means Yes or All. */
-           ok = -2 * x * y + x - y + 1;
-
-           if (ok == 2 && !all)
-               ok = -2;
+       /* Look ma!  We get to duplicate lots of code from
+        * do_mouse()!! */
+       else if (kbinput == KEY_MOUSE) {
+           kbinput = get_mouseinput(&mouse_x, &mouse_y, 0);
+
+           if (mouse_x != -1 && mouse_y != -1 && !ISSET(NO_HELP) &&
+               wenclose(bottomwin, mouse_y, mouse_x) && mouse_x <
+               (width * 2) && mouse_y >= editwinrows + 3) {
+
+               int x = mouse_x / width;
+                   /* Did we click in the first column of shortcuts, or
+                    * the second? */
+               int y = mouse_y - editwinrows - 3;
+                   /* Did we click in the first row of shortcuts? */
+
+               assert(0 <= x && x <= 1 && 0 <= y && y <= 1);
+
+               /* x = 0 means they clicked Yes or No.
+                * y = 0 means Yes or All. */
+               ok = -2 * x * y + x - y + 1;
+
+               if (ok == 2 && !all)
+                   ok = -2;
+           }
        }
 #endif
        /* Look for the kbinput in the yes, no and (optionally) all
@@ -1729,9 +1951,6 @@ int do_yesno(int all, int leavecursor, const char *msg, ...)
            ok = 2;
     } while (ok == -2);
 
-    /* Then blank the statusbar. */
-    blank_statusbar_refresh();
-
     return ok;
 }
 
@@ -1974,7 +2193,7 @@ int do_help(void)
            no_more = 1;
            continue;
        }
-    } while ((kbinput = get_kbinput(edit, &meta, ISSET(REBIND_DELETE))) != NANO_EXIT_KEY && kbinput != NANO_EXIT_FKEY);
+    } while ((kbinput = get_kbinput(edit, &meta)) != NANO_EXIT_KEY && kbinput != NANO_EXIT_FKEY);
 
     currshortcut = oldshortcut;