summary refs log tree commit diff
path: root/edit.c
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2022-02-09 17:55:33 -0500
committerJune McEnroe <june@causal.agency>2022-02-09 17:55:33 -0500
commit9c384de6dbe526374af5075e06260063a9764cb9 (patch)
treec18590d1f08f87bd1fef8b9984e610972a313efc /edit.c
parentAdd M-s to (temporarily) reveal spoiler text (diff)
downloadcatgirl-9c384de6dbe526374af5075e06260063a9764cb9.tar.gz
catgirl-9c384de6dbe526374af5075e06260063a9764cb9.zip
Treat any amount of space and punctuation as word boundaries
This matches behaviour of, e.g. zsh -o emacs.
Diffstat (limited to 'edit.c')
-rw-r--r--edit.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/edit.c b/edit.c
index 71c5cca..9aa1c86 100644
--- a/edit.c
+++ b/edit.c
@@ -207,6 +207,10 @@ static void tabReject(void) {
 	tab.len = 0;
 }
 
+static bool isword(wchar_t ch) {
+	return !iswspace(ch) && !iswpunct(ch);
+}
+
 void edit(uint id, enum Edit op, wchar_t ch) {
 	size_t init = pos;
 	switch (op) {
@@ -215,12 +219,12 @@ void edit(uint id, enum Edit op, wchar_t ch) {
 		break; case EditPrev: if (pos) pos--;
 		break; case EditNext: if (pos < len) pos++;
 		break; case EditPrevWord: {
-			if (pos) pos--;
-			while (pos && !iswspace(buf[pos - 1])) pos--;
+			while (pos && !isword(buf[pos - 1])) pos--;
+			while (pos && isword(buf[pos - 1])) pos--;
 		}
 		break; case EditNextWord: {
-			if (pos < len) pos++;
-			while (pos < len && !iswspace(buf[pos])) pos++;
+			while (pos < len && !isword(buf[pos])) pos++;
+			while (pos < len && isword(buf[pos])) pos++;
 		}
 
 		break; case EditDeleteHead: delete(true, 0, pos); pos = 0;
@@ -229,15 +233,17 @@ void edit(uint id, enum Edit op, wchar_t ch) {
 		break; case EditDeleteNext: delete(false, pos, 1);
 		break; case EditDeletePrevWord: {
 			if (!pos) break;
-			size_t word = pos - 1;
-			while (word && !iswspace(buf[word - 1])) word--;
+			size_t word = pos;
+			while (word && !isword(buf[word - 1])) word--;
+			while (word && isword(buf[word - 1])) word--;
 			delete(true, word, pos - word);
 			pos = word;
 		}
 		break; case EditDeleteNextWord: {
 			if (pos == len) break;
-			size_t word = pos + 1;
-			while (word < len && !iswspace(buf[word])) word++;
+			size_t word = pos;
+			while (word < len && !isword(buf[word])) word++;
+			while (word < len && isword(buf[word])) word++;
 			delete(true, pos, word - pos);
 		}
 		break; case EditPaste: {