From e98f346fbee3898127eec55f8646adfca0325f73 Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Sat, 12 Mar 2022 17:23:37 -0500 Subject: Implement vi insert mode --- edit.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'edit.c') diff --git a/edit.c b/edit.c index 0a409a4..25341d1 100644 --- a/edit.c +++ b/edit.c @@ -195,16 +195,29 @@ int editInsert(struct Edit *e, wchar_t ch) { enum { Esc = L'\33', + Erase = L'\177', + Kill = L'@' ^ L'U', + LNext = L'@' ^ 'V', + WErase = L'@' ^ L'W', }; static int editViInsert(struct Edit *e, wchar_t ch) { + if (e->vi.lnext) { + e->vi.lnext = false; + return editInsert(e, ch); + } switch (ch) { + break; case Erase: return editFn(e, EditDeletePrev); + break; case Kill: return editFn(e, EditDeleteHead); + break; case LNext: e->vi.lnext = true; + break; case WErase: return editFn(e, EditDeletePrevWord); break; case Esc: { + if (e->pos) e->pos--; e->vi.mode = EditViCommand; - return 0; } - default: return editInsert(e, ch); + break; default: return editInsert(e, ch); } + return 0; } static int editViCommand(struct Edit *e, wchar_t ch) { @@ -220,9 +233,6 @@ int editVi(struct Edit *e, wchar_t ch) { 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; } @@ -232,6 +242,7 @@ int editVi(struct Edit *e, wchar_t ch) { #include static void fix(struct Edit *e, const char *str) { + e->vi.mode = EditViInsert; assert(0 == editFn(e, EditClear)); for (const char *ch = str; *ch; ++ch) { assert(0 == editInsert(e, (wchar_t)*ch)); @@ -334,6 +345,19 @@ int main(void) { assert(e.vi.mode == EditViInsert); editVi(&e, L'b'); assert(eq(&e, "fob\0o")); + editVi(&e, Esc); + assert(eq(&e, "fo\0bo")); + + fix(&e, "foo bar"); + editVi(&e, Erase); + assert(eq(&e, "foo ba\0")); + editVi(&e, WErase); + assert(eq(&e, "foo \0")); + editVi(&e, LNext); + editVi(&e, Esc); + assert(eq(&e, "foo \33\0")); + editVi(&e, Kill); + assert(eq(&e, "\0")); } #endif /* TEST */ -- cgit 1.4.1