From 621634e70386c14667e6d63364f79e9405108a08 Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Windows 11)" <rob@synchro.net>
Date: Fri, 1 Nov 2024 23:42:27 -0700
Subject: [PATCH] Refactor the internal message editor /D command to support
 deletion of ranges

Supporting the deletion of ranges of lines (e.g. 10-20 rather than one line
at a time) was a big ommission for a long time.
---
 src/sbbs3/writemsg.cpp | 45 +++++++++++++++++++++++++-----------------
 text/menu/editor.asc   |  1 +
 2 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/src/sbbs3/writemsg.cpp b/src/sbbs3/writemsg.cpp
index d61ed7bac2..9c05da075c 100644
--- a/src/sbbs3/writemsg.cpp
+++ b/src/sbbs3/writemsg.cpp
@@ -1053,7 +1053,7 @@ uint sbbs_t::msgeditor(char *buf, const char *top, char *title, uint maxlines, u
 				continue;
 			}
 		}
-		if(strin[0]=='/' && strlen(strin)<8) {
+		if(strin[0]=='/' && strlen(strin)<16) {
 			if(!stricmp(strin,"/DEBUG") && SYSOP) {
 				bprintf("\r\nline=%d lines=%d (%d), rows=%d\r\n",line,lines,(int)strListCount(str), rows);
 				continue;
@@ -1062,26 +1062,35 @@ uint sbbs_t::msgeditor(char *buf, const char *top, char *title, uint maxlines, u
 				strListFree(&str);
 				return(0);
 			}
-			else if(toupper(strin[1])=='D') {	/* delete a line */
-				if(str[0] == NULL)
-					continue;
+			else if(toupper(strin[1])=='D') {	// delete line(s)
 				lines = strListCount(str);
-				i=atoi(strin+2)-1;
-				if(i==-1)   /* /D means delete last line */
-					i=lines-1;
-				if(i>=(int)lines || i<0)
-					bputs(text[InvalidLineNumber]);
-				else {
-					free(str[i]);
-					lines--;
-					while(i<(int)lines) {
-						str[i]=str[i+1];
-						i++;
+				char* p = strin + 2;
+				int first = atoi(p) - 1;
+				if(first < 0 || (uint)first >= lines) {
+					if(*p) {
+						bputs(text[InvalidLineNumber]);
+						continue;
+					}
+					first = lines - 1; // /D means delete last line
+					if(first < 0)
+						continue;
+				}
+				int last = first;
+				SKIP_DIGIT(p);
+				FIND_CHAR(p, '-');
+				if(*p == '-') {
+					++p;
+					last = atoi(p) - 1;
+					if(last < first || (uint)last >= lines) {
+						bputs(text[InvalidLineNumber]);
+						continue;
 					}
-					str[i] = NULL;
-					if(line>lines)
-						line=lines;
 				}
+				int count = (last - first) + 1;
+				strListFastDelete(str, first, count);
+				lines -= count;
+				if(line>lines)
+					line=lines;
 				continue;
 			}
 			else if(toupper(strin[1])=='I') {	/* insert a line before number x */
diff --git a/text/menu/editor.asc b/text/menu/editor.asc
index 15b49085d6..2f8a019a71 100644
--- a/text/menu/editor.asc
+++ b/text/menu/editor.asc
@@ -8,6 +8,7 @@
 h/Ex     nEdit Line x
 h/D      nDelete Last Line
 h/Dx     nDelete Line x
+h/Dx-y   nDelete Lines x through y
 h/I      nInsert Line Before Last
 h/Ix     nInsert Line Before Line x
 h/T      nEdit Message Subject
-- 
GitLab