diff --git a/src/global.c b/src/global.c
index 363c034c98ed53c8eebb9a854539ae4db50c5b54..9a8c8f55188133bec985514ded9cb8029842ed9a 100644
--- a/src/global.c
+++ b/src/global.c
@@ -77,6 +77,7 @@ int controlleft, controlright, controlup, controldown, controlhome, controlend;
 #ifndef NANO_TINY
 int shiftcontrolleft, shiftcontrolright, shiftcontrolup, shiftcontroldown;
 int shiftcontrolhome, shiftcontrolend;
+int altleft, altright, altup, altdown;
 int shiftaltleft, shiftaltright, shiftaltup, shiftaltdown;
 #endif
 
@@ -420,28 +421,45 @@ functionptrtype func_from_key(int *kbinput)
 void assign_keyinfo(sc *s, const char *keystring, const int keycode)
 {
     s->keystr = keystring;
-    s->meta = (keystring[0] == 'M');
+    s->meta = (keystring[0] == 'M' && keystring[2] != '\xE2');
 
     assert(strlen(keystring) > 1 && (!s->meta || strlen(keystring) > 2));
 
     if (keycode)
 	s->keycode = keycode;
-    else if (keystring[0] == '^') {
+    else
+	s->keycode = keycode_from_string(keystring);
+}
+
+/* Parse the given keystring and return the corresponding keycode,
+ * or return -1 when the string is invalid. */
+int keycode_from_string(const char *keystring)
+{
+    if (keystring[0] == '^') {
 	if (strcasecmp(keystring, "^Space") == 0)
-	    s->keycode = 0;
+	    return 0;
+	if (strlen(keystring) == 2)
+	    return keystring[1] - 64;
 	else
-	    s->keycode = keystring[1] - 64;
-    } else if (s->meta) {
+	    return -1;
+    } else if (keystring[0] == 'M') {
 	if (strcasecmp(keystring, "M-Space") == 0)
-	    s->keycode = (int)' ';
+	    return (int)' ';
+	if (keystring[1] == '-')
+	    return tolower((unsigned char)keystring[2]);
 	else
-	    s->keycode = tolower((unsigned char)keystring[2]);
-    } else if (keystring[0] == 'F')
-	s->keycode = KEY_F0 + atoi(&keystring[1]);
-    else if (!strcasecmp(keystring, "Ins"))
-	s->keycode = KEY_IC;
+	    return -1;
+    } else if (keystring[0] == 'F') {
+	int fn = atoi(&keystring[1]);
+	if ((fn < 0) || (fn > 63))
+	    return -1;
+	return KEY_F0 + fn;
+    } else if (!strcasecmp(keystring, "Ins"))
+	return KEY_IC;
     else if (!strcasecmp(keystring, "Del"))
-	s->keycode = KEY_DC;
+	return KEY_DC;
+    else
+	return -1;
 }
 
 #ifdef DEBUG
@@ -1121,6 +1139,10 @@ void shortcut_init(void)
 	add_to_sclist(MMOST, "\xE2\x86\x92", KEY_RIGHT, do_right, 0);
 	add_to_sclist(MSOME, "^\xE2\x86\x90", CONTROL_LEFT, do_prev_word_void, 0);
 	add_to_sclist(MSOME, "^\xE2\x86\x92", CONTROL_RIGHT, do_next_word_void, 0);
