From: Michael D. Lowis Date: Fri, 3 Mar 2017 14:43:43 +0000 (-0500) Subject: Fixed delete functionality to make deleting by word work as expected. Also tweaked... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=6d0326c7cf8dc7d644b41103f17f04a53954b198;p=projs%2Ftide.git Fixed delete functionality to make deleting by word work as expected. Also tweaked movement by word so it behaves more reasonably --- diff --git a/lib/buf.c b/lib/buf.c index b94675c..7f183ee 100644 --- a/lib/buf.c +++ b/lib/buf.c @@ -442,17 +442,31 @@ unsigned buf_byrune(Buf* buf, unsigned pos, int count) { return pos; } +static Rune nextrune(Buf* buf, unsigned off, int move, bool (*testfn)(Rune)) { + bool ret = false; + unsigned end = buf_end(buf); + if (move < 0 && off > 0) + ret = testfn(buf_get(buf, off-1)); + else if (move > 0 && off < end) + ret = testfn(buf_get(buf, off+1)); + return ret; +} + unsigned buf_byword(Buf* buf, unsigned off, int count) { int move = (count < 0 ? -1 : 1); - unsigned end = buf_end(buf); - if (move < 0) { - for (; off > 0 && !risword(buf_get(buf, off-1)); off--); - for (; off > 0 && risword(buf_get(buf, off-1)); off--); + + while (nextrune(buf, off, move, risblank)) + off = buf_byrune(buf, off, move); + + if (nextrune(buf, off, move, risword)) { + while (nextrune(buf, off, move, risword)) + off = buf_byrune(buf, off, move); + if (move > 0) + off = buf_byrune(buf, off, move); } else { - for (; off < end && risword(buf_get(buf, off+1)); off++); - for (; off < end && !risword(buf_get(buf, off+1)); off++); - if (off < buf_end(buf)) off++; + off = buf_byrune(buf, off, move); } + return off; } @@ -558,22 +572,18 @@ void buf_lastins(Buf* buf, size_t* beg, size_t* end) { opbeg = log->data.ins.end, opend = log->data.ins.end; unsigned delsize = 0; - //printf("start: %u-%u\n", opbeg, opend); for (; log; log = log->next) { if (log->insert) { unsigned ibeg = log->data.ins.beg, iend = log->data.ins.end - delsize; - //printf("ins: %u-%u\n", ibeg, iend); if (iend < ibeg || ibeg > opbeg || iend < opbeg) break; if (ibeg < opbeg && iend > opend) break; opbeg = ibeg, delsize = 0; } else { - //printf("del: %u-%u\n", log->data.del.off, log->data.del.off+log->data.del.len); /* bail if the delete doesnt overlap */ if(log->data.del.off != opbeg) break; delsize = log->data.del.len; } } - //printf("finish: %u-%u\n\n", opbeg, opend); *beg = opbeg, *end = opend; } diff --git a/lib/view.c b/lib/view.c index d43de7b..eed9f55 100644 --- a/lib/view.c +++ b/lib/view.c @@ -412,19 +412,13 @@ void view_insert(View* view, bool indent, Rune rune) { } void view_delete(View* view, int dir, bool byword) { - Sel sel = view->selection; - selswap(&sel); - size_t num = num_selected(sel); - if (num != 0) - sel.end = buf_delete(&(view->buffer), sel.beg, sel.end); - else if ((dir == LEFT) && (sel.end > 0)) - sel.end = buf_delete(&(view->buffer), sel.end-1, sel.end); - else if ((dir == RIGHT) && (sel.end < buf_end(&(view->buffer)))) - sel.end = buf_delete(&(view->buffer), sel.end, sel.end+1); - sel.beg = sel.end; - /* update the selection */ - view->selection = sel; - view->selection.col = buf_getcol(&(view->buffer), view->selection.end); + Sel* sel = &(view->selection); + if (sel->beg == sel->end) + (byword ? view_byword : view_byrune)(view, dir, true); + selswap(sel); + sel->end = buf_delete(&(view->buffer), sel->beg, sel->end); + sel->beg = sel->end; + sel->col = buf_getcol(&(view->buffer), sel->end); view->sync_needed = true; } diff --git a/tests/xedit.c b/tests/xedit.c index 2d82a6e..67f5158 100644 --- a/tests/xedit.c +++ b/tests/xedit.c @@ -176,8 +176,8 @@ TEST_SUITE(UnitTests) { TEST(ctrl+right should move right by one word) { setup_view(EDIT, "AB CD", CRLF, 0); send_keys(ModCtrl, XK_Right); - CHECK(win_sel(EDIT)->beg == 3); - CHECK(win_sel(EDIT)->end == 3); + CHECK(win_sel(EDIT)->beg == 2); + CHECK(win_sel(EDIT)->end == 2); } TEST(right should move right by one rune) {