diff --git a/ChangeLog b/ChangeLog
index f4420cc7dca84b440a7352b70e02e95d65a8ac95..0d829ebbb1cc588c2e480b4ecda8fe17463dfbfa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,27 @@
 CVS code -
+- General:
+	- Minor overhaul and abstraction of the lowest level of mouse
+	  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.
+	- 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
+	  miscellaneous key value (misc), and tweak the
+	  shortcut-handling code to deal with this.  These changes allow
+	  NANO_OPEN(PREV|NEXT)_ALTKEY to work properly when added to the
+	  shortcut entries for NANO_OPEN(PREV|NEXT)_KEY.  Also remove
+	  the values in the shortcut list that were made redundant by
+	  the low-level input overhaul, use toupper() instead of
+	  subtracting 32 from values for greater 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)
+	- 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.
 - files.c:
   do_writeout()
 	- Prompt the user if we're trying to save an existing file (and
diff --git a/TODO b/TODO
index c615348c1339814cf7e35b7747cedbf746a8d743..9ae8054f8bce91dabb4f5a75efa0c6800328d8af 100644
--- a/TODO
+++ b/TODO
@@ -7,6 +7,7 @@ For version 1.4:
 - Undo/Redo key?
 - Rebindable keys?
 - Keystroke to implement "Add next sequence as raw" like vi's ^V.
