From 22ea2185c1e6bbd5dda9099980e10e7530ce137f Mon Sep 17 00:00:00 2001
From: David Lawrence Ramsey <pooka109@gmail.com>
Date: Mon, 5 Nov 2018 18:08:33 -0600
Subject: [PATCH] input: recognize escape sequences for Shift-Delete

Also, interpret Shift-Delete as Backspace when getting such sequences.

This fixes http://savannah.gnu.org/bugs/?54948.
---
 src/global.c |  3 +++
 src/nano.c   |  1 +
 src/nano.h   |  1 +
 src/proto.h  |  1 +
 src/winio.c  | 20 ++++++++++++++++----
 5 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/global.c b/src/global.c
index c523818c..926cf875 100644
--- a/src/global.c
+++ b/src/global.c
@@ -70,6 +70,7 @@ int didfind = 0;
 
 int controlleft, controlright, controlup, controldown;
 int controlhome, controlend;
+int shiftdelete;
 #ifndef NANO_TINY
 int controldelete, controlshiftdelete;
 int shiftleft, shiftright, shiftup, shiftdown;
@@ -1093,6 +1094,7 @@ void shortcut_init(void)
 	add_to_sclist(MMOST, "Enter", KEY_ENTER, do_enter, 0);
 	add_to_sclist(MMOST, "^H", 0, do_backspace, 0);
 	add_to_sclist(MMOST, "Bsp", KEY_BACKSPACE, do_backspace, 0);
+	add_to_sclist(MMOST, "Sh-Del", SHIFT_DELETE, do_backspace, 0);
 	add_to_sclist(MMOST, "^D", 0, do_delete, 0);
 	add_to_sclist(MMOST, "Del", 0, do_delete, 0);
 	/* Make ASCII DEL do a delete when requested, otherwise a backspace. */
@@ -1128,6 +1130,7 @@ void shortcut_init(void)
 	add_to_sclist(MMAIN, "M-G", 0, do_gotolinecolumn_void, 0);
 	add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "^Y", 0, do_page_up, 0);
 	add_to_sclist(MHELP|MBROWSER, "Bsp", KEY_BACKSPACE, do_page_up, 0);
+	add_to_sclist(MHELP|MBROWSER, "Sh-Del", SHIFT_DELETE, do_page_up, 0);
 	add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "PgUp", KEY_PPAGE, do_page_up, 0);
 	add_to_sclist(MMAIN|MHELP|MBROWSER|MLINTER, "^V", 0, do_page_down, 0);
 	add_to_sclist(MHELP|MBROWSER, "Space", 0x20, do_page_down, 0);
diff --git a/src/nano.c b/src/nano.c
index ef43657b..b6faeb23 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -2575,6 +2575,7 @@ int main(int argc, char **argv)
 
 	controlhome = get_keycode("kHOM5", CONTROL_HOME);
 	controlend = get_keycode("kEND5", CONTROL_END);
+	shiftdelete = get_keycode("kDC", SHIFT_DELETE);
 #ifndef NANO_TINY
 	controldelete = get_keycode("kDC5", CONTROL_DELETE);
 	controlshiftdelete = get_keycode("kDC6", CONTROL_SHIFT_DELETE);
diff --git a/src/nano.h b/src/nano.h
index db726b6a..9dbcf6ce 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -607,6 +607,7 @@ enum
 #define SHIFT_END 0x456
 #define SHIFT_PAGEUP 0x457
 #define SHIFT_PAGEDOWN 0x458
+#define SHIFT_DELETE 0x459
 #define SHIFT_TAB 0x45F
 
 #ifdef USE_SLANG
diff --git a/src/proto.h b/src/proto.h
index b6c50e58..7fa88713 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -58,6 +58,7 @@ extern int didfind;
 extern int controlleft, controlright;
 extern int controlup, controldown;
 extern int controlhome, controlend;
+extern int shiftdelete;
 #ifndef NANO_TINY
 extern int controldelete, controlshiftdelete;
 extern int shiftleft, shiftright;
diff --git a/src/winio.c b/src/winio.c
index 6d18f39c..c9a8913d 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -533,6 +533,8 @@ int parse_kbinput(WINDOW *win)
 		return CONTROL_HOME;
 	else if (retval == controlend)
 		return CONTROL_END;
+	else if (retval == shiftdelete)
+		return SHIFT_DELETE;
 #ifndef NANO_TINY
 	else if (retval == controldelete)
 		return CONTROL_DELETE;
@@ -608,8 +610,10 @@ int parse_kbinput(WINDOW *win)
 				return SHIFT_TAB;
 			shift_held = TRUE;
 		}
-		/* Is Delete pressed together with either Ctrl+Shift or Meta? */
+		/* Is Delete pressed together with Shift, Ctrl+Shift, or Meta? */
 		if (retval == KEY_DC) {
+			if ((modifiers & 0x01) == 0x01)
+				return SHIFT_DELETE;
 			if ((modifiers & 0x05) == 0x05)
 				return CONTROL_SHIFT_DELETE;
 			if (modifiers == 0x08)
@@ -723,8 +727,8 @@ int parse_kbinput(WINDOW *win)
 		case KEY_C3:    /* PageDown (3) on keypad with NumLock off. */
 			return KEY_NPAGE;
 #ifdef KEY_SDC  /* Slang doesn't support KEY_SDC. */
-		case KEY_SDC:  /* Make a shifted <Del> key do a backspace. */
-			return KEY_BACKSPACE;
+		case KEY_SDC:
+			return SHIFT_DELETE;
 #endif
 #ifdef KEY_SIC  /* Slang doesn't support KEY_SIC. */
 		case KEY_SIC:
@@ -1107,9 +1111,12 @@ int convert_sequence(const int *seq, size_t length, int *consumed)
 							   * Linux console/xterm/Terminal. */
 						if (length > 2 && seq[2] == '~')
 							return KEY_DC;
-#ifndef NANO_TINY
 						if (length > 4 && seq[2] == ';' && seq[4] == '~') {
 							*consumed = 5;
+							if (seq[3] == '2')
+								/* Esc [ 3 ; 2 ~ == Shift-Delete on xterm/Terminal. */
+								return SHIFT_DELETE;
+#ifndef NANO_TINY
 							if (seq[3] == '3')
 								/* Esc [ 3 ; 3 ~ == Alt-Delete on xterm/rxvt/Eterm/Terminal. */
 								return ALT_DELETE;
@@ -1119,7 +1126,12 @@ int convert_sequence(const int *seq, size_t length, int *consumed)
 							if (seq[3] == '6')
 								/* Esc [ 3 ; 6 ~ == Ctrl-Shift-Delete on xterm. */
 								return controlshiftdelete;
+#endif
 						}
+						if (length > 2 && seq[2] == '$')
+							/* Esc [ 3 $ == Shift-Delete on urxvt. */
+							return SHIFT_DELETE;
+#ifndef NANO_TINY
 						if (length > 2 && seq[2] == '^')
 							/* Esc [ 3 ^ == Ctrl-Delete on urxvt. */
 							return CONTROL_DELETE;
-- 
2.19.1

