]> git.mdlowis.com Git - projs/tide.git/commitdiff
refactored column tracking for selections
authorMichael D. Lowis <mike.lowis@gentex.com>
Mon, 21 Oct 2019 18:45:04 +0000 (14:45 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Mon, 21 Oct 2019 18:45:04 +0000 (14:45 -0400)
inc/edit.h
src/lib/buf.c
src/lib/view.c
tests/lib/buf.c

index f8eaf5042c6d676c61863bc458ef2a9583d3ee12..8ce20847a663adbdb5dcf7ea7b9bce780cf98c6b 100644 (file)
@@ -48,6 +48,12 @@ typedef struct {
     Sel selection;    /* the currently selected text */
 } Buf;
 
+enum {
+    BY_RUNE = 0,
+    BY_WORD,
+    BY_LINE
+};
+
 void gapbuf_init(GapBuf* buf);
 size_t gapbuf_end(GapBuf* buf);
 long gapbuf_save(GapBuf* buf, char* path);
@@ -112,6 +118,8 @@ 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_selmove(Buf* buf, bool extsel, int move, int bything);
+void buf_selmoveto(Buf* buf, bool extsel, size_t off);
 
 /* Screen management functions
  *****************************************************************************/
index ba42c209de46cc086b8702b75feda2ef8f24106c..c7b209f5650c0132285ae77ab654a2ce58274629 100644 (file)
@@ -822,3 +822,56 @@ char* buf_fetch(Buf* buf, bool (*isword)(Rune), size_t off)
     buf->selection = prev;
     return str;
 }
+
+static size_t moveby(int bything, Buf* buf, size_t pos, int count)
+{
+    size_t newpos = pos;
+    switch (bything)
+    {
+        case BY_WORD:
+            newpos = buf_byword(buf, pos, count);
+            break;
+        case BY_LINE:
+            newpos = buf_byline(buf, pos, count);
+            break;
+        case BY_RUNE:
+        default:
+            newpos = buf_byrune(buf, pos, count);
+            break;
+    }
+    return newpos;
+}
+
+void buf_selmove(Buf* buf, bool extsel, int move, int bything)
+{
+    buf->selection.end = moveby(bything, buf, buf->selection.end, move);
+
+    if (bything == BY_LINE)
+    {
+        buf_setcol(buf);
+    }
+    else
+    {
+        buf_getcol(buf);
+    }
+
+    if (!extsel)
+    {
+        buf->selection.beg = buf->selection.end;
+    }
+}
+
+void buf_selmoveto(Buf* buf, bool extsel, size_t off)
+{
+    off = (off > buf_end(buf) ? buf_end(buf) : off);
+    int dir = (off < buf->selection.end ? LEFT : RIGHT);
+    buf->selection.end = off;
+    if (!extsel)
+    {
+        buf_selclr(buf, dir);
+    }
+    else
+    {
+        buf_getcol(buf);
+    }
+}
index 10990cc34ee9740638ff4f21dc8ffff45ec3687f..de2e64649e862d9e282c778d87b4914144c38256 100644 (file)
@@ -25,51 +25,16 @@ extern size_t glyph_width(View* view, int c);
 #define BUF    (&(view->buffer))
 #define CSRPOS (view->buffer.selection.end)
 
-typedef size_t (*movefn_t)(Buf* buf, size_t pos, int count);
-
-static void move_selection(View* view, bool extsel, int move, movefn_t bything)
+static void move_selection(View* view, bool extsel, int move, int bything)
 {
     view->sync_flags |= CURSOR;
-    if (buf_selsz(BUF) && !extsel)
-    {
-        buf_selclr(BUF, move);
-        if (bything == buf_byline)
-        {
-            CSRPOS = bything(BUF, CSRPOS, move);
-            buf_setcol(BUF);
-            if (!extsel)
-            {
-                buf_selclr(BUF, (move < 0 ? LEFT : RIGHT));
-            }
-        }
-    }
-    else
-    {
-        CSRPOS = bything(BUF, CSRPOS, move);
-        if (bything == buf_byline)
-        {
-            buf_setcol(BUF);
-        }
-
-        if (!extsel)
-        {
-            buf_selclr(BUF, (move < 0 ? LEFT : RIGHT));
-        }
-    }
+    buf_selmove(BUF, extsel, move, bything);
 }
 
 static void move_to(View* view, bool extsel, size_t off)
 {
-    Buf* buf = BUF;
-    off = (off > buf_end(buf) ? buf_end(buf) : off);
-    int dir = (off < CSRPOS ? LEFT : RIGHT);
-    CSRPOS = off;
-    if (!extsel)
-    {
-        buf_selclr(BUF, dir);
-    }
-    buf_getcol(buf);
     view->sync_flags |= CURSOR;
+    buf_selmoveto(BUF, extsel, off);
 }
 
 static bool selection_visible(View* view)
@@ -313,21 +278,21 @@ Row* view_getrow(View* view, size_t row)
 void view_byrune(View* view, int move, bool extsel)
 {
     require(view != NULL);
-    move_selection(view, extsel, move, buf_byrune);
+    move_selection(view, extsel, move, BY_RUNE);
     ensure(view_valid(view));
 }
 
 void view_byword(View* view, int move, bool extsel)
 {
     require(view != NULL);
-    move_selection(view, extsel, move, buf_byword);
+    move_selection(view, extsel, move, BY_WORD);
     ensure(view_valid(view));
 }
 
 void view_byline(View* view, int move, bool extsel)
 {
     require(view != NULL);
-    move_selection(view, extsel, move, buf_byline);
+    move_selection(view, extsel, move, BY_LINE);
     ensure(view_valid(view));
 }
 