+  [DONE for edit window, needs to be done for statusbar prompt]
 - Spell check selected text only.
 - Make "To line" (^W^T) and "Read from Command" (^R^X) re-enter their
   parent menu when their keystroke is entered a second time (^W^T^T and
diff --git a/src/files.c b/src/files.c
index 6bda6ac6362b04b9332bf31786056aa763574655..452cd66032d658461435f37730689a67ecaa5cf5 100644
--- a/src/files.c
+++ b/src/files.c
@@ -489,7 +489,7 @@ int do_insertfile(int loading_file)
 
 #ifndef NANO_SMALL
 #ifdef ENABLE_MULTIBUFFER
-	if (i == TOGGLE_LOAD_KEY) {
+	if (i == TOGGLE_MULTIBUFFER_KEY) {
 	    /* Don't allow toggling if we're in view mode. */
 	    if (!ISSET(VIEW_MODE))
 		TOGGLE(MULTIBUFFER);
diff --git a/src/global.c b/src/global.c
index 3774098e7c78b3b4df0908d7a6cae676e941359a..34a6589e8e982011b3898fd13bbe8c1d7421df50 100644
--- a/src/global.c
+++ b/src/global.c
@@ -172,7 +172,7 @@ void sc_init_one(shortcut **shortcutage, int key, const char *desc,
 #ifndef DISABLE_HELP
 	const char *help,
 #endif
-	int alt, int misc1, int misc2, int view, int (*func) (void))
+	int alt, int func_key, int misc, int view, int (*func) (void))
 {
     shortcut *s;
 
@@ -192,8 +192,8 @@ void sc_init_one(shortcut **shortcutage, int key, const char *desc,
     s->help = help;
 #endif
     s->altval = alt;
-    s->misc1 = misc1;
-    s->misc2 = misc2;
+    s->func_key = func_key;
+    s->misc = misc;
     s->viewok = view;
     s->func = func;
     s->next = NULL;
@@ -235,7 +235,7 @@ void toggle_init(void)
     char *toggle_wrap_msg;
 #endif
 #ifdef ENABLE_MULTIBUFFER
-    char *toggle_load_msg;
+    char *toggle_multibuffer_msg;
 #endif
 #ifdef ENABLE_COLOR
     char *toggle_syntax_msg;
@@ -266,22 +266,22 @@ void toggle_init(void)
     toggle_wrap_msg = _("Auto line wrap");
 #endif
 #ifdef ENABLE_MULTIBUFFER
-    toggle_load_msg = _("Multiple file buffers");
+    toggle_multibuffer_msg = _("Multiple file buffers");
 #endif
 
+    toggle_init_one(TOGGLE_NOHELP_KEY, toggle_nohelp_msg, NO_HELP);
+#ifdef ENABLE_MULTIBUFFER
+    toggle_init_one(TOGGLE_MULTIBUFFER_KEY, toggle_multibuffer_msg, MULTIBUFFER);
+#endif
     toggle_init_one(TOGGLE_CONST_KEY, toggle_const_msg, CONSTUPDATE);
     toggle_init_one(TOGGLE_AUTOINDENT_KEY, toggle_autoindent_msg, AUTOINDENT);
-    toggle_init_one(TOGGLE_SUSPEND_KEY, toggle_suspend_msg, SUSPEND);
-    toggle_init_one(TOGGLE_NOHELP_KEY, toggle_nohelp_msg, NO_HELP);
 #ifndef DISABLE_WRAPPING
     toggle_init_one(TOGGLE_WRAP_KEY, toggle_wrap_msg, NO_WRAP);
 #endif
+    toggle_init_one(TOGGLE_CUTTOEND_KEY, toggle_cuttoend_msg, CUT_TO_END);
+    toggle_init_one(TOGGLE_SUSPEND_KEY, toggle_suspend_msg, SUSPEND);
 #ifndef DISABLE_MOUSE
     toggle_init_one(TOGGLE_MOUSE_KEY, toggle_mouse_msg, USE_MOUSE);
-#endif
-    toggle_init_one(TOGGLE_CUTTOEND_KEY, toggle_cuttoend_msg, CUT_TO_END);
-#ifdef ENABLE_MULTIBUFFER
-    toggle_init_one(TOGGLE_LOAD_KEY, toggle_load_msg, MULTIBUFFER);
 #endif
     toggle_init_one(TOGGLE_NOCONVERT_KEY, toggle_noconvert_msg, NO_CONVERT);
     toggle_init_one(TOGGLE_DOS_KEY, toggle_dos_msg, DOS_FILE);
@@ -321,27 +321,30 @@ void free_shortcutage(shortcut **shortcutage)
 void shortcut_init(int unjustify)
 {
 #ifndef DISABLE_HELP
-    const char *nano_help_msg = "", *nano_writeout_msg = "", *nano_exit_msg =
-	"", *nano_goto_msg = "", *nano_justify_msg =
-	"", *nano_replace_msg = "", *nano_insert_msg =
-	"", *nano_whereis_msg = "", *nano_whereis_next_msg =
-	"", *nano_prevpage_msg = "", *nano_nextpage_msg =
-	"", *nano_cut_msg = "", *nano_uncut_msg =
-	"", *nano_cursorpos_msg = "", *nano_spell_msg =
-	"", *nano_up_msg = "", *nano_down_msg =
-	"", *nano_forward_msg = "", *nano_back_msg = "", *nano_home_msg =
+    const char *nano_help_msg = "", *nano_writeout_msg =
+	"", *nano_exit_msg = "", *nano_goto_msg =
+	"", *nano_justify_msg = "", *nano_replace_msg =
+	"", *nano_insert_msg = "", *nano_whereis_msg =
+	"", *nano_whereis_next_msg = "", *nano_prevpage_msg =
+	"", *nano_nextpage_msg = "", *nano_cut_msg =
+	"", *nano_uncut_msg = "", *nano_cursorpos_msg =
+	"", *nano_spell_msg = "", *nano_up_msg =
+	"", *nano_down_msg = "", *nano_forward_msg =
+	"", *nano_back_msg = "", *nano_home_msg =
 	"", *nano_end_msg = "", *nano_firstline_msg =
 	"", *nano_lastline_msg = "", *nano_refresh_msg =
 	"", *nano_mark_msg = "", *nano_delete_msg =
 	"", *nano_backspace_msg = "", *nano_tab_msg =
-	"", *nano_enter_msg = "", *nano_cancel_msg =
-	"", *nano_unjustify_msg = "", *nano_append_msg =
-	"", *nano_prepend_msg = "", *nano_tofiles_msg =
-	"", *nano_gotodir_msg = "", *nano_case_msg =
-	"", *nano_reverse_msg = "", *nano_execute_msg =
-	"", *nano_dos_msg = "", *nano_mac_msg =
-	"", *nano_backup_msg = "", *nano_editstr_msg =
-	"", *nano_parabegin_msg = "", *nano_paraend_msg = "";
+	"", *nano_enter_msg = "", *nano_prevword_msg =
+	"", *nano_nextword_msg = "", *nano_verbatim_msg =
+	"", *nano_cancel_msg = "", *nano_unjustify_msg =
+	"", *nano_append_msg = "", *nano_prepend_msg =
+	"", *nano_tofiles_msg = "", *nano_gotodir_msg =
+	"", *nano_case_msg = "", *nano_reverse_msg =
+	"", *nano_execute_msg = "", *nano_dos_msg =
+	"", *nano_mac_msg = "", *nano_backup_msg =
+	"", *nano_editstr_msg = "", *nano_parabegin_msg =
+	"", *nano_paraend_msg = "";
 
 #ifdef ENABLE_MULTIBUFFER
     const char *nano_openprev_msg = "", *nano_opennext_msg =
@@ -386,6 +389,10 @@ void shortcut_init(int unjustify)
 	_("Delete the character to the left of the cursor");
     nano_tab_msg = _("Insert a tab character");
     nano_enter_msg = _("Insert a carriage return at the cursor position");
+    nano_prevword_msg = _("Move backward one word");
+    nano_nextword_msg = _("Move forward one word");
+    nano_verbatim_msg = _("Insert character(s) verbatim");
+    nano_enter_msg = _("Insert a carriage return at the cursor position");
     nano_case_msg =
 	_("Make the current search or replace case (in)sensitive");
     nano_tofiles_msg = _("Go to file browser");
@@ -422,39 +429,41 @@ void shortcut_init(int unjustify)
 #else
 #  define IFHELP(help, nextvar) help, nextvar
 #endif
+
     /* 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, 0), NANO_HELP_FKEY,
+		0, 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, 0), NANO_EXIT_FKEY,
+		0, 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, 0), NANO_EXIT_FKEY,
+		0, 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, 0), NANO_WRITEOUT_FKEY,
+		    0, 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, 0), NANO_JUSTIFY_FKEY,
+		    0, 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, 0), NANO_INSERTFILE_FKEY,
+		0,
 #ifdef ENABLE_MULTIBUFFER
 		VIEW
 #else
@@ -464,132 +473,126 @@ 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, 0), NANO_WHEREIS_FKEY,
+		0, 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, KEY_PPAGE, VIEW, do_page_up);
+		IFHELP(nano_prevpage_msg, 0), NANO_PREVPAGE_FKEY,
+		0, 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, KEY_NPAGE, VIEW, do_page_down);
+		IFHELP(nano_nextpage_msg, 0), NANO_NEXTPAGE_FKEY,
+		0, 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, 0), NANO_CUT_FKEY, 0, 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, 0), 0, 0, 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, 0), NANO_UNCUT_FKEY,
+		0, 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, 0), NANO_CURSORPOS_FKEY,
+		0, 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, 0), NANO_SPELL_FKEY,
+		0, 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);
+
+    sc_init_one(&main_list, NANO_REPLACE_KEY, _("Replace"),
+		IFHELP(nano_replace_msg, NANO_ALT_REPLACE_KEY),
+		NANO_REPLACE_FKEY, 0, NOVIEW, do_replace);
 
     sc_init_one(&main_list, NANO_UP_KEY, _("Up"),
-		IFHELP(nano_up_msg, 0),
-		KEY_UP, 0, VIEW, do_up);
+		IFHELP(nano_up_msg, 0), 0, 0, VIEW, do_up);
 
     sc_init_one(&main_list, NANO_DOWN_KEY, _("Down"),
-		IFHELP(nano_down_msg, 0),
-		KEY_DOWN, 0, VIEW, do_down);
+		IFHELP(nano_down_msg, 0), 0, 0, VIEW, do_down);
 
     sc_init_one(&main_list, NANO_FORWARD_KEY, _("Forward"),
-		IFHELP(nano_forward_msg, 0),
-		KEY_RIGHT, 0, VIEW, do_right);
+		IFHELP(nano_forward_msg, 0), 0, 0, VIEW, do_right);
 
     sc_init_one(&main_list, NANO_BACK_KEY, _("Back"),
-		IFHELP(nano_back_msg, 0),
-		KEY_LEFT, 0, VIEW, do_left);
+		IFHELP(nano_back_msg, 0), 0, 0, VIEW, do_left);
 
     sc_init_one(&main_list, NANO_HOME_KEY, _("Home"),
-		IFHELP(nano_home_msg, 0),
-		KEY_HOME, 362, VIEW, do_home);
+		IFHELP(nano_home_msg, 0), 0, 0, VIEW, do_home);
 
     sc_init_one(&main_list, NANO_END_KEY, _("End"),
-		IFHELP(nano_end_msg, 0),
-		KEY_END, 385, VIEW, do_end);
+		IFHELP(nano_end_msg, 0), 0, 0, 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, 0), 0, 0, 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);
 
     sc_init_one(&main_list, NANO_DELETE_KEY, _("Delete"),
-		IFHELP(nano_delete_msg, 0), KEY_DC,
-		NANO_CONTROL_D, NOVIEW, do_delete);
+		IFHELP(nano_delete_msg, 0), 0, 0, NOVIEW, do_delete);
 
     sc_init_one(&main_list, NANO_BACKSPACE_KEY, _("Backspace"),
-		IFHELP(nano_backspace_msg, 0),
-		KEY_BACKSPACE, 127, NOVIEW, do_backspace);
+		IFHELP(nano_backspace_msg, 0), 0, 0, NOVIEW, do_backspace);
 
     sc_init_one(&main_list, NANO_TAB_KEY, _("Tab"),
 		IFHELP(nano_tab_msg, 0), 0, 0, NOVIEW, do_tab);
 
-    sc_init_one(&main_list, NANO_REPLACE_KEY, _("Replace"),
-		    IFHELP(nano_replace_msg, NANO_ALT_REPLACE_KEY),
-		    NANO_REPLACE_FKEY, 0, NOVIEW, do_replace);
-
     sc_init_one(&main_list, NANO_ENTER_KEY, _("Enter"),
-		IFHELP(nano_enter_msg, 0),
-		KEY_ENTER, NANO_CONTROL_M, NOVIEW, do_enter);
-
-    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_enter_msg, 0), 0, 0, NOVIEW, do_enter);
 
 #ifndef NANO_SMALL
     sc_init_one(&main_list, NANO_NEXTWORD_KEY, _("Next Word"),
-		IFHELP(_("Move forward one word"), 0),
-		0, 0, VIEW, do_next_word);
+		IFHELP(nano_nextword_msg, 0), 0, 0, VIEW, do_next_word);
 
-    sc_init_one(&main_list, -9, _("Prev Word"),
-		IFHELP(_("Move backward one word"), NANO_PREVWORD_KEY), 0, 0,
-		VIEW, do_prev_word);
-#endif
-#if !defined(NANO_SMALL) && defined(HAVE_REGEX_H)
-    sc_init_one(&main_list, -9, _("Find Other Bracket"),
-		    IFHELP(nano_bracket_msg, NANO_BRACKET_KEY),
-		    0, 0, VIEW, do_find_bracket);
+    sc_init_one(&main_list, -1, _("Prev Word"),
+		IFHELP(nano_prevword_msg, NANO_PREVWORD_KEY),
+		0, 0, VIEW, do_prev_word);
 #endif
 
-    sc_init_one(&main_list, -9, _("Where Is Next"),
-		IFHELP(nano_whereis_next_msg, NANO_WHEREIS_NEXT_KEY), 0, 0,
-		VIEW, do_research);
+    sc_init_one(&main_list, -1, _("Verbatim Input"),
+		IFHELP(nano_verbatim_msg, NANO_VERBATIM_KEY),
+		0, 0, VIEW, do_verbatim_input);
 
 #ifdef ENABLE_MULTIBUFFER
-    sc_init_one(&main_list, -9, _("Previous File"),
-		    IFHELP(nano_openprev_msg, NANO_OPENPREV_KEY),
-		    0, 0, VIEW, open_prevfile_void);
-    sc_init_one(&main_list, -9, _("Next File"),
-		    IFHELP(nano_opennext_msg, NANO_OPENNEXT_KEY),
-		    0, 0, VIEW, open_nextfile_void);
+    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, -1, _("Next File"),
+		IFHELP(nano_opennext_msg, NANO_OPENNEXT_KEY),
+		0, 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);
+#endif
+
+    sc_init_one(&main_list, -1, _("Where Is Next"),
+		IFHELP(nano_whereis_next_msg, NANO_WHEREIS_NEXT_KEY),
+		0, 0, VIEW, do_research);
+
     free_shortcutage(&whereis_list);
 
     sc_init_one(&whereis_list, NANO_HELP_KEY, _("Get Help"),
-		IFHELP(nano_help_msg, 0), 0, 0, VIEW, do_help);
+		IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
+		0, VIEW, do_help);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&whereis_list, NANO_CANCEL_KEY, _("Cancel"),
@@ -597,8 +600,7 @@ void shortcut_init(int unjustify)
 
     /* 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, 0), 0, 0, VIEW, do_first_line);
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&whereis_list, NANO_LASTLINE_KEY, _("Last Line"),
@@ -606,11 +608,13 @@ void shortcut_init(int unjustify)
 
     /* Translators: try to keep this string under 10 characters long */
     sc_init_one(&whereis_list, NANO_OTHERSEARCH_KEY, _("Replace"),
-		IFHELP(nano_replace_msg, 0), 0, 0, VIEW, do_replace);
+		IFHELP(nano_replace_msg, 0), NANO_REPLACE_FKEY,
+		0, 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), 0, 0, VIEW, do_gotoline_void);
+		IFHELP(nano_goto_msg, 0), NANO_GOTO_FKEY,
+		0, VIEW, do_gotoline_void);
 
 #ifndef DISABLE_JUSTIFY
     /* Translators: try to keep this string under 10 characters long */
@@ -639,8 +643,8 @@ void shortcut_init(int unjustify)
 
 #ifndef NANO_SMALL
     /* Translators: try to keep this string under 10 characters long */
-    sc_init_one(&whereis_list, KEY_UP, _("History"),
-		IFHELP(nano_editstr_msg, 0), NANO_UP_KEY, 0, VIEW, 0);
+    sc_init_one(&whereis_list, NANO_UP_KEY, _("History"),
+		IFHELP(nano_editstr_msg, 0), 0, NANO_DOWN_KEY, VIEW, 0);
 #endif
 
 #endif /* !NANO_SMALL */
@@ -648,7 +652,8 @@ void shortcut_init(int unjustify)
     free_shortcutage(&replace_list);
 
     sc_init_one(&replace_list, NANO_HELP_KEY, _("Get Help"),
-		IFHELP(nano_help_msg, 0), 0, 0, VIEW, do_help);
+		IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
+		0, VIEW, do_help);
 
     sc_init_one(&replace_list, NANO_CANCEL_KEY, _("Cancel"),
 		IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
@@ -661,10 +666,12 @@ void shortcut_init(int unjustify)
 
     /* 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), 0, 0, VIEW, do_search);
+		IFHELP(nano_whereis_msg, 0), NANO_REPLACE_FKEY,
+		0, VIEW, do_search);
 
     sc_init_one(&replace_list, NANO_FROMSEARCHTOGOTO_KEY, _("Go To Line"), 
-		IFHELP(nano_goto_msg, 0), 0, 0, VIEW, do_gotoline_void);
+		IFHELP(nano_goto_msg, 0), NANO_GOTO_FKEY,
+		0, VIEW, do_gotoline_void);
 
 #ifndef NANO_SMALL
     sc_init_one(&replace_list, TOGGLE_CASE_KEY, _("Case Sens"),
@@ -678,14 +685,15 @@ void shortcut_init(int unjustify)
 		IFHELP(nano_regexp_msg, 0), 0, 0, VIEW, 0);
 #endif
 
-    sc_init_one(&replace_list, KEY_UP, _("History"),
-		IFHELP(nano_editstr_msg, 0), NANO_UP_KEY, 0, VIEW, 0);
+    sc_init_one(&replace_list, NANO_UP_KEY, _("History"),
+		IFHELP(nano_editstr_msg, 0), 0, 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), 0, 0, VIEW, do_help);
+		IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
+		0, VIEW, do_help);
 
     sc_init_one(&replace_list_2, NANO_CANCEL_KEY, _("Cancel"),
 		IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
@@ -697,14 +705,15 @@ void shortcut_init(int unjustify)
 		IFHELP(nano_lastline_msg, 0), 0, 0, VIEW, do_last_line);
 
 #ifndef NANO_SMALL
-    sc_init_one(&replace_list_2, KEY_UP, _("History"),
-		IFHELP(nano_editstr_msg, 0), NANO_UP_KEY, 0, VIEW, 0);
+    sc_init_one(&replace_list_2, NANO_UP_KEY, _("History"),
+		IFHELP(nano_editstr_msg, 0), 0, 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), 0, 0, VIEW, do_help);
+		IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
+		0, VIEW, do_help);
 
     sc_init_one(&goto_list, NANO_CANCEL_KEY, _("Cancel"),
 		IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
@@ -720,21 +729,22 @@ void shortcut_init(int unjustify)
 
     sc_init_one(&help_list, NANO_PREVPAGE_KEY, _("Prev Page"),
 		IFHELP(nano_prevpage_msg, 0), NANO_PREVPAGE_FKEY,
-		KEY_PPAGE, VIEW, do_page_up);
+		0, VIEW, do_page_up);
 
     sc_init_one(&help_list, NANO_NEXTPAGE_KEY, _("Next Page"),
-		IFHELP(nano_nextpage_msg, 0),
-		NANO_NEXTPAGE_FKEY, KEY_NPAGE, VIEW, do_page_down);
+		IFHELP(nano_nextpage_msg, 0), NANO_NEXTPAGE_FKEY,
+		0, 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, 0), NANO_EXIT_FKEY,
+		0, VIEW, do_exit);
 #endif
 
     free_shortcutage(&writefile_list);
 
     sc_init_one(&writefile_list, NANO_HELP_KEY, _("Get Help"),
-		IFHELP(nano_help_msg, 0), 0, 0, VIEW, do_help);
+		IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
+		0, VIEW, do_help);
 
 #ifndef DISABLE_BROWSER
     /* Translators: try to keep this string under 16 characters long */
@@ -772,7 +782,8 @@ void shortcut_init(int unjustify)
     free_shortcutage(&insertfile_list);
 
     sc_init_one(&insertfile_list, NANO_HELP_KEY, _("Get Help"),
-		IFHELP(nano_help_msg, 0), 0, 0, VIEW, do_help);
+		IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
+		0, VIEW, do_help);
 
     sc_init_one(&insertfile_list, NANO_CANCEL_KEY, _("Cancel"),
 		IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
@@ -781,13 +792,15 @@ void shortcut_init(int unjustify)
     sc_init_one(&insertfile_list, NANO_TOFILES_KEY, _("To Files"),
 		IFHELP(nano_tofiles_msg, 0), 0, 0, 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);
+
 #ifdef ENABLE_MULTIBUFFER
     /* Translators: try to keep this string under 22 characters long */
-    sc_init_one(&insertfile_list, TOGGLE_LOAD_KEY, _("New Buffer"),
+    sc_init_one(&insertfile_list, TOGGLE_MULTIBUFFER_KEY, _("New Buffer"),
 		IFHELP(nano_multibuffer_msg, 0), 0, 0, NOVIEW, 0);
 #endif
 #endif
@@ -796,7 +809,8 @@ void shortcut_init(int unjustify)
     free_shortcutage(&spell_list);
 
     sc_init_one(&spell_list, NANO_HELP_KEY, _("Get Help"),
-		IFHELP(nano_help_msg, 0), 0, 0, VIEW, do_help);
+		IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
+		0, VIEW, do_help);
 
     sc_init_one(&spell_list, NANO_CANCEL_KEY, _("Cancel"),
 		IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
@@ -806,7 +820,8 @@ void shortcut_init(int unjustify)
     free_shortcutage(&extcmd_list);
 
     sc_init_one(&extcmd_list, NANO_HELP_KEY, _("Get Help"),
-		IFHELP(nano_help_msg, 0), 0, 0, VIEW, do_help);
+		IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
+		0, VIEW, do_help);
 
     sc_init_one(&extcmd_list, NANO_CANCEL_KEY, _("Cancel"),
 		IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
@@ -816,18 +831,19 @@ void shortcut_init(int unjustify)
     free_shortcutage(&browser_list);
 
     sc_init_one(&browser_list, NANO_HELP_KEY, _("Get Help"),
-		IFHELP(nano_help_msg, 0), 0, 0, VIEW, do_help);
+		IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
+		0, VIEW, do_help);
 
     sc_init_one(&browser_list, NANO_CANCEL_KEY, _("Cancel"),
-		IFHELP(nano_cancel_msg, 0), NANO_EXIT_FKEY, 0, VIEW, 0);
+		IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
 
     sc_init_one(&browser_list, NANO_PREVPAGE_KEY, _("Prev Page"),
 		IFHELP(nano_prevpage_msg, 0), NANO_PREVPAGE_FKEY,
-		KEY_PPAGE, VIEW, 0);
+		0, VIEW, 0);
 
     sc_init_one(&browser_list, NANO_NEXTPAGE_KEY, _("Next Page"),
 		IFHELP(nano_nextpage_msg, 0), NANO_NEXTPAGE_FKEY,
-		KEY_NPAGE, VIEW, 0);
+		0, VIEW, 0);
 
     /* Translators: try to keep this string under 22 characters long */
     sc_init_one(&browser_list, NANO_GOTO_KEY, _("Go To Dir"),
@@ -837,7 +853,8 @@ void shortcut_init(int unjustify)
     free_shortcutage(&gotodir_list);
 
     sc_init_one(&gotodir_list, NANO_HELP_KEY, _("Get Help"),
-		IFHELP(nano_help_msg, 0), 0, 0, VIEW, do_help);
+		IFHELP(nano_help_msg, 0), NANO_HELP_FKEY,
+		0, VIEW, do_help);
 
     sc_init_one(&gotodir_list, NANO_CANCEL_KEY, _("Cancel"),
 		IFHELP(nano_cancel_msg, 0), 0, 0, VIEW, 0);
