}
}
-static void insert(Buf* buf, unsigned off, Rune rune) {
+static unsigned insert(Buf* buf, unsigned off, Rune rune) {
+ unsigned rcount = 1;
syncgap(buf, off);
- if (buf->crlf && rune == '\n' && buf_get(buf, off-1) == '\r')
+ if (buf->crlf && rune == '\n' && buf_get(buf, off-1) == '\r') {
+ rcount = 0;
*(buf->gapstart-1) = RUNE_CRLF;
- else
+ } else if (buf->crlf && rune == '\n') {
+ *(buf->gapstart++) = RUNE_CRLF;
+ } else {
*(buf->gapstart++) = rune;
+ }
+ return rcount;
}
static void clear_redo(Buf* buf) {
if (fmt && buf->expand_tabs && rune == '\t') {
size_t n = (TabWidth - ((off - buf_bol(buf, off)) % TabWidth));
log_insert(&(buf->undo), off, off+n);
- for(; n > 0; n--) insert(buf, off++, ' ');
+ for(; n > 0; n--) off += insert(buf, off, ' ');
} else {
- log_insert(&(buf->undo), off, off+1);
- insert(buf, off++, rune);
+ size_t n = insert(buf, off, rune);
+ log_insert(&(buf->undo), off, off+n);
+ off += n;
}
if (fmt && buf->copy_indent && (rune == '\n' || rune == RUNE_CRLF)) {
unsigned indent = getindent(buf, off-1);
} else {
newlog->insert = true;
newlog->data.ins.beg = log->data.del.off;
- newlog->data.ins.end = log->data.del.off + log->data.del.len;
+ newlog->data.ins.end = newlog->data.ins.beg;
+ //newlog->data.ins.end = log->data.del.off + log->data.del.len;
for (size_t i = log->data.del.len; i > 0; i--) {
- insert(buf, newlog->data.ins.beg, log->data.del.runes[i-1]);
+ newlog->data.ins.end += insert(buf, newlog->data.ins.beg, log->data.del.runes[i-1]);
}
pos = newlog->data.ins.end;
}
static Buf TestBuf;
-static void buf_clr(Buf* buf) {
- while (buf->undo) {
- Log* deadite = buf->undo;
- buf->undo = deadite->next;
- if (!deadite->insert)
- free(deadite->data.del.runes);
- free(deadite);
- }
- free(buf->bufstart);
- buf_init(buf);
-}
-
static void set_buffer_text(char* str) {
int i = 0;
- buf_clr(&TestBuf);
+ buf_init(&TestBuf);
TestBuf.crlf = 1;
for (Rune* curr = TestBuf.bufstart; curr < TestBuf.bufend; curr++)
*curr = '-';
}
TEST_SUITE(BufferTests) {
-#if 0
/* Initializing
*************************************************************************/
/* Loading
/* Insertions
*************************************************************************/
TEST(buf_ins should insert at 0 in empty buf) {
- buf_clr(&TestBuf);
+ buf_init(&TestBuf);
buf_ins(&TestBuf, false, 0, 'a');
CHECK(buf_text_eq("a"));
}
TEST(buf_ins should insert at 0) {
- buf_clr(&TestBuf);
+ buf_init(&TestBuf);
buf_ins(&TestBuf, false, 0, 'b');
buf_ins(&TestBuf, false, 0, 'a');
CHECK(buf_text_eq("ab"));
}
TEST(buf_ins should insert at 1) {
- buf_clr(&TestBuf);
+ buf_init(&TestBuf);
buf_ins(&TestBuf, false, 0, 'a');
buf_ins(&TestBuf, false, 1, 'b');
CHECK(buf_text_eq("ab"));
}
TEST(buf_ins should insert at 1) {
- buf_clr(&TestBuf);
+ buf_init(&TestBuf);
buf_ins(&TestBuf, false, 0, 'a');
buf_ins(&TestBuf, false, 1, 'c');
buf_ins(&TestBuf, false, 1, 'b');
set_buffer_text("abc\n\tdef");
CHECK(8 == buf_setcol(&TestBuf, 4, 100));
}
-#endif
}
key_handler(mods, key);
}
+bool verify_text(enum RegionId id, char* text) {
+ Sel sel = { .beg = 0, .end = buf_end(getbuf(id)) };
+ char* buftext = view_getstr(getview(id), &sel);
+ bool result = (0 == strcmp(buftext, text));
+ printf("'%s'\n", buftext);
+ free(buftext);
+ return result;
+}
+
/* Stubbed Functions
*****************************************************************************/
bool x11_keymodsset(int mask) {
/* Unit Tests
*****************************************************************************/
TEST_SUITE(XeditTests) {
+ /* Key Handling - Normal Input
+ *************************************************************************/
+ TEST(input not matching a shortcut should be inserted as text) {
+ setup_view(EDIT, "", 0);
+ send_keys(ModNone, 'e');
+ CHECK(getsel(EDIT)->beg == 1);
+ CHECK(getsel(EDIT)->end == 1);
+ }
+
/* Key Handling - Cursor Movement - Basic
*************************************************************************/
TEST(left should do nothing for empty buffer) {
CHECK(getsel(EDIT)->end == 2);
}
- /* Key Handling - Unix Standard Shortcuts
+ /* Key Handling - Unix Editing Shortcuts
*************************************************************************/
TEST(ctrl+u should do nothing for empty buffer) {
setup_view(EDIT, "", 0);
CHECK(getsel(EDIT)->end == 2);
}
- /* Key Handling - Normal Input
+ /* Key Handling - Standard Text Editing Shortcuts
*************************************************************************/
- TEST(input not matching a shortcut should be inserted as text) {
+ TEST(cut and paste should delete selection and transfer it to+from the system clipboard) {
+ setup_view(EDIT, "foo\nbar\nbaz\n", 0);
+ CHECK(RUNE_CRLF == buf_get(getbuf(EDIT), 3));
+ getview(EDIT)->selection = (Sel){ 0, 8, 0 };
+ send_keys(ModCtrl, 'x');
+ getview(EDIT)->selection = (Sel){ 4, 4, 0 };
+ send_keys(ModCtrl, 'v');
+ CHECK(getsel(EDIT)->beg == 12);
+ CHECK(getsel(EDIT)->end == 12);
+ CHECK(verify_text(EDIT, "baz\r\nfoo\r\nbar\r\n"));
+ }
+
+ TEST(copy and paste should copy selection and transfer it to+from the system clipboard) {
+ getbuf(EDIT)->crlf = 1;
+ setup_view(EDIT, "foo\nbar\nbaz\n", 0);
+ CHECK(RUNE_CRLF == buf_get(getbuf(EDIT), 3));
+ getview(EDIT)->selection = (Sel){ 0, 8, 0 };
+ send_keys(ModCtrl, 'c');
+ getview(EDIT)->selection = (Sel){ 12, 12, 0 };
+ send_keys(ModCtrl, 'v');
+ CHECK(getsel(EDIT)->beg == 20);
+ CHECK(getsel(EDIT)->end == 20);
+ CHECK(verify_text(EDIT, "foo\r\nbar\r\nbaz\r\nfoo\r\nbar\r\n"));
+ }
+
+ /* Key Handling - Block Indent
+ *************************************************************************/
+ TEST(ctrl+[ should do nothing on empty buffer) {
setup_view(EDIT, "", 0);
- send_keys(ModNone, 'e');
- CHECK(getsel(EDIT)->beg == 1);
- CHECK(getsel(EDIT)->end == 1);
+ send_keys(ModCtrl, '[');
+ CHECK(getsel(EDIT)->beg == 0);
+ CHECK(getsel(EDIT)->end == 0);
+ }
+
+ //TEST(ctrl+[ should do nothing on empty buffer) {
+ // setup_view(EDIT, "a", 0);
+ // send_keys(ModCtrl, '[');
+ // CHECK(getsel(EDIT)->beg == 0);
+ // CHECK(getsel(EDIT)->end == 0);
+ //}
+
+ TEST(ctrl+] should do nothing on empty buffer) {
+ setup_view(EDIT, "", 0);
+ send_keys(ModCtrl, ']');
+ CHECK(getsel(EDIT)->beg == 0);
+ CHECK(getsel(EDIT)->end == 0);
}
+ //TEST(ctrl+] should indent the current line) {
+ // setup_view(EDIT, "a", 0);
+ // send_keys(ModCtrl, ']');
+ // CHECK(getsel(EDIT)->beg == 0);
+ // CHECK(getsel(EDIT)->end == 0);
+ //}
+
+ /* Key Handling - Special Keys
+ *************************************************************************/
+
/* Key Handling - Implementation Specific
*************************************************************************/
TEST(ctrl+t should switch focus to EDIT view) {