about summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--chat.h5
-rw-r--r--edit.c28
-rw-r--r--ui.c12
3 files changed, 41 insertions, 4 deletions
diff --git a/chat.h b/chat.h
index 8279d1b..a327620 100644
--- a/chat.h
+++ b/chat.h
@@ -133,7 +133,12 @@ void uiFormat(
 ) __attribute__((format(printf, 4, 5)));
 
 enum Edit {
+	EditHome,
+	EditEnd,
+	EditLeft,
+	EditRight,
 	EditKill,
+	EditErase,
 	EditInsert,
 	EditEnter,
 };
diff --git a/edit.c b/edit.c
index 68593d1..b6edb98 100644
--- a/edit.c
+++ b/edit.c
@@ -45,13 +45,33 @@ char *editTail(void) {
 	return mbs;
 }
 
+static void reserve(size_t index, size_t count) {
+	if (len + count > Cap) return;
+	memmove(&buf[index + count], &buf[index], sizeof(*buf) * (len - index));
+	len += count;
+}
+
+static void delete(size_t index, size_t count) {
+	if (index + count > len) return;
+	memmove(
+		&buf[index], &buf[index + count], sizeof(*buf) * (len - index - count)
+	);
+	len -= count;
+}
+
 void edit(size_t id, enum Edit op, wchar_t ch) {
 	switch (op) {
-		break; case EditKill: len = pos = 0;
+		break; case EditHome:  pos = 0;
+		break; case EditEnd:   pos = len;
+		break; case EditLeft:  if (pos) pos--;
+		break; case EditRight: if (pos < len) pos++;
+
+		break; case EditKill:  len = pos = 0;
+		break; case EditErase: if (pos) delete(--pos, 1);
+
 		break; case EditInsert: {
-			if (len == Cap) break;
-			buf[pos++] = ch;
-			len++;
+			reserve(pos, 1);
+			if (pos < Cap) buf[pos++] = ch;
 		}
 		break; case EditEnter: {
 			pos = 0;
diff --git a/ui.c b/ui.c
index ffe8748..f73020a 100644
--- a/ui.c
+++ b/ui.c
@@ -546,12 +546,20 @@ void uiShowNum(size_t num) {
 }
 
 static void keyCode(int code) {
+	size_t id = windows.active->id;
 	switch (code) {
 		break; case KEY_RESIZE:  resize();
 		break; case KeyFocusIn:  unmark();
 		break; case KeyFocusOut: windows.active->mark = true;
 		break; case KeyPasteOn:; // TODO
 		break; case KeyPasteOff:; // TODO
+
+		break; case KEY_BACKSPACE: edit(id, EditErase, 0);
+		break; case KEY_END: edit(id, EditEnd, 0);
+		break; case KEY_ENTER: edit(id, EditEnter, 0);
+		break; case KEY_HOME: edit(id, EditHome, 0);
+		break; case KEY_LEFT: edit(id, EditLeft, 0);
+		break; case KEY_RIGHT: edit(id, EditRight, 0);
 	}
 }
 
@@ -567,6 +575,10 @@ static void keyMeta(wchar_t ch) {
 static void keyCtrl(wchar_t ch) {
 	size_t id = windows.active->id;
 	switch (ch) {
+		break; case L'?': edit(id, EditErase, 0);
+		break; case L'A': edit(id, EditHome, 0);
+		break; case L'E': edit(id, EditEnd, 0);
+		break; case L'H': edit(id, EditErase, 0);
 		break; case L'J': edit(id, EditEnter, 0);
 		break; case L'L': clearok(curscr, true);
 		break; case L'U': edit(id, EditKill, 0);