diff --git a/src/nano.c b/src/nano.c
index d44ed93179a61280b097d69667471064737f819c..3457aa4734f0d7d7837472dfd42e98d15b799615 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -406,40 +406,44 @@ void help_init(void)
 	/* true if the character in s->altval is shown in first column */
 	int meta_shortcut = 0;
 
-	if (s->val > 0 && s->val < 32)
-	    ptr += sprintf(ptr, "^%c", s->val + 64);
 #ifndef NANO_SMALL
-	else if (s->val == NANO_CONTROL_SPACE)
-	    ptr += sprintf(ptr, "^%.6s", _("Space"));
+	if (s->val == NANO_UP_KEY && s->misc == NANO_DOWN_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"));
+	    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) {
 	    meta_shortcut = 1;
 	    ptr += sprintf(ptr, "M-%.5s", _("Space"));
-	} else if (s->val == KEY_UP)
-	    ptr += sprintf(ptr, "%.2s", _("Up"));
+	}
 #endif
-	else if (s->altval > 0) {
+	else if (s->val > 0) {
 	    meta_shortcut = 1;
-	    ptr += sprintf(ptr, "M-%c", s->altval -
-			(('A' <= s->altval && s->altval <= 'Z') ||
-			'a' <= s->altval ? 32 : 0));
-	}
-	/* Hack */
-	else if (s->val >= 'a') {
+	    ptr += sprintf(ptr, "M-%c", toupper(s->val));
+	} else if (s->altval > 0) {
 	    meta_shortcut = 1;
-	    ptr += sprintf(ptr, "M-%c", s->val - 32);
+	    ptr += sprintf(ptr, "M-%c", toupper(s->altval));
 	}
 
 	*(ptr++) = '\t';
 
-	if (s->misc1 > KEY_F0 && s->misc1 <= KEY_F(64))
-	    ptr += sprintf(ptr, "(F%d)", s->misc1 - KEY_F0);
+	if (s->func_key > KEY_F0 && s->func_key <= KEY_F(64))
+	    ptr += sprintf(ptr, "(F%d)", s->func_key - KEY_F0);
 
 	*(ptr++) = '\t';
 
 	if (!meta_shortcut && s->altval > 0)
-	    ptr += sprintf(ptr, "(M-%c)", s->altval -
-		(('A' <= s->altval && s->altval <= 'Z') || 'a' <= s->altval
-			? 32 : 0));
+	    ptr += sprintf(ptr, "(M-%c)", toupper(s->altval));
+	else if (meta_shortcut && s->misc > 0)
+	    ptr += sprintf(ptr, "(M-%c)", toupper(s->misc));
 
 	*(ptr++) = '\t';
 
@@ -452,7 +456,7 @@ void help_init(void)
     if (currshortcut == main_list)
 	for (t = toggles; t != NULL; t = t->next) {
 	    assert(t->desc != NULL);
-	    ptr += sprintf(ptr, "M-%c\t\t\t%s %s\n", t->val - 32, t->desc,
+	    ptr += sprintf(ptr, "M-%c\t\t\t%s %s\n", toupper(t->val), t->desc,
 				_("enable/disable"));
 	}
 #endif /* !NANO_SMALL */
@@ -774,7 +778,7 @@ void nano_disabled_msg(void)
 #endif
 
 #ifndef NANO_SMALL
-static int pid;		/* This is the PID of the newly forked process 
+static int pid;		/* This is the PID of the newly forked process
 			 * below.  It must be global since the signal
 			 * handler needs it. */
 RETSIGTYPE cancel_fork(int signal)
@@ -890,87 +894,56 @@ int open_pipe(const char *command)
 #ifndef DISABLE_MOUSE
 void do_mouse(void)
 {
-    MEVENT mevent;
-    int currslen;
-    const shortcut *s = currshortcut;
+    int mouse_x, mouse_y;
 
-    if (getmouse(&mevent) == ERR)
-	return;
+    if (get_mouseinput(&mouse_x, &mouse_y) == 0) {
 
-    /* If mouse not in edit or bottom window, return */
-    if (wenclose(edit, mevent.y, mevent.x) && currshortcut == main_list) {
-	int sameline;
-	    /* Did they click on the line with the cursor?  If they
-	       clicked on the cursor, we set the mark. */
-	size_t xcur;
-	    /* The character they clicked on. */
+	/* Click in the edit window to move the cursor, but only when
+	   we're not in a subfunction. */
+	if (wenclose(edit, mouse_y, mouse_x) && currshortcut == main_list) {
+	    int sameline;
+		/* Did they click on the line with the cursor?  If they
+		   clicked on the cursor, we set the mark. */
+	    size_t xcur;
+		/* The character they clicked on. */
 
-	/* Subtract out size of topwin.  Perhaps we need a constant
-	 * somewhere? */
-	mevent.y -= 2;
+	    /* Subtract out size of topwin.  Perhaps we need a constant
+	       somewhere? */
+	    mouse_y -= 2;
 
-	sameline = mevent.y == current_y;
+	    sameline = (mouse_y == current_y);
 
-	/* Move to where the click occurred. */
-	for (; current_y < mevent.y && current->next != NULL; current_y++)
-	    current = current->next;
-	for (; current_y > mevent.y && current->prev != NULL; current_y--)
-	    current = current->prev;
+	    /* Move to where the click occurred. */
+	    for (; current_y < mouse_y && current->next != NULL; current_y++)
+		current = current->next;
+	    for (; current_y > mouse_y && current->prev != NULL; current_y--)
+		current = current->prev;
 
-	xcur = actual_x(current->data, get_page_start(xplustabs()) + mevent.x);
+	    xcur = actual_x(current->data, get_page_start(xplustabs()) +
+		mouse_x);
 
-	/* Selecting where the cursor is toggles the mark.  As does
-	   selecting beyond the line length with the cursor at the end of
-	   the line. */
-	if (sameline && xcur == current_x) {
-	    if (ISSET(VIEW_MODE)) {
-		print_view_warning();
-		return;
+	    /* Selecting where the cursor is toggles the mark.  As does
+	       selecting beyond the line length with the cursor at the
+	       end of the line. */
+	    if (sameline && xcur == current_x) {
+		if (ISSET(VIEW_MODE)) {
+		    print_view_warning();
+		    return;
+		}
+		do_mark();
 	    }
-	    do_mark();
-	}
-
-	current_x = xcur;
-	placewewant = xplustabs();
-	edit_refresh();
-    } else if (wenclose(bottomwin, mevent.y, mevent.x) && !ISSET(NO_HELP)) {
-	int i, k;
-
-	if (currshortcut == main_list)
-	    currslen = MAIN_VISIBLE;
-	else
-	    currslen = length_of_list(currshortcut);
-
-	if (currslen < 2)
-	    k = COLS / 6;
-	else 
-	    k = COLS / ((currslen + (currslen %2)) / 2);
-
-	/* Determine what shortcut list was clicked */
-	mevent.y -= (editwinrows + 3);
 
-	if (mevent.y < 0) /* They clicked on the statusbar */
-	    return;
-
-	/* Don't select stuff beyond list length */
-	if (mevent.x / k >= currslen)	
-	    return;
-
-	for (i = 0; i < (mevent.x / k) * 2 + mevent.y; i++)
-	    s = s->next;
-
-	/* And ungetch that value */
-	ungetch(s->val);
-
-	/* And if it's an alt-key sequence, we should probably send alt
-	   too ;-) */
-	if (s->val >= 'a' && s->val <= 'z')
-	   ungetch(27);
+	    current_x = xcur;
+	    placewewant = xplustabs();
+	    edit_refresh();
+	}
     }
+    /* FIXME: If we clicked on a location in the statusbar, the cursor
+       should move to the location we clicked on. */
 }
 #endif
 
-/* The user typed a printable character; add it to the edit buffer. */
+/* The user typed a character; add it to the edit buffer. */
 void do_char(char ch)
 {
     size_t current_len = strlen(current->data);
@@ -980,25 +953,33 @@ void do_char(char ch)
 	 * update_line()? */
 #endif
 
-    /* magic-line: when a character is inserted on the current magic line,
-     * it means we need a new one! */
-    if (filebot == current && current->data[0] == '\0') {
+    if (ch == '\0')		/* Null to newline, if needed. */
+	ch = '\n';
+    else if (ch == '\n') {	/* Newline to Enter, if needed. */
+	do_enter();
+	return;
+    }
+
+    assert(current != NULL && current->data != NULL);
+
+    /* When a character is inserted on the current magicline, it means
+     * we need a new one! */
+    if (filebot == current) {
 	new_magicline();
 	fix_editbot();
     }
 
-    /* more dangerousness fun =) */
+    /* More dangerousness fun =) */
     current->data = charealloc(current->data, current_len + 2);
     assert(current_x <= current_len);
-    charmove(&current->data[current_x + 1],
-	    &current->data[current_x],
-	    current_len - current_x + 1);
+    charmove(&current->data[current_x + 1], &current->data[current_x],
+	current_len - current_x + 1);
     current->data[current_x] = ch;
     totsize++;
     set_modified();
 
 #ifndef NANO_SMALL
-    /* note that current_x has not yet been incremented */
+    /* Note that current_x has not yet been incremented. */
     if (current == mark_beginbuf && current_x < mark_beginx)
 	mark_beginx++;
 #endif
@@ -1020,6 +1001,48 @@ void do_char(char ch)
 #endif
 }
 
+int do_verbatim_input(void)
+{
+    char *verbatim_kbinput;	/* Used to hold verbatim input */
+    int verbatim_len;		/* Length of verbatim input */
+    int old_preserve = ISSET(PRESERVE), old_suspend = ISSET(SUSPEND);
+    int i;
+
+    /* Turn off Ctrl-Q (XON), Ctrl-S (XOFF), and Ctrl-Z (suspend) if
+     * they're on, so that we can use them to insert ^Q, ^S, and ^Z
+     * verbatim. */
+    if (old_preserve)
+	UNSET(PRESERVE);
+    if (old_suspend)
+	UNSET(SUSPEND);
+    if (old_preserve || old_suspend)
+	signal_init();
+
+    statusbar(_("Verbatim input"));
+    verbatim_kbinput = get_verbatim_kbinput(edit, &verbatim_len);
+
+    /* Turn on DISABLE_CURPOS while inserting character(s) and turn it
+     * off afterwards, so that if constant cursor position display is
+     * on, it will be updated properly. */
+    SET(DISABLE_CURPOS);
+    for (i = 0; i < verbatim_len; i++)
+	do_char(verbatim_kbinput[i]);
+    UNSET(DISABLE_CURPOS);
+
+    free(verbatim_kbinput);
+
+    /* Turn Ctrl-Q, Ctrl-S, and Ctrl-Z back on if they were on
+     * before. */
+    if (old_preserve)
+	SET(PRESERVE);
+    if (old_suspend)
+	SET(SUSPEND);
+    if (old_preserve || old_suspend)
+	signal_init();
+
+    return 1;
+}
+
 int do_backspace(void)
 {
     if (current != fileage || current_x > 0) {
@@ -2876,7 +2899,7 @@ RETSIGTYPE do_cont(int signal)
     doupdate();
 
     /* The Hurd seems to need this, otherwise a ^Y after a ^Z will
-	start suspending again. */
+       start suspending again. */
     signal_init();
 
 #ifndef NANO_SMALL
@@ -3497,55 +3520,37 @@ int main(int argc, char *argv[])
 	fprintf(stderr, "AHA!  %c (%d)\n", kbinput, kbinput);
 #endif
 	if (meta == 1) {
-	    switch (kbinput) {
-#ifdef ENABLE_MULTIBUFFER
-	    case NANO_OPENPREV_KEY:
-	    case NANO_OPENPREV_ALTKEY:
-		open_prevfile_void();
-		keyhandled = 1;
-		break;
-	    case NANO_OPENNEXT_KEY:
-	    case NANO_OPENNEXT_ALTKEY:
-		open_nextfile_void();
-		keyhandled = 1;
-		break;
-#endif
-	    default:
-		/* Check for the altkey defs.... */
-		for (s = main_list; s != NULL; s = s->next)
-		    if (kbinput == s->altval || (kbinput >= 'A' &&
-			    kbinput <= 'Z' && kbinput == s->altval - 32)) {
-			if (ISSET(VIEW_MODE) && !s->viewok)
-			    print_view_warning();
-			else {
-			    if (s->func != do_cut_text)
-				UNSET(KEEP_CUTBUFFER);
-			    s->func();
-			}
-			keyhandled = 1;
-			break;
+	    /* Check for the altkey and misc defs... */
+	    for (s = main_list; s != NULL; s = s->next)
+		if ((s->altval > 0 && kbinput == s->altval) ||
+		    (s->misc > 0 && kbinput == s->misc)) {
+		    if (ISSET(VIEW_MODE) && !s->viewok)
+			print_view_warning();
+		    else {
+			if (s->func != do_cut_text)
+			    UNSET(KEEP_CUTBUFFER);
+			s->func();
 		    }
+		    keyhandled = 1;
+		}
 #ifndef NANO_SMALL
 		if (!keyhandled)
 		    /* And for toggle switches */
 		    for (t = toggles; t != NULL; t = t->next)
-			if (kbinput == t->val || (t->val >= 'a' &&
-				t->val <= 'z' && kbinput == t->val - 32)) {
+			if (kbinput == t->val) {
 			    UNSET(KEEP_CUTBUFFER);
 			    do_toggle(t);
 			    keyhandled = 1;
-			    break;
 		        }
 #endif
 #ifdef DEBUG
-		fprintf(stderr, "I got Alt-%c! (%d)\n", kbinput,
-			kbinput);
+	    fprintf(stderr, "I got Alt-%c! (%d)\n", kbinput,
+		kbinput);
 #endif
-	    }
 	}
 
 	/* Look through the main shortcut list to see if we've hit a
-	   shortcut key */
+	   shortcut key or function key */
 
 	if (!keyhandled)
 #if !defined(DISABLE_BROWSER) || !defined (DISABLE_HELP) || !defined(DISABLE_MOUSE)
@@ -3553,9 +3558,8 @@ int main(int argc, char *argv[])
 #else
 	    for (s = main_list; s != NULL && !keyhandled; s = s->next) {
 #endif
-		if (kbinput == s->val ||
-		    (s->misc1 && kbinput == s->misc1) ||
-		    (s->misc2 && kbinput == s->misc2)) {
+		if ((s->val >= 0 && kbinput == s->val) ||
+		    (s->func_key > 0 && kbinput == s->func_key)) {
 		    if (ISSET(VIEW_MODE) && !s->viewok)
 			print_view_warning();
 		    else {
@@ -3564,10 +3568,8 @@ int main(int argc, char *argv[])
 			s->func();
 		    }
 		    keyhandled = 1;
-		    /* Rarely, the value of s can change after
-		       s->func(), leading to problems; get around this
-		       by breaking out explicitly once we successfully
-		       handle a shortcut */
+		    /* Break out explicitly once we successfully handle
+		       a shortcut */
 		    break;
 		}
 	    }
@@ -3607,6 +3609,7 @@ int main(int argc, char *argv[])
 	    				 * have been handled before we
 	    				 * got here */
 	    case NANO_CONTROL_5:	/* Ctrl-] */
+	    case NANO_CONTROL_8:	/* Ctrl-? (Delete) */
 		break;
 	    default:
 #ifdef DEBUG
diff --git a/src/nano.h b/src/nano.h
index 27a367ceb4be433ab31b3becf8c293499835f3ba..eaf1b8f310d874e0edf66c3f9511d201a1904e9c 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -112,12 +112,14 @@
 #define KEY_SUSPEND -5
 #endif
 
-/* Snatch these out of the ncurses defs, so we can use them in search
-   history regardless of whether we're using ncurses or not */
-#if !defined(KEY_UP) || !defined(KEY_DOWN)
-#define KEY_UP   0403
-#define KEY_DOWN 0402
-#endif /* !KEY_UP || !KEY_DOWN */
+/* Non-ncurses may not support KEY_UP and KEY_DOWN */
+#ifndef KEY_UP
+#define KEY_UP -6
+#endif
+
+#ifndef KEY_DOWN
+#define KEY_DOWN -7
+#endif
 
 #define VERMSG "GNU nano " VERSION
 
@@ -166,10 +168,11 @@ typedef struct openfilestruct {
 #endif
 
 typedef struct shortcut {
-   int val;		/* Actual sequence that generates the keystroke */
-   int altval;		/* Alt key # for this function, or 0 for none */
-   int misc1;		/* Other int functions we want bound */
-   int misc2;
+   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" */
@@ -339,7 +342,7 @@ typedef struct historyheadtype {
 #define NANO_ALT_COMMA ','
 #define NANO_ALT_LCARAT '<'
 #define NANO_ALT_RCARAT '>'
-#define NANO_ALT_BRACKET ']'
+#define NANO_ALT_RBRACKET ']'
 #define NANO_ALT_SPACE ' '
 
 /* Some semi-changeable keybindings; don't play with unless you're sure
@@ -403,12 +406,13 @@ typedef struct historyheadtype {
 #define NANO_OPENNEXT_KEY	NANO_ALT_RCARAT
 #define NANO_OPENPREV_ALTKEY	NANO_ALT_COMMA
 #define NANO_OPENNEXT_ALTKEY	NANO_ALT_PERIOD
-#define NANO_BRACKET_KEY	NANO_ALT_BRACKET
+#define NANO_BRACKET_KEY	NANO_ALT_RBRACKET
 #define NANO_EXTCMD_KEY		NANO_CONTROL_X
 #define NANO_NEXTWORD_KEY	NANO_CONTROL_SPACE
 #define NANO_PREVWORD_KEY	NANO_ALT_SPACE
 #define NANO_PARABEGIN_KEY	NANO_CONTROL_W
 #define NANO_PARAEND_KEY	NANO_CONTROL_O
+#define NANO_VERBATIM_KEY	NANO_ALT_V
 
 #ifndef NANO_SMALL
 /* Toggles do not exist with NANO_SMALL. */
@@ -422,7 +426,7 @@ typedef struct historyheadtype {
 #define TOGGLE_WRAP_KEY		NANO_ALT_L
 #define TOGGLE_BACKWARDS_KEY	NANO_ALT_B
 #define TOGGLE_CASE_KEY		NANO_ALT_C
-#define TOGGLE_LOAD_KEY		NANO_ALT_F
+#define TOGGLE_MULTIBUFFER_KEY	NANO_ALT_F
 #define TOGGLE_DOS_KEY		NANO_ALT_D
 #define TOGGLE_MAC_KEY		NANO_ALT_O
 #define TOGGLE_SMOOTH_KEY	NANO_ALT_S
diff --git a/src/proto.h b/src/proto.h
index 417aef307c119b5c4ca34947c178070dc6ca5d7a..ddf08cc844836350ea7743a6b89b7a36423cc6d5 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -207,7 +207,7 @@ void sc_init_one(shortcut **shortcutage, int key, const char *desc,
 #ifndef DISABLE_HELP
 	const char *help,
 #endif
-	int alt, int misc1, int misc2, int view, int (*func) (void));
+	int alt, int func_key, int misc, int view, int (*func) (void));
 #ifndef NANO_SMALL
 void toggle_init_one(int val, const char *desc, int flag);
 void toggle_init(void);
@@ -271,6 +271,7 @@ int open_pipe(const char *command);
 void do_mouse(void);
 #endif
 void do_char(char ch);
+int do_verbatim_input(void);
 int do_backspace(void);
 int do_delete(void);
 int do_tab(void);
@@ -443,6 +444,7 @@ 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 do_first_line(void);
 int do_last_line(void);
 int xpt(const filestruct *fileptr, int index);
diff --git a/src/winio.c b/src/winio.c
index 844ce7c931cb4c9d94ac5e1fdb676e76b610d518..3428c0ba88fd2fb397a78616c3d9b0532c8c242d 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -317,6 +317,86 @@ int get_skip_tilde_kbinput(WINDOW *win, int errval, int retval)
     }
 }
 
+#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)
+{
+    MEVENT mevent;
+
+    *mouse_x = -1;
+    *mouse_y = -1;
+
+    /* First, get the actual mouse event. */
+    if (getmouse(&mevent) == ERR)
+	return 0;
+
+    /* Save the screen coordinates where the mouse event took place. */
+    *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 (!ISSET(NO_HELP) && wenclose(bottomwin, *mouse_y, *mouse_x)) {
+	int i, j;
+	int currslen;
+	    /* The number of shortcuts in the current shortcut list. */
+	const shortcut *s = currshortcut;
+	    /* The actual shortcut we clicked on, starting at the first
+	     * one in the current shortcut list. */
+
+	/* Get the shortcut lists' length. */
+	if (currshortcut == main_list)
+	    currslen = MAIN_VISIBLE;
+	else
+	    currslen = length_of_list(currshortcut);
+
+	/* Calculate the width of each shortcut in the list (it's the
+	 * same for all of them). */
+	if (currslen < 2)
+	    i = COLS / 6;
+	else
+	    i = COLS / ((currslen / 2) + (currslen % 2));
+
+	/* Calculate the y-coordinates relative to the beginning of
+	 * bottomwin, i.e, the bottom three lines of the screen. */
+	j = *mouse_y - (editwinrows + 3);
+
+	/* If we're on the statusbar, beyond the end of the shortcut
+	 * list, or beyond the end of a shortcut on the right side of
+	 * the screen, don't do anything. */
+	if (j < 0 || (*mouse_x / i) >= currslen)
+	    return 0;
+	j = (*mouse_x / i) * 2 + j;
+	if (j >= currslen)
+	    return 0;
+
+	/* Go through the shortcut list to determine which shortcut was
+	 * clicked. */
+	for (; j > 0; j--)
+	    s = s->next;
+
+	/* And ungetch() the equivalent keystroke. */
+	ungetch(s->val);
+
+	/* If it's not a control character, assume it's a Meta key
+	 * sequence, in which case we need to ungetch() Escape too. */
+	if (!is_cntrl_char(s->val))
+	   ungetch(NANO_CONTROL_3);
+
+	return 1;
+    }
+    return 0;
+}
+#endif
+
 int do_first_line(void)
 {
     current = fileage;
@@ -605,7 +685,7 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
 	    fprintf(stderr, "Aha! \'%c\' (%d)\n", kbinput, kbinput);
 #endif
 
-	    if (kbinput == t->val && (kbinput < 32 || kbinput == 127)) {
+	    if (kbinput == t->val && is_cntrl_char(kbinput)) {
 
 #ifndef DISABLE_HELP
 		/* Have to do this here, it would be too late to do it
@@ -615,6 +695,11 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
 		    break;
 		}
 #endif
+#ifndef NANO_SMALL
+		/* Have to handle these here too, for the time being */
+		if (kbinput == NANO_UP_KEY || kbinput == NANO_DOWN_KEY)
+		    break;
+#endif
 
 		return t->val;
 	    }
@@ -787,7 +872,7 @@ 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 || kbinput == t->val - 32))
+		    if (meta == 1 && kbinput == t->val)
 			/* 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
@@ -795,7 +880,7 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
 			return t->val;
 		}
 
-	    if (kbinput < 32 || kbinput == 127)
+	    if (is_cntrl_char(kbinput))
 		break;
 	    answer = charealloc(answer, xend + 2);
 	    charmove(answer + x + 1, answer + x, xend - x + 1);
@@ -911,14 +996,14 @@ void bottombars(const shortcut *s)
 	    if (s->val == NANO_CONTROL_SPACE)
 		strcpy(keystr, "^ ");
 #ifndef NANO_SMALL
-	    else if (s->val == KEY_UP)
+	    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);
 		else
-		    sprintf(keystr, "M-%c", s->val - 32);
+		    sprintf(keystr, "M-%c", toupper(s->val));
 	    } else if (s->altval > 0)
 		sprintf(keystr, "M-%c", s->altval);