diff options
author | June McEnroe <june@causal.agency> | 2022-03-12 15:32:08 -0500 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2022-03-12 15:34:50 -0500 |
commit | 6cdda636227b492d9ed606a3d7de22909d241c48 (patch) | |
tree | 0d79cf9dd5346d95dfe8de15029689e93124dbaa | |
parent | Separate emacs key bindings (diff) | |
download | catgirl-6cdda636227b492d9ed606a3d7de22909d241c48.tar.gz catgirl-6cdda636227b492d9ed606a3d7de22909d241c48.zip |
Implement basic esc/i mode switching
-rw-r--r-- | edit.c | 43 | ||||
-rw-r--r-- | edit.h | 14 |
2 files changed, 52 insertions, 5 deletions
diff --git a/edit.c b/edit.c index bb92edf..0a409a4 100644 --- a/edit.c +++ b/edit.c @@ -193,6 +193,39 @@ int editInsert(struct Edit *e, wchar_t ch) { return 0; } +enum { + Esc = L'\33', +}; + +static int editViInsert(struct Edit *e, wchar_t ch) { + switch (ch) { + break; case Esc: { + e->vi.mode = EditViCommand; + return 0; + } + default: return editInsert(e, ch); + } +} + +static int editViCommand(struct Edit *e, wchar_t ch) { + switch (ch) { + break; case L'i': e->vi.mode = EditViInsert; + } + return 0; +} + +int editVi(struct Edit *e, wchar_t ch) { + int error; + switch (e->vi.mode) { + break; case EditViInsert: error = editViInsert(e, ch); + break; case EditViCommand: error = editViCommand(e, ch); + } + if (e->vi.mode == EditViCommand && e->pos == e->len && e->pos) { + e->pos--; + } + return error; +} + #ifdef TEST #undef NDEBUG #include <assert.h> @@ -291,6 +324,16 @@ int main(void) { fix(&e, " foo bar "); editFn(&e, EditCollapse); assert(eq(&e, "foo bar\0")); + + fix(&e, "foo"); + assert(e.vi.mode == EditViInsert); + editVi(&e, Esc); + assert(e.vi.mode == EditViCommand); + assert(eq(&e, "fo\0o")); + editVi(&e, L'i'); + assert(e.vi.mode == EditViInsert); + editVi(&e, L'b'); + assert(eq(&e, "fob\0o")); } #endif /* TEST */ diff --git a/edit.h b/edit.h index db0d416..535b575 100644 --- a/edit.h +++ b/edit.h @@ -28,17 +28,18 @@ #include <stdbool.h> #include <stddef.h> -enum EditMode { - EditInsert, -}; - struct Edit { - enum EditMode mode; wchar_t *buf; size_t pos; size_t len; size_t cap; struct Edit *cut; + struct { + enum EditViMode { + EditViInsert, + EditViCommand, + } mode; + } vi; }; enum EditFn { @@ -63,6 +64,9 @@ enum EditFn { // Perform an editing function. int editFn(struct Edit *e, enum EditFn fn); +// Perform a vi editing function. +int editVi(struct Edit *e, wchar_t ch); + // Insert a character at the cursor. int editInsert(struct Edit *e, wchar_t ch); |