+#ifdef ENABLE_MULTIBUFFER
+	add_to_sclist(MMAIN, "M-\xE2\x86\x90", ALT_LEFT, switch_to_prev_buffer_void, 0);
+	add_to_sclist(MMAIN, "M-\xE2\x86\x92", ALT_RIGHT, switch_to_next_buffer_void, 0);
+#endif
     } else
 #endif
     {
diff --git a/src/help.c b/src/help.c
index 12b3efa5b40e431ce1c5c40af2fdd2cd6238b5e7..46aff4e70c2f78d4a5ce258eec150bbb0315f592 100644
--- a/src/help.c
+++ b/src/help.c
@@ -510,7 +510,7 @@ void help_init(void)
 		if (scsfound == 1) {
 		    sprintf(ptr, "%s               ", s->keystr);
 		    /* Unicode arrows take three bytes instead of one. */
-		    if (s->keystr[0] == '\xE2' || s->keystr[1] == '\xE2')
+		    if (strstr(s->keystr, "\xE2") != NULL)
 			ptr += 8;
 		    else
 			ptr += 6;
diff --git a/src/nano.c b/src/nano.c
index 7307925f89b9dd30d40183f1307ef01b15aa37b7..befd2a8190d65dd6344d5b7c7c466fcb7c877d79 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -2525,6 +2525,11 @@ int main(int argc, char **argv)
     /* Ask for the codes for Shift+Control+Home/End. */
     shiftcontrolhome = get_keycode("kHOM6", SHIFT_CONTROL_HOME);
     shiftcontrolend = get_keycode("kEND6", SHIFT_CONTROL_END);
+    /* Ask for the codes for Alt+Left/Right/Up/Down. */
+    altleft = get_keycode("kLFT3", ALT_LEFT);
+    altright = get_keycode("kRIT3", ALT_RIGHT);
+    altup = get_keycode("kUP3", ALT_UP);
+    altdown = get_keycode("kDN3", ALT_DOWN);
     /* Ask for the codes for Shift+Alt+Left/Right/Up/Down. */
     shiftaltleft = get_keycode("kLFT4", SHIFT_ALT_LEFT);
     shiftaltright = get_keycode("kRIT4", SHIFT_ALT_RIGHT);
diff --git a/src/nano.h b/src/nano.h
index 7c52da8bf3d2ce0ecbcd7b612b433d8885ffdd84..58b66619ec0cdc9d7ded67718fb0233899412553 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -568,6 +568,10 @@ enum
 #define SHIFT_CONTROL_DOWN 0x408
 #define SHIFT_CONTROL_HOME 0x413
 #define SHIFT_CONTROL_END 0x414
+#define ALT_LEFT 0x415
+#define ALT_RIGHT 0x416
+#define ALT_UP 0x417
+#define ALT_DOWN 0x418
 #define SHIFT_ALT_LEFT 0x409
 #define SHIFT_ALT_RIGHT 0x40a
 #define SHIFT_ALT_UP 0x40b
diff --git a/src/proto.h b/src/proto.h
index 4adf84c19ef5cdf3b38bae04f1753eed94c7f06d..4f1c7032bd9dd2fae635d1553c1030d65f6a899d 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -71,6 +71,10 @@ extern int shiftcontrolup;
 extern int shiftcontroldown;
 extern int shiftcontrolhome;
 extern int shiftcontrolend;
+extern int altleft;
+extern int altright;
+extern int altup;
+extern int altdown;
 extern int shiftaltleft;
 extern int shiftaltright;
 extern int shiftaltup;
@@ -327,6 +331,7 @@ size_t length_of_list(int menu);
 const sc *first_sc_for(int menu, void (*func)(void));
 int the_code_for(void (*func)(void), int defaultval);
 functionptrtype func_from_key(int *kbinput);
+int keycode_from_string(const char *keystring);
 void assign_keyinfo(sc *s, const char *keystring, const int keycode);
 void print_sclist(void);
 void shortcut_init(void);
diff --git a/src/rcfile.c b/src/rcfile.c
index db9f6fba002ade529e8719cb76aa3727a79cf554..c4611bfde8d8542a2e297dd6075da3d2dbe5d846 100644
--- a/src/rcfile.c
+++ b/src/rcfile.c
@@ -410,12 +410,7 @@ void parse_binding(char *ptr, bool dobind)
     else if (keycopy[0] != '^' && keycopy[0] != 'M' && keycopy[0] != 'F') {
 	rcfile_error(N_("Key name must begin with \"^\", \"M\", or \"F\""));
 	goto free_copy;
-    } else if ((keycopy[0] == 'M' && keycopy[1] != '-') ||
-		(keycopy[0] == '^' && ((keycopy[1] < 'A' || keycopy[1] > 'z') ||
-		keycopy[1] == '[' || keycopy[1] == '`' ||
-		(strlen(keycopy) > 2 && strcmp(keycopy, "^Space") != 0))) ||
-		(strlen(keycopy) > 3 && strcmp(keycopy, "^Space") != 0 &&
-		strcmp(keycopy, "M-Space") != 0)) {
+    } else if (keycode_from_string(keycopy) < 0) {
 	rcfile_error(N_("Key name %s is invalid"), keycopy);
 	goto free_copy;
     }
diff --git a/src/winio.c b/src/winio.c
index 650f93b55dcd11a6d263fc55448b9c4e4877ced5..723868b0a9b424ef5fcb1472f58ce1c07140680f 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -523,6 +523,10 @@ int parse_kbinput(WINDOW *win)
     } else if (retval == shiftcontrolend) {
 	shift_held = TRUE;
 	return CONTROL_END;
+    } else if (retval == altleft) {
+	return ALT_LEFT;
+    } else if (retval == altright) {
+	return ALT_RIGHT;
     } else if (retval == shiftaltleft) {
 	shift_held = TRUE;
 	return KEY_HOME;
@@ -954,6 +958,18 @@ int convert_sequence(const int *seq, size_t seq_len)
 		}
 		break;
 #ifndef NANO_TINY
+	    case '3':
+		switch (seq[4]) {
+		    case 'A': /* Esc [ 1 ; 3 A == Alt-Up on xterm. */
+			return ALT_UP;
+		    case 'B': /* Esc [ 1 ; 3 B == Alt-Down on xterm. */
+			return ALT_DOWN;
+		    case 'C': /* Esc [ 1 ; 3 C == Alt-Right on xterm. */
+			return ALT_RIGHT;
+		    case 'D': /* Esc [ 1 ; 3 D == Alt-Left on xterm. */
+			return ALT_LEFT;
+		}
+		break;
 	    case '4':
 		/* When the arrow keys are held together with Shift+Meta,
 		 * act as if they are Home/End/PgUp/PgDown with Shift. */