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);
+ }
+}
#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)
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));
}
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
*************************************************************************/