diff options
author | June McEnroe <june@causal.agency> | 2022-03-12 17:52:44 -0500 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2022-03-12 17:52:44 -0500 |
commit | 186180700c55c224dbf69555debd2a07f52aa19a (patch) | |
tree | 1ba9c942d518c057ad95e0e47324478b1b795d24 | |
parent | Treat C-v as an emacs key (diff) | |
download | catgirl-186180700c55c224dbf69555debd2a07f52aa19a.tar.gz catgirl-186180700c55c224dbf69555debd2a07f52aa19a.zip |
Implement vi R and r
-rw-r--r-- | edit.c | 53 | ||||
-rw-r--r-- | edit.h | 1 |
2 files changed, 40 insertions, 14 deletions
diff --git a/edit.c b/edit.c index 25341d1..e7cb62e 100644 --- a/edit.c +++ b/edit.c @@ -202,27 +202,37 @@ enum { }; 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; + if (!e->vi.lnext) { + switch (ch) { + break; case Erase: return editFn(e, EditDeletePrev); + break; case Kill: return editFn(e, EditDeleteHead); + break; case LNext: e->vi.lnext = true; return 0; + break; case WErase: return editFn(e, EditDeletePrevWord); + break; case Esc: { + if (e->pos) e->pos--; + e->vi.mode = EditViCommand; + return 0; + } } - break; default: return editInsert(e, ch); + } + e->vi.lnext = false; + if (e->vi.verb == 'R' && e->pos < e->len) { + e->buf[e->pos] = ch; + e->pos++; + } else if (e->vi.verb == 'r' && e->pos < e->len) { + e->buf[e->pos] = ch; + e->vi.mode = EditViCommand; + } else { + return editInsert(e, ch); } return 0; } static int editViCommand(struct Edit *e, wchar_t ch) { switch (ch) { - break; case L'i': e->vi.mode = EditViInsert; + break; case L'R': e->vi.verb = 'R'; e->vi.mode = EditViInsert; + break; case L'i': e->vi.verb = 'i'; e->vi.mode = EditViInsert; + break; case L'r': e->vi.verb = 'r'; e->vi.mode = EditViInsert; } return 0; } @@ -261,6 +271,13 @@ static bool eq(struct Edit *e, const char *str1) { } #define editFn(...) assert(0 == editFn(__VA_ARGS__)) +#define editVi(...) assert(0 == editVi(__VA_ARGS__)) + +static void vi(struct Edit *e, const char *str) { + for (const char *ch = str; *ch; ++ch) { + editVi(e, *ch); + } +} int main(void) { struct Edit cut = {0}; @@ -358,6 +375,14 @@ int main(void) { assert(eq(&e, "foo \33\0")); editVi(&e, Kill); assert(eq(&e, "\0")); + + fix(&e, "foo"); + vi(&e, "\33rx"); + assert(e.vi.mode == EditViCommand); + assert(eq(&e, "fo\0x")); + vi(&e, "Robar\33"); + assert(e.vi.mode == EditViCommand); + assert(eq(&e, "fooba\0r")); } #endif /* TEST */ diff --git a/edit.h b/edit.h index 8ad382b..382e9d2 100644 --- a/edit.h +++ b/edit.h @@ -40,6 +40,7 @@ struct Edit { EditViCommand, } mode; bool lnext; + char verb; } vi; }; |