From 05941593d2b3309972d5a421bfe548a0ef0a0be8 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 8 Jan 2019 22:13:06 -0500 Subject: [PATCH] added quote matching logic to context selection --- TODO.md | 3 --- src/lib/buf.c | 41 ++++++++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/TODO.md b/TODO.md index 645571f..94fa745 100644 --- a/TODO.md +++ b/TODO.md @@ -9,9 +9,6 @@ * registrar: should remove invalid windows from registry when detected * tide: Ctrl+D should not pass tag name as arg when executing tag commands * tide: gap buffer does not handle UTF-8 currently -* Add matching logic for "", '', `` - * Look at char to left, scan forward if quote to find end. - * Look at current char or char to right, if quote, scan right to find beginning ## BACKLOG diff --git a/src/lib/buf.c b/src/lib/buf.c index ba14c65..f825170 100644 --- a/src/lib/buf.c +++ b/src/lib/buf.c @@ -521,20 +521,47 @@ void buf_selall(Buf* buf) { buf->selection = (Sel){ .beg = 0, .end = buf_end(buf) }; } +static bool selquote(Buf* buf, Rune c) { + Rune curr = buf_getc(buf); + size_t nextoff = buf_byrune(buf, buf->selection.end, RIGHT); + Rune prev = buf_getrat(buf, buf_byrune(buf, buf->selection.end, LEFT)); + Rune next = buf_getrat(buf, buf_byrune(buf, buf->selection.end, RIGHT)); + if (prev == c || curr == c) { + size_t bend = buf_end(buf); + buf->selection.beg = buf->selection.end = (prev == c ? buf->selection.end : nextoff); + size_t selend = buf->selection.end; + for (; selend < bend && buf_getrat(buf, selend) != c; selend = buf_byrune(buf, selend, RIGHT)); + if (buf_getrat(buf, selend) == c) + buf->selection.end = selend; + return true; + } else if (next == c) { + buf->selection.beg = buf->selection.end; + buf->selection.end = nextoff; + size_t selbeg = buf->selection.beg; + for (; selbeg > 0 && buf_getrat(buf, selbeg) != c; selbeg = buf_byrune(buf, selbeg, LEFT)); + if (buf_getrat(buf, selbeg) == c) + buf->selection.beg = buf_byrune(buf, selbeg, RIGHT); + return true; + } + return false; +} + void buf_selctx(Buf* buf, bool (*isword)(Rune)) { size_t bol = buf_bol(buf, buf->selection.end); - Rune r = buf_getc(buf); - if (r == '(' || r == ')') + Rune curr = buf_getc(buf); + if (curr == '(' || curr == ')') selblock(buf, '(', ')'); - else if (r == '[' || r == ']') + else if (curr == '[' || curr == ']') selblock(buf, '[', ']'); - else if (r == '{' || r == '}') + else if (curr == '{' || curr == '}') selblock(buf, '{', '}'); - else if (r == '<' || r == '>') + else if (curr == '<' || curr == '>') selblock(buf, '<', '>'); - else if (buf->selection.end == bol || r == '\n') + else if (selquote(buf, '"') || selquote(buf, '`') || selquote(buf, '\'')) + ; /* condition performs selection */ + else if (buf->selection.end == bol || curr == '\n') selline(buf); - else if (risword(r)) + else if (risword(curr)) buf_selword(buf, isword); else buf_selword(buf, risbigword); -- 2.52.0