diff options
author | June McEnroe <june@causal.agency> | 2022-03-16 20:18:54 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2022-03-16 20:21:00 -0400 |
commit | 714b4bc76a239a7802715f13104cdcafa1020e7c (patch) | |
tree | a91f1a69bca57a8aaa12257c64e8b28e8e07cc63 | |
parent | Document using -S to connect over IPv4 or IPv6 (diff) | |
download | catgirl-714b4bc76a239a7802715f13104cdcafa1020e7c.tar.gz catgirl-714b4bc76a239a7802715f13104cdcafa1020e7c.zip |
Skip non-spacing when moving and deleting by "character"
I uh... don't think I can write tests for this, since macOS's wcwidth is notoriously useless.
-rw-r--r-- | edit.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/edit.c b/edit.c index bb92edf..effb623 100644 --- a/edit.c +++ b/edit.c @@ -105,13 +105,29 @@ int editDelete(struct Edit *e, bool cut, size_t index, size_t count) { return 0; } +static size_t prevSpacing(const struct Edit *e, size_t pos) { + if (!pos) return 0; + do { + pos--; + } while (pos && !wcwidth(e->buf[pos])); + return pos; +} + +static size_t nextSpacing(const struct Edit *e, size_t pos) { + if (pos == e->len) return e->len; + do { + pos++; + } while (pos < e->len && !wcwidth(e->buf[pos])); + return pos; +} + int editFn(struct Edit *e, enum EditFn fn) { int ret = 0; switch (fn) { break; case EditHead: e->pos = 0; break; case EditTail: e->pos = e->len; - break; case EditPrev: if (e->pos) e->pos--; - break; case EditNext: if (e->pos < e->len) e->pos++; + break; case EditPrev: e->pos = prevSpacing(e, e->pos); + break; case EditNext: e->pos = nextSpacing(e, e->pos); break; case EditPrevWord: { while (e->pos && !isword(e->buf[e->pos-1])) e->pos--; while (e->pos && isword(e->buf[e->pos-1])) e->pos--; @@ -129,10 +145,12 @@ int editFn(struct Edit *e, enum EditFn fn) { ret = editDelete(e, true, e->pos, e->len - e->pos); } break; case EditDeletePrev: { - if (e->pos) editDelete(e, false, --e->pos, 1); + size_t prev = prevSpacing(e, e->pos); + editDelete(e, false, prev, e->pos - prev); + e->pos = prev; } break; case EditDeleteNext: { - editDelete(e, false, e->pos, 1); + editDelete(e, false, e->pos, nextSpacing(e, e->pos) - e->pos); } break; case EditDeletePrevWord: { if (!e->pos) break; |