From 26e2edd3a4c9ca3c428a811f4589035927e00946 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 22 Oct 2019 23:23:16 -0400 Subject: [PATCH] refactored selection handling --- TODO.md | 1 - inc/edit.h | 17 +++----- src/lib/buf.c | 116 ++++++++++++++++++++++++-------------------------- 3 files changed, 62 insertions(+), 72 deletions(-) diff --git a/TODO.md b/TODO.md index e04e325..e3525b2 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,6 @@ ## STAGING -* tide: refactor selection handling and column tracking out of view.c * all: eliminate multiple return statements and other lint * tide: byrune, byword, byline functions should be hidden in buf.c * tide: column tracking should be hidden in buf.c diff --git a/inc/edit.h b/inc/edit.h index 8ce2084..5e41b9e 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -97,19 +97,11 @@ bool buf_iseol(Buf* buf, size_t pos); size_t buf_bol(Buf* buf, size_t pos); size_t buf_eol(Buf* buf, size_t pos); -void buf_selword(Buf* buf, bool (*isword)(Rune)); -void buf_selall(Buf* buf); -void buf_selctx(Buf* buf, bool (*isword)(Rune)); - -size_t buf_byrune(Buf* buf, size_t pos, int count); -size_t buf_byword(Buf* buf, size_t pos, int count); -size_t buf_byline(Buf* buf, size_t pos, int count); bool buf_findstr(Buf* buf, int dir, char* str); +char* buf_fetch(Buf* buf, bool (*isword)(Rune), size_t off); void buf_setln(Buf* buf, size_t line); void buf_getln(Buf* buf, size_t* begln, size_t* endln); -void buf_getcol(Buf* buf); -void buf_setcol(Buf* buf); size_t buf_selbeg(Buf* buf); size_t buf_selend(Buf* buf); @@ -117,7 +109,12 @@ size_t buf_selsz(Buf* buf); void buf_selln(Buf* buf); void buf_selclr(Buf* buf, int dir); bool buf_insel(Buf* buf, size_t off); -char* buf_fetch(Buf* buf, bool (*isword)(Rune), size_t off); +void buf_selword(Buf* buf, bool (*isword)(Rune)); +void buf_selall(Buf* buf); +void buf_selctx(Buf* buf, bool (*isword)(Rune)); + +size_t buf_byrune(Buf* buf, size_t pos, int count); +size_t buf_moveby(Buf* buf, int bything, size_t pos, int count); void buf_selmove(Buf* buf, bool extsel, int move, int bything); void buf_selmoveto(Buf* buf, bool extsel, size_t off); diff --git a/src/lib/buf.c b/src/lib/buf.c index 097ff4e..774feb9 100644 --- a/src/lib/buf.c +++ b/src/lib/buf.c @@ -27,6 +27,45 @@ static bool buf_valid(Buf* buf) } #endif +static void getcol(Buf* buf) +{ + require(buf != NULL); + Sel sel = buf->selection; + size_t pos = sel.end, curr = buf_bol(buf, pos); + for (sel.col = 0; curr < pos; curr = buf_byrune(buf, curr, 1)) + { + sel.col += runewidth(sel.col, buf_getrat(buf, curr)); + } + buf->selection = sel; +} + +static void setcol(Buf* buf) +{ + require(buf != NULL); + Sel sel = buf->selection; + size_t bol = buf_bol(buf, sel.end); + size_t curr = bol, len = 0, i = 0; + + /* determine the length of the line in columns */ + for (; !buf_iseol(buf, curr); curr++) + { + len += runewidth(len, buf_getrat(buf, curr)); + } + + /* iterate over the runes until we reach the target column */ + for (sel.end = bol, i = 0; i < sel.col && i < len;) + { + int width = runewidth(i, buf_getrat(buf, sel.end)); + sel.end = buf_byrune(buf, sel.end, 1); + if (sel.col >= i && sel.col < (i + width)) + { + break; + } + i += width; + } + buf->selection = sel; +} + static Sel selswap(Sel sel) { size_t off = sel.beg; @@ -44,10 +83,9 @@ static Sel selget(Buf* buf) static void selset(Buf* buf, Sel sel) { buf->selection = sel; - buf_getcol(buf); + getcol(buf); } - static void putch(Buf* buf, char b, Sel* p_sel) { if (b != '\r') @@ -549,7 +587,7 @@ void buf_selctx(Buf* buf, bool (*isword)(Rune)) { buf_selword(buf, risbigword); } - buf_getcol(buf); + getcol(buf); } size_t buf_byrune(Buf* buf, size_t pos, int count) @@ -585,7 +623,7 @@ size_t buf_byrune(Buf* buf, size_t pos, int count) return pos; } -size_t buf_byword(Buf* buf, size_t off, int count) +static size_t byword(Buf* buf, size_t off, int count) { require(buf != NULL); int move = (count < 0 ? -1 : 1); @@ -615,7 +653,7 @@ size_t buf_byword(Buf* buf, size_t off, int count) return off; } -size_t buf_byline(Buf* buf, size_t pos, int count) +static size_t byline(Buf* buf, size_t pos, int count) { require(buf != NULL); int move = (count < 0 ? -1 : 1); @@ -675,7 +713,7 @@ void buf_setln(Buf* buf, size_t line) size_t curr = 0, end = buf_end(buf); while (line > 1 && curr < end) { - size_t next = buf_byline(buf, curr, DOWN); + size_t next = byline(buf, curr, DOWN); if (curr == next) { break; @@ -693,7 +731,7 @@ void buf_getln(Buf* buf, size_t* begln, size_t* endln) size_t sbeg = buf_selbeg(buf), send = buf_selend(buf); while (curr < end) { - size_t next = buf_byline(buf, curr, DOWN); + size_t next = byline(buf, curr, DOWN); if (curr <= sbeg && sbeg < next) { @@ -715,45 +753,6 @@ void buf_getln(Buf* buf, size_t* begln, size_t* endln) } } -void buf_getcol(Buf* buf) -{ - require(buf != NULL); - Sel sel = buf->selection; - size_t pos = sel.end, curr = buf_bol(buf, pos); - for (sel.col = 0; curr < pos; curr = buf_byrune(buf, curr, 1)) - { - sel.col += runewidth(sel.col, buf_getrat(buf, curr)); - } - buf->selection = sel; -} - -void buf_setcol(Buf* buf) -{ - require(buf != NULL); - Sel sel = buf->selection; - size_t bol = buf_bol(buf, sel.end); - size_t curr = bol, len = 0, i = 0; - - /* determine the length of the line in columns */ - for (; !buf_iseol(buf, curr); curr++) - { - len += runewidth(len, buf_getrat(buf, curr)); - } - - /* iterate over the runes until we reach the target column */ - for (sel.end = bol, i = 0; i < sel.col && i < len;) - { - int width = runewidth(i, buf_getrat(buf, sel.end)); - sel.end = buf_byrune(buf, sel.end, 1); - if (sel.col >= i && sel.col < (i + width)) - { - break; - } - i += width; - } - buf->selection = sel; -} - size_t buf_selbeg(Buf* buf) { require(buf != NULL); @@ -823,16 +822,16 @@ char* buf_fetch(Buf* buf, bool (*isword)(Rune), size_t off) return str; } -static size_t moveby(int bything, Buf* buf, size_t pos, int count) +size_t buf_moveby(Buf* buf, int bything, size_t pos, int count) { size_t newpos = pos; switch (bything) { case BY_WORD: - newpos = buf_byword(buf, pos, count); + newpos = byword(buf, pos, count); break; case BY_LINE: - newpos = buf_byline(buf, pos, count); + newpos = byline(buf, pos, count); break; case BY_RUNE: default: @@ -844,31 +843,26 @@ static size_t moveby(int bything, Buf* buf, size_t pos, int count) void buf_selmove(Buf* buf, bool extsel, int move, int bything) { - (void)bything, (void)moveby, (void)extsel; - if (buf_selsz(buf) && !extsel) { - if (move < 0) - { - buf->selection.end = moveby(bything, buf, buf_selbeg(buf), move); - } - else if (!buf_isbol(buf, buf->selection.end)) + buf_selclr(buf, move); + if (bything == BY_LINE && move < 0) { - buf->selection.end = moveby(bything, buf, buf_selend(buf), move); + buf->selection.end = buf_moveby(buf, bything, buf->selection.end, move); } } else { - buf->selection.end = moveby(bything, buf, buf->selection.end, move); + buf->selection.end = buf_moveby(buf, bything, buf->selection.end, move); } if (bything == BY_LINE) { - buf_setcol(buf); + setcol(buf); } else { - buf_getcol(buf); + getcol(buf); } if (!extsel) @@ -898,6 +892,6 @@ void buf_selmoveto(Buf* buf, bool extsel, size_t off) } else { - buf_getcol(buf); + getcol(buf); } } -- 2.52.0