]> git.mdlowis.com Git - projs/tide.git/commitdiff
added quote matching logic to context selection
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 9 Jan 2019 03:13:06 +0000 (22:13 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 9 Jan 2019 03:13:06 +0000 (22:13 -0500)
TODO.md
src/lib/buf.c

diff --git a/TODO.md b/TODO.md
index 645571f24371375027998052b26bc7bc9d55c248..94fa7457f07ff84f1bba403d6f057033d40065cd 100644 (file)
--- 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
 
index ba14c65fe6c18f2b245f746560503847b8f2d64c..f82517072e4b3b9cb1268473c8a02cd8f419c990 100644 (file)
@@ -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);