summary refs log tree commit diff
path: root/edit.c
diff options
context:
space:
mode:
authorC. McEnroe2020-02-07 01:55:26 -0500
committerC. McEnroe2020-02-07 01:56:23 -0500
commitaf244ad3cd19fb50bf9b9855f02d81e61441ab50 (patch)
tree4ecd69f0d6fc8f041823e4d5846467ce0b7c1709 /edit.c
parent5470254fa5fd0f6108b1f075d9ac2dd24afa7fdc (diff)
Add some real line editing operations
Diffstat (limited to 'edit.c')
-rw-r--r--edit.c28
1 files changed, 24 insertions, 4 deletions
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;