index 6312141184d099459c4188c24bf10882cc1a7d08..ea6254411a4c29386e8afd8ced9bf102711a936f 100644 (file)
@@ -307,67 +307,67 @@ TEST_SUITE(BufferTests)
         CHECK(3 == buf_bol(&TestBuf, 3));
     }
 
-    /* Cursor Column Tracking
-     *************************************************************************/
-    TEST(buf_getcol should return the column associated with the position)
-    {
-        set_buffer_text("abcdef");
-        TestBuf.selection = (Sel){ .end = 4 };
-        buf_getcol(&TestBuf);
-        CHECK(4 == TestBuf.selection.col);
-    }
-
-    TEST(buf_getcol should return the column associated with the position on second line)
-    {
-        set_buffer_text("abcdef\nabcdef");
-        TestBuf.selection = (Sel){ .end = 7 };
-        buf_getcol(&TestBuf);
-        CHECK(0 == TestBuf.selection.col);
-    }
-
-    TEST(buf_getcol should handle tab characters)
-    {
-        set_buffer_text("\tabcdef");
-        TestBuf.selection = (Sel){ .end = 1 };
-        buf_getcol(&TestBuf);
-        CHECK(4 == TestBuf.selection.col);
-    }
-
-    TEST(buf_setcol should set the column to column 1 of second line)
-    {
-        set_buffer_text("abc\ndef");
-        TestBuf.selection = (Sel){ .end = 4, .col = 0 };
-        buf_setcol(&TestBuf);
-        CHECK(0 == TestBuf.selection.col);
-        CHECK(4 == TestBuf.selection.end);
-    }
-
-//    TEST(buf_setcol should set the column to column 2 of second line) {
-//        set_buffer_text("abc\ndef");
-//        TestBuf.selection = (Sel){ .end = 4, .col = 1 };
-//        buf_setcol(&TestBuf);
-//        CHECK(1 == TestBuf.selection.col);
-//        printf("%lu\n", TestBuf.selection.end);
-//        CHECK(5 == TestBuf.selection.end);
+//    /* Cursor Column Tracking
+//     *************************************************************************/
+//    TEST(buf_getcol should return the column associated with the position)
+//    {
+//        set_buffer_text("abcdef");
+//        TestBuf.selection = (Sel){ .end = 4 };
+//        buf_getcol(&TestBuf);
+//        CHECK(4 == TestBuf.selection.col);
 //    }
 //
-//    TEST(buf_setcol should handle tabs) {
-//        set_buffer_text("abc\n\tdef");
-//        TestBuf.selection = (Sel){ .end = 4, .col = 4 };
-//        buf_setcol(&TestBuf);
+//    TEST(buf_getcol should return the column associated with the position on second line)
+//    {
+//        set_buffer_text("abcdef\nabcdef");
+//        TestBuf.selection = (Sel){ .end = 7 };
+//        buf_getcol(&TestBuf);
+//        CHECK(0 == TestBuf.selection.col);
+//    }
+//
+//    TEST(buf_getcol should handle tab characters)
+//    {
+//        set_buffer_text("\tabcdef");
+//        TestBuf.selection = (Sel){ .end = 1 };
+//        buf_getcol(&TestBuf);
 //        CHECK(4 == TestBuf.selection.col);
-//        printf("%lu\n", TestBuf.selection.end);
-//        CHECK(5 == TestBuf.selection.end);
 //    }
 //
-//    TEST(buf_setcol should not set column past the last rune) {
-//        set_buffer_text("abc\n\tdef");
-//        TestBuf.selection = (Sel){ .end = 4, .col = 100 };
+//    TEST(buf_setcol should set the column to column 1 of second line)
+//    {
+//        set_buffer_text("abc\ndef");
+//        TestBuf.selection = (Sel){ .end = 4, .col = 0 };
 //        buf_setcol(&TestBuf);
-//        CHECK(100 == TestBuf.selection.col);
-//        printf("%lu\n", TestBuf.selection.end);
-//        CHECK(8 == TestBuf.selection.end);
+//        CHECK(0 == TestBuf.selection.col);
+//        CHECK(4 == TestBuf.selection.end);
 //    }
+//
+////    TEST(buf_setcol should set the column to column 2 of second line) {
+////        set_buffer_text("abc\ndef");
+////        TestBuf.selection = (Sel){ .end = 4, .col = 1 };
+////        buf_setcol(&TestBuf);
+////        CHECK(1 == TestBuf.selection.col);
+////        printf("%lu\n", TestBuf.selection.end);
+////        CHECK(5 == TestBuf.selection.end);
+////    }
+////
+////    TEST(buf_setcol should handle tabs) {
+////        set_buffer_text("abc\n\tdef");
+////        TestBuf.selection = (Sel){ .end = 4, .col = 4 };
+////        buf_setcol(&TestBuf);
+////        CHECK(4 == TestBuf.selection.col);
+////        printf("%lu\n", TestBuf.selection.end);
+////        CHECK(5 == TestBuf.selection.end);
+////    }
+////
+////    TEST(buf_setcol should not set column past the last rune) {
+////        set_buffer_text("abc\n\tdef");
+////        TestBuf.selection = (Sel){ .end = 4, .col = 100 };
+////        buf_setcol(&TestBuf);
+////        CHECK(100 == TestBuf.selection.col);
+////        printf("%lu\n", TestBuf.selection.end);
+////        CHECK(8 == TestBuf.selection.end);
+////    }
 
     /* Context-Sensitive Selection
      *************************************************************************/