From 4cdba7b8f6b9a1f1c6fbc4b3151fd559a1268107 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 9 Apr 2018 16:23:10 -0400 Subject: [PATCH] removed unused functions --- inc/edit.h | 3 - inc/utf.h | 4 - lib/buf.c | 13 +- lib/utf8.c | 29 +- lib/utils.c | 29 -- lib/x11.c | 19 +- tests/tide.c | 988 --------------------------------------------------- tide.c | 5 +- 8 files changed, 28 insertions(+), 1062 deletions(-) delete mode 100644 tests/tide.c diff --git a/inc/edit.h b/inc/edit.h index 8d3fa5e..3354d06 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -1,9 +1,6 @@ /* Utility Functions *****************************************************************************/ -size_t pagealign(size_t sz); -uint64_t getmillis(void); char* stringdup(const char* str); -uint64_t modtime(char* path); char* strmcat(char* first, ...); /* Buffer management functions diff --git a/inc/utf.h b/inc/utf.h index 3a8a74e..31660af 100644 --- a/inc/utf.h +++ b/inc/utf.h @@ -11,11 +11,7 @@ typedef int32_t Rune; size_t utf8encode(char str[UTF_MAX], Rune rune); bool utf8decode(Rune* rune, size_t* length, int byte); -Rune fgetrune(FILE* f); -void fputrune(Rune rune, FILE* f); int runewidth(unsigned col, Rune r); -size_t rstrlen(Rune* runes); -Rune* charstorunes(char* str); bool risword(Rune r); bool rissigil(Rune r); bool risfile(Rune r); diff --git a/lib/buf.c b/lib/buf.c index 84713ae..64c8385 100644 --- a/lib/buf.c +++ b/lib/buf.c @@ -14,6 +14,7 @@ static int bytes_match(Buf* buf, size_t mbeg, size_t mend, char* str); static Rune nextrune(Buf* buf, size_t off, int move, bool (*testfn)(Rune)); static void selline(Buf* buf); static void selblock(Buf* buf, Rune first, Rune last); +static size_t pagealign(size_t sz); void buf_init(Buf* buf) { /* cleanup old data if there is any */ @@ -40,7 +41,7 @@ void buf_load(Buf* buf, char* path) { /* process the file path and address */ if (path[0] == '.' && path[1] == '/') path += 2; - buf->path = stringdup(path); + buf->path = strdup(path); /* load the contents from the file */ int fd, nread; @@ -61,7 +62,7 @@ void buf_load(Buf* buf, char* path) { /* reset buffer state */ buf->modified = false; - buf->modtime = modtime(buf->path); + buf->modtime = (uint64_t)sb.st_mtime; buf_logclear(buf); } @@ -478,3 +479,11 @@ static void selblock(Buf* buf, Rune first, Rune last) { if (end > beg) beg++; else end++; buf->selection.beg = beg, buf->selection.end = end; } + +static size_t pagealign(size_t sz) { + size_t pgsize = sysconf(_SC_PAGE_SIZE), alignmask = pgsize - 1; + if (sz & alignmask) + sz += pgsize - (sz & alignmask); + return sz; +} + diff --git a/lib/utf8.c b/lib/utf8.c index 28e8bfd..dc095ac 100644 --- a/lib/utf8.c +++ b/lib/utf8.c @@ -5,9 +5,9 @@ #include #include -const uint8_t UTF8_SeqBits[] = { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE }; -const uint8_t UTF8_SeqMask[] = { 0x00, 0xFF, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00 }; -const uint8_t UTF8_SeqLens[] = { 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00 }; +static const uint8_t UTF8_SeqBits[] = { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE }; +static const uint8_t UTF8_SeqMask[] = { 0x00, 0xFF, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00 }; +static const uint8_t UTF8_SeqLens[] = { 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00 }; static bool runevalid(Rune val) { return (val <= RUNE_MAX) @@ -82,29 +82,6 @@ int runewidth(unsigned col, Rune r) { return width; } -size_t rstrlen(Rune* runes) { - size_t len = 0; - for (; runes[len]; len++); - return len; -} - -Rune* charstorunes(char* str) { - size_t len = 0; - Rune* runes = NULL; - while (str && *str) { - Rune rune = 0; - size_t length = 0; - while (!utf8decode(&rune, &length, *str++)); - runes = realloc(runes, (len + 1) * sizeof(Rune)); - runes[len++] = rune; - } - if (runes) { - runes = realloc(runes, (len + 1) * sizeof(Rune)); - runes[len++] = '\0'; - } - return runes; -} - bool risword(Rune r) { return (r < 127 && (isalnum(r) || r == '_')); } diff --git a/lib/utils.c b/lib/utils.c index deafb56..b44127e 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -10,21 +10,6 @@ #include #include -size_t pagealign(size_t sz) { - size_t pgsize = sysconf(_SC_PAGE_SIZE), alignmask = pgsize - 1; - if (sz & alignmask) - sz += pgsize - (sz & alignmask); - return sz; -} - -uint64_t getmillis(void) { - struct timespec time; - clock_gettime(CLOCK_MONOTONIC, &time); - uint64_t ms = ((uint64_t)time.tv_sec * (uint64_t)1000); - ms += ((uint64_t)time.tv_nsec / (uint64_t)1000000); - return ms; -} - void die(const char* msgfmt, ...) { va_list args; va_start(args, msgfmt); @@ -37,20 +22,6 @@ void die(const char* msgfmt, ...) { exit(EXIT_FAILURE); } -char* stringdup(const char* s) { - char* ns = (char*)malloc(strlen(s) + 1); - assert(ns); - strcpy(ns,s); - return ns; -} - -uint64_t modtime(char* path) { - struct stat status; - if (stat(path, &status) < 0) - return 0u; - return (uint64_t)status.st_mtime; -} - char* strmcat(char* first, ...) { va_list args; /* calculate the length of the final string */ diff --git a/lib/x11.c b/lib/x11.c index ce4ef1c..c33d098 100644 --- a/lib/x11.c +++ b/lib/x11.c @@ -86,6 +86,7 @@ struct XFont { }; static struct { + Time now; Window root; Display* display; Visual* visual; @@ -142,7 +143,7 @@ void win_save(char* path) { View* view = win_view(EDIT); if (!path) path = view->buffer.path; if (!path) return; - path = stringdup(path); + path = strdup(path); free(view->buffer.path); view->buffer.path = path; buf_save(&(view->buffer)); @@ -178,10 +179,9 @@ Buf* win_buf(WinRegion id) { void win_quit(void) { static uint64_t before = 0; - uint64_t now = getmillis(); - if (!win_buf(EDIT)->modified || (now-before) <= (uint64_t)ClickTime) + if (!win_buf(EDIT)->modified || (X.now - before) <= (uint64_t)ClickTime) exit(0); - before = now; + before = X.now; } /******************************************************************************/ @@ -493,6 +493,7 @@ static void xfocus(XEvent* e) { } static void xkeypress(XEvent* e) { + X.now = e->xkey.time; win_setregion(getregion(e->xkey.x, e->xkey.y)); uint32_t key = getkey(e); if (key == RUNE_ERR) return; @@ -516,16 +517,19 @@ static void xkeypress(XEvent* e) { } static void xbtnpress(XEvent* e) { + X.now = e->xbutton.time; KeyBtnState = (e->xbutton.state | (1 << (e->xbutton.button + 7))); mouse_click(e->xbutton.button, true, e->xbutton.x, e->xbutton.y); } static void xbtnrelease(XEvent* e) { + X.now = e->xbutton.time; KeyBtnState = (e->xbutton.state & ~(1 << (e->xbutton.button + 7))); mouse_click(e->xbutton.button, false, e->xbutton.x, e->xbutton.y); } static void xbtnmotion(XEvent* e) { + X.now = e->xbutton.time; size_t row, col; KeyBtnState = e->xbutton.state; int x = e->xbutton.x, y = e->xbutton.y; @@ -660,11 +664,10 @@ static void mouse_click(int btn, bool pressed, int x, int y) { static void mouse_left(WinRegion id, bool pressed, size_t row, size_t col) { static int count = 0; - static uint64_t before = 0; + static Time before = 0; if (!pressed) return; - uint64_t now = getmillis(); - count = ((now-before) <= (uint64_t)ClickTime ? count+1 : 1); - before = now; + count = ((X.now - before) <= (uint64_t)ClickTime ? count+1 : 1); + before = X.now; if (win_btnpressed(MouseRight)) { puts("fetch tag"); } else if (win_btnpressed(MouseMiddle)) { diff --git a/tests/tide.c b/tests/tide.c deleted file mode 100644 index 2416477..0000000 --- a/tests/tide.c +++ /dev/null @@ -1,988 +0,0 @@ -#define INCLUDE_DEFS -#include -#include -#include -#include -#include - -void x11_handle_event(XEvent* e); - -enum { - LF = 0, - CRLF = 1 -}; - -// Test Globals -bool ExitExpected = false; -int ExitCode = 0; -jmp_buf ExitPad; -Display* XDisplay; - -// Include the source file so we can access everything -#include "../tide.c" - -static void initialize(void) { - ShellCmd[0] = "/bin/sh"; - win_window("edit", false, ondiagmsg); - XDisplay = XOpenDisplay(NULL); - win_setkeys(Bindings, NULL); -} - -/* Helper Functions - *****************************************************************************/ -#define EXPECT_EXIT \ - if ((ExitExpected = true, 0 == setjmp(ExitPad))) - -void setup_view(WinRegion id, char* text, int crlf, unsigned cursor) { - win_setregion(id); - win_buf(id)->crlf = crlf; - win_settext(id, text); - win_sel(id)->beg = cursor; - win_sel(id)->end = cursor; - win_sel(id)->col = buf_getcol(win_buf(id), win_sel(id)->end); -} - -void insert(WinRegion id, char* text) { - view_putstr(win_view(id), text); -} - -void send_keys(uint mods, uint key) { - XEvent e; - e.xkey.display = XDisplay, - e.xkey.type = KeyPress, - e.xkey.state = mods, - e.xkey.keycode = XKeysymToKeycode(XDisplay, key), - x11_handle_event(&e); -} - -bool verify_text(WinRegion id, char* text) { - Sel sel = { .beg = 0, .end = buf_end(win_buf(id)) }; - char* buftext = view_getstr(win_view(id), &sel); - //printf("buftext: '%s'\n", buftext); - bool result; - if (buftext == NULL) - result = (*text == '\0'); - else - result = (0 == strcmp(buftext, text)); - free(buftext); - return result; -} - -/* Unit Tests - *****************************************************************************/ -TEST_SUITE(UnitTests) { - /* Key Handling - Normal Input - *************************************************************************/ - TEST(input not matching a shortcut should be inserted as text) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModNone, XK_e); - verify_text(EDIT, "e"); - CHECK(win_sel(EDIT)->beg == 1); - CHECK(win_sel(EDIT)->end == 1); - } - - TEST(input \n should result in RUNE_CRLF if in crlf mode) { - setup_view(EDIT, "", CRLF, 0); - win_buf(EDIT)->crlf = 1; - send_keys(ModNone, XK_Return); - CHECK(win_sel(EDIT)->beg == 1); - CHECK(win_sel(EDIT)->end == 1); - CHECK(RUNE_CRLF == buf_get(win_buf(EDIT), 0)); - } - - TEST(input \n chould result in \n if not in crlf mode) { - setup_view(EDIT, "", CRLF, 0); - win_buf(EDIT)->crlf = 0; - send_keys(ModNone, XK_Return); - CHECK(win_sel(EDIT)->beg == 1); - CHECK(win_sel(EDIT)->end == 1); - CHECK('\n' == buf_get(win_buf(EDIT), 0)); - } - /* Key Handling - Cursor Movement - Basic - *************************************************************************/ - TEST(left should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModNone, XK_Left); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+left should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModCtrl, XK_Left); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(left should do nothing at beginning of buffer) { - setup_view(EDIT, "AB", CRLF, 0); - send_keys(ModNone, XK_Left); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+left should do nothing at beginning of buffer) { - setup_view(EDIT, "AB", CRLF, 0); - send_keys(ModCtrl, XK_Left); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+left should move left by one word) { - setup_view(EDIT, "AB CD", CRLF, 3); - send_keys(ModCtrl, XK_Left); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(left should move left by one rune) { - setup_view(EDIT, "AB", CRLF, 1); - send_keys(ModNone, XK_Left); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(right should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModNone, XK_Right); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(right should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModCtrl, XK_Right); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+right should do nothing at end of buffer) { - setup_view(EDIT, "AB", CRLF, 2); - send_keys(ModNone, XK_Right); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 2); - } - - TEST(ctrl+right should do nothing at end of buffer) { - setup_view(EDIT, "AB", CRLF, 2); - send_keys(ModCtrl, XK_Right); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 2); - } - - TEST(ctrl+right should move right by one word) { - setup_view(EDIT, "AB CD", CRLF, 0); - send_keys(ModCtrl, XK_Right); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 2); - } - - TEST(right should move right by one rune) { - setup_view(EDIT, "AB", CRLF, 1); - send_keys(ModNone, XK_Right); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 2); - } - - TEST(up should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModNone, XK_Up); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(up should move cursor up one line) { - setup_view(EDIT, "AB\nCD", CRLF, 4); - send_keys(ModNone, XK_Up); - CHECK(win_sel(EDIT)->beg == 1); - CHECK(win_sel(EDIT)->end == 1); - } - - TEST(up should do nothing for first line) { - setup_view(EDIT, "AB\nCD", CRLF, 1); - send_keys(ModNone, XK_Up); - CHECK(win_sel(EDIT)->beg == 1); - CHECK(win_sel(EDIT)->end == 1); - } - - TEST(down should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModNone, XK_Down); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(down should move down one line) { - setup_view(EDIT, "AB\nCD", CRLF, 1); - send_keys(ModNone, XK_Down); - CHECK(win_sel(EDIT)->beg == 4); - CHECK(win_sel(EDIT)->end == 4); - } - - TEST(down should do nothing on last line) { - setup_view(EDIT, "AB\nCD", CRLF, 4); - send_keys(ModNone, XK_Down); - CHECK(win_sel(EDIT)->beg == 4); - CHECK(win_sel(EDIT)->end == 4); - } - - TEST(home should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModNone, XK_Home); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+home should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModCtrl, XK_Home); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+home should move to beginning of buffer) { - setup_view(EDIT, "ABCD", CRLF, 4); - send_keys(ModCtrl, XK_Home); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(home should move to beginning of indented content) { - setup_view(EDIT, " ABCD", CRLF, 7); - send_keys(ModNone, XK_Home); - CHECK(win_sel(EDIT)->beg == 4); - CHECK(win_sel(EDIT)->end == 4); - } - - TEST(home should move to beginning of line if at beginning of indented content) { - setup_view(EDIT, " ABCD", CRLF, 7); - send_keys(ModNone, XK_Home); - CHECK(win_sel(EDIT)->beg == 4); - CHECK(win_sel(EDIT)->end == 4); - } - - TEST(home should move to beginning of indented content when at beginning of line) { - setup_view(EDIT, " ABCD", CRLF, 0); - send_keys(ModNone, XK_Home); - CHECK(win_sel(EDIT)->beg == 4); - CHECK(win_sel(EDIT)->end == 4); - } - - TEST(end should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModNone, XK_End); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+end should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModCtrl, XK_End); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+end should move to end of buffer) { - setup_view(EDIT, "ABCD", CRLF, 0); - send_keys(ModCtrl, XK_End); - CHECK(win_sel(EDIT)->beg == 4); - CHECK(win_sel(EDIT)->end == 4); - } - - TEST(end should do nothing at end of line) { - setup_view(EDIT, "AB\nCD", CRLF, 2); - send_keys(ModNone, XK_End); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 2); - } - - TEST(end should move to end of line) { - setup_view(EDIT, "AB\nCD", CRLF, 0); - send_keys(ModNone, XK_End); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 2); - } - - /* Key Handling - Unix Editing Shortcuts - *************************************************************************/ - TEST(ctrl+u should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModCtrl, XK_u); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+u should delete to beginning of line) { - setup_view(EDIT, "\nABC\n", CRLF, 2); - send_keys(ModCtrl, XK_u); - CHECK(win_sel(EDIT)->beg == 1); - CHECK(win_sel(EDIT)->end == 1); - CHECK(buf_end(win_buf(EDIT)) == 4); - } - - TEST(ctrl+u should delete entire lines contents) { - setup_view(EDIT, "\nABC\n", CRLF, 3); - send_keys(ModCtrl, XK_u); - CHECK(win_sel(EDIT)->beg == 1); - CHECK(win_sel(EDIT)->end == 1); - CHECK(buf_end(win_buf(EDIT)) == 3); - } - - TEST(ctrl+k should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModCtrl, XK_k); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - CHECK(buf_end(win_buf(EDIT)) == 0); - } - - TEST(ctrl+k should delete to end of line) { - setup_view(EDIT, "\nABC\n", CRLF, 2); - send_keys(ModCtrl, XK_k); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 2); - CHECK(buf_end(win_buf(EDIT)) == 3); - } - - TEST(ctrl+k should delete entire lines contents) { - setup_view(EDIT, "\nABC\n", CRLF, 1); - send_keys(ModCtrl, XK_k); - CHECK(win_sel(EDIT)->beg == 1); - CHECK(win_sel(EDIT)->end == 1); - CHECK(buf_end(win_buf(EDIT)) == 2); - } - - TEST(ctrl+w should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModCtrl, XK_w); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - CHECK(buf_end(win_buf(EDIT)) == 0); - } - - TEST(ctrl+w should delete previous word) { - setup_view(EDIT, "abc def", CRLF, 4); - send_keys(ModCtrl, XK_w); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - CHECK(buf_end(win_buf(EDIT)) == 3); - } - - TEST(ctrl+a should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModCtrl, XK_a); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+a should move to beginning of indented content) { - setup_view(EDIT, " ABCD", CRLF, 7); - send_keys(ModCtrl, XK_a); - CHECK(win_sel(EDIT)->beg == 4); - CHECK(win_sel(EDIT)->end == 4); - } - - TEST(ctrl+a should move to beginning of line if at beginning of indented content) { - setup_view(EDIT, " ABCD", CRLF, 7); - send_keys(ModCtrl, XK_a); - CHECK(win_sel(EDIT)->beg == 4); - CHECK(win_sel(EDIT)->end == 4); - } - - TEST(ctrl+a should move to beginning of indented content when at beginning of line) { - setup_view(EDIT, " ABCD", CRLF, 0); - send_keys(ModCtrl, XK_a); - CHECK(win_sel(EDIT)->beg == 4); - CHECK(win_sel(EDIT)->end == 4); - } - - TEST(ctrl+e should do nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModCtrl, XK_e); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+e should do nothing at end of line) { - setup_view(EDIT, "AB\nCD", CRLF, 2); - send_keys(ModCtrl, XK_e); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 2); - } - - TEST(ctrl+e should move to end of line) { - setup_view(EDIT, "AB\nCD", CRLF, 0); - send_keys(ModCtrl, XK_e); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 2); - } - - TEST(esc should select previously inserted text) { - setup_view(EDIT, "", CRLF, 0); - insert(EDIT, "foo"); - win_view(EDIT)->selection = (Sel) {0,0,0}; - send_keys(ModNone, XK_Escape); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 3); - } - - TEST(esc should select previously edited text) { - setup_view(EDIT, "foo", CRLF, 0); - insert(EDIT, "foob"); - win_view(EDIT)->selection = (Sel) {4,4,4}; - send_keys(ModNone, XK_BackSpace); - send_keys(ModNone, XK_Escape); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 3); - } - - /* Key Handling - Standard Text Editing Shortcuts - *************************************************************************/ - TEST(cut and paste should delete selection and transfer it to+from the system clipboard) { - IGNORE("paste callback isn't happening"); - setup_view(EDIT, "foo\nbar\nbaz\n", CRLF, 0); - win_view(EDIT)->selection = (Sel){ 0, 8, 0 }; - send_keys(ModCtrl, XK_x); - win_view(EDIT)->selection = (Sel){ 4, 4, 0 }; - send_keys(ModCtrl, XK_v); - CHECK(win_sel(EDIT)->beg == 4); - CHECK(win_sel(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) { - IGNORE("paste callback isn't happening"); - win_buf(EDIT)->crlf = 1; - setup_view(EDIT, "foo\nbar\nbaz\n", CRLF, 0); - win_view(EDIT)->selection = (Sel){ 0, 8, 0 }; - send_keys(ModCtrl, XK_c); - win_view(EDIT)->selection = (Sel){ 12, 12, 0 }; - send_keys(ModCtrl, XK_v); - CHECK(win_sel(EDIT)->beg == 12); - CHECK(win_sel(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, "", CRLF, 0); - send_keys(ModCtrl, XK_bracketleft); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+[ should do nothing at beginning of buffer) { - setup_view(EDIT, "a", CRLF, 0); - send_keys(ModCtrl, XK_bracketleft); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 1); - } - - TEST(ctrl+] should do nothing on empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModCtrl, XK_bracketright); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+] should indent the first line) { - setup_view(EDIT, "a", CRLF, 0); - send_keys(ModCtrl, XK_bracketright); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 5); - CHECK(verify_text(EDIT, " a")); - } - - /* Key Handling - Special - *************************************************************************/ - TEST(backspace should do nothing on empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModNone, XK_BackSpace); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - CHECK(verify_text(EDIT, "")); - } - - TEST(backspace should do nothing at beginning of buffer) { - setup_view(EDIT, "abc", CRLF, 0); - send_keys(ModNone, XK_BackSpace); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - CHECK(verify_text(EDIT, "abc")); - } - - TEST(backspace should delete previous character) { - setup_view(EDIT, "abc", CRLF, 1); - send_keys(ModNone, XK_BackSpace); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - CHECK(verify_text(EDIT, "bc")); - } - - TEST(backspace should delete selection) { - setup_view(EDIT, "abcde", CRLF, 0); - win_view(EDIT)->selection = (Sel){ .beg = 1, .end = 4 }; - send_keys(ModNone, XK_BackSpace); - CHECK(win_sel(EDIT)->beg == 1); - CHECK(win_sel(EDIT)->end == 1); - CHECK(verify_text(EDIT, "ae")); - } - - TEST(delete should do nothing on empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModNone, XK_Delete); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - CHECK(verify_text(EDIT, "")); - } - - TEST(delete should do nothing at end of buffer) { - setup_view(EDIT, "abc", CRLF, 3); - send_keys(ModNone, XK_Delete); - CHECK(win_sel(EDIT)->beg == 3); - CHECK(win_sel(EDIT)->end == 3); - CHECK(verify_text(EDIT, "abc")); - } - - TEST(delete should delete next character) { - setup_view(EDIT, "abc", CRLF, 2); - send_keys(ModNone, XK_Delete); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 2); - CHECK(verify_text(EDIT, "ab")); - } - - TEST(delete should delete selection) { - setup_view(EDIT, "abcde", CRLF, 0); - win_view(EDIT)->selection = (Sel){ .beg = 1, .end = 4 }; - send_keys(ModNone, XK_Delete); - CHECK(win_sel(EDIT)->beg == 1); - CHECK(win_sel(EDIT)->end == 1); - CHECK(verify_text(EDIT, "ae")); - } - - /* Key Handling - Implementation Specific - *************************************************************************/ - TEST(ctrl+t should switch focus to EDIT view) { - win_setregion(TAGS); - send_keys(ModCtrl, XK_t); - CHECK(win_getregion() == EDIT); - } - - TEST(ctrl+t should switch focus to TAGs view) { - win_setregion(EDIT); - send_keys(ModCtrl, XK_t); - CHECK(win_getregion() == TAGS); - } - - TEST(ctrl+q should quit) { - setup_view(TAGS, "", CRLF, 0); - setup_view(EDIT, "", CRLF, 0); - win_buf(EDIT)->modified = false; - ExitCode = 42; - EXPECT_EXIT { - send_keys(ModCtrl, XK_q); - } - ExitExpected = false; - CHECK(ExitCode == 0); - CHECK(verify_text(TAGS, "")); - } - - TEST(ctrl+f should find next occurrence of selected text) { - setup_view(EDIT, "foobarfoo", CRLF, 0); - win_view(EDIT)->selection = (Sel){ 0, 3, 0 }; - send_keys(ModCtrl, XK_f); - CHECK(win_view(EDIT)->selection.beg == 6); - CHECK(win_view(EDIT)->selection.end == 9); - } - - TEST(ctrl+f should wrap around to beginning of buffer) { - setup_view(EDIT, "foobarbazfoo", CRLF, 0); - win_view(EDIT)->selection = (Sel){ 9, 12, 0 }; - send_keys(ModCtrl, XK_f); - CHECK(win_view(EDIT)->selection.beg == 0); - CHECK(win_view(EDIT)->selection.end == 3); - } - - TEST(ctrl+h should nothing for empty buffer) { - setup_view(EDIT, "", CRLF, 0); - send_keys(ModCtrl, XK_h); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 0); - } - - TEST(ctrl+h should highlight content in parens from left paren) { - setup_view(EDIT, " (foo bar) ", CRLF, 1); - send_keys(ModCtrl, XK_h); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 9); - } - - TEST(ctrl+h should highlight content in parens from right paren) { - setup_view(EDIT, " (foo bar) ", CRLF, 9); - send_keys(ModCtrl, XK_h); - CHECK(win_sel(EDIT)->beg == 9); - CHECK(win_sel(EDIT)->end == 2); - } - - TEST(ctrl+h should highlight content in parens from left bracket) { - setup_view(EDIT, " [foo bar] ", CRLF, 1); - send_keys(ModCtrl, XK_h); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 9); - } - - TEST(ctrl+h should highlight content in parens from right bracket) { - setup_view(EDIT, " [foo bar] ", CRLF, 9); - send_keys(ModCtrl, XK_h); - CHECK(win_sel(EDIT)->beg == 9); - CHECK(win_sel(EDIT)->end == 2); - } - - TEST(ctrl+h should highlight content in parens from left brace) { - setup_view(EDIT, " {foo bar} ", CRLF, 1); - send_keys(ModCtrl, XK_h); - CHECK(win_sel(EDIT)->beg == 2); - CHECK(win_sel(EDIT)->end == 9); - } - - TEST(ctrl+h should highlight content in parens from right brace) { - setup_view(EDIT, " {foo bar} ", CRLF, 9); - send_keys(ModCtrl, XK_h); - CHECK(win_sel(EDIT)->beg == 9); - CHECK(win_sel(EDIT)->end == 2); - } - - TEST(ctrl+h should highlight whole line from bol) { - setup_view(EDIT, "foo bar\n", CRLF, 0); - send_keys(ModCtrl, XK_h); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 8); - } - - TEST(ctrl+h should highlight whole line from eol) { - setup_view(EDIT, "foo bar\n", CRLF, 7); - send_keys(ModCtrl, XK_h); - CHECK(win_sel(EDIT)->beg == 0); - CHECK(win_sel(EDIT)->end == 8); - } - - TEST(ctrl+h should highlight word under cursor) { - setup_view(EDIT, " foo.bar \n", CRLF, 1); - send_keys(ModCtrl, XK_h); - CHECK(win_sel(EDIT)->beg == 1); - CHECK(win_sel(EDIT)->end == 4); - } - - TEST(ctrl+h should highlight word under cursor) { - setup_view(EDIT, " foo.bar \n", CRLF, 4); - send_keys(ModCtrl, XK_h); - CHECK(win_sel(EDIT)->beg == 1); - CHECK(win_sel(EDIT)->end == 8); - } - - /* Mouse Input Handling - *************************************************************************/ - - /* Command Execution - *************************************************************************/ - TEST(Commands starting with : should be executed as sed scripts) { - setup_view(EDIT, "foo", CRLF, 0); - win_view(EDIT)->selection = (Sel){ .beg = 0, .end = 3 }; - setup_view(TAGS, ":s/foo/bar/", CRLF, 0); - win_view(TAGS)->selection = (Sel){ .beg = 0, .end = 11 }; - send_keys(ModCtrl, XK_d); - do { event_poll(50); } while (exec_reap()); - #ifdef __MACH__ - CHECK(verify_text(EDIT, "bar\r\n")); - #else - CHECK(verify_text(EDIT, "bar")); - #endif - } - - TEST(Commands starting with | should take selection as input and replace it with output) { - setup_view(EDIT, "foo", CRLF, 0); - win_view(EDIT)->selection = (Sel){ .beg = 0, .end = 3 }; - setup_view(TAGS, "|sed -e 's/foo/bar/'", CRLF, 0); - win_view(TAGS)->selection = (Sel){ .beg = 0, .end = 20 }; - send_keys(ModCtrl, XK_d); - do { event_poll(50); } while (exec_reap()); - #ifdef __MACH__ - CHECK(verify_text(EDIT, "bar\r\n")); - #else - CHECK(verify_text(EDIT, "bar")); - #endif - } - - TEST(Commands starting with ! should execute in the background with no input or output) { - setup_view(EDIT, "foo", CRLF, 0); - win_view(EDIT)->selection = (Sel){ .beg = 0, .end = 3 }; - setup_view(TAGS, "!ls", CRLF, 0); - win_view(TAGS)->selection = (Sel){ .beg = 0, .end = 3 }; - send_keys(ModCtrl, XK_d); - do { event_poll(50); } while (exec_reap()); - CHECK(verify_text(EDIT, "foo")); - } - - TEST(Commands starting with > should execute in the background with selection as input) { - setup_view(EDIT, "foo", CRLF, 0); - win_view(EDIT)->selection = (Sel){ .beg = 0, .end = 3 }; - setup_view(TAGS, ">cat", CRLF, 0); - win_view(TAGS)->selection = (Sel){ .beg = 0, .end = 4 }; - send_keys(ModCtrl, XK_d); - do { event_poll(50); } while (exec_reap()); - CHECK(verify_text(EDIT, "foo")); - } - - TEST(Commands starting with < should replace selection with output) { - setup_view(EDIT, "foo", CRLF, 0); - win_view(EDIT)->selection = (Sel){ .beg = 0, .end = 3 }; - setup_view(TAGS, "selection = (Sel){ .beg = 0, .end = 9 }; - send_keys(ModCtrl, XK_d); - do { event_poll(50); } while (exec_reap()); - CHECK(verify_text(EDIT, "bar\r\n")); - } - - TEST(Commands not starting with a sigil should replace themselves with their output) { - setup_view(EDIT, "echo foo", CRLF, 0); - win_view(EDIT)->selection = (Sel){ .beg = 0, .end = 8 }; - send_keys(ModCtrl, XK_d); - do { event_poll(50); } while (exec_reap()); - CHECK(verify_text(EDIT, "foo\r\n")); - } - - /* Tag Handling - *************************************************************************/ - TEST(Quit should quit immediately if buffer is unmodified) { - setup_view(TAGS, "", CRLF, 0); - setup_view(EDIT, "", CRLF, 0); - win_buf(EDIT)->modified = false; - ExitCode = 42; - EXPECT_EXIT { - exec("Quit"); - } - ExitExpected = false; - CHECK(ExitCode == 0); - CHECK(verify_text(TAGS, "")); - } - - TEST(Quit should display error message when quit called with unsaved changes) { - setup_view(TAGS, "", CRLF, 0); - setup_view(EDIT, "", CRLF, 0); - win_buf(EDIT)->modified = true; - ExitCode = 42; - usleep(251 * 1000); - exec("Quit"); - CHECK(ExitCode == 42); - CHECK(verify_text(TAGS, "File is modified. Repeat action twice quickly to quit.")); - } - - TEST(Quit should discard changes if quit executed twice in less than DblClickTime) { - setup_view(TAGS, "", CRLF, 0); - setup_view(EDIT, "", CRLF, 0); - win_buf(EDIT)->modified = true; - ExitCode = 42; - usleep((config_get_int(DblClickTime)+1) * 1000); - EXPECT_EXIT { - exec("Quit"); - CHECK(ExitCode == 42); - CHECK(verify_text(TAGS, "File is modified. Repeat action twice quickly to quit.")); - exec("Quit"); - } - ExitExpected = false; - CHECK(ExitCode == 0); - CHECK(verify_text(TAGS, "File is modified. Repeat action twice quickly to quit.")); - } - - TEST(Save should save changes to disk with crlf line endings) { - setup_view(TAGS, "", CRLF, 0); - view_init(win_view(EDIT), "testdocs/crlf.txt", ondiagmsg); - CHECK(verify_text(EDIT, "this file\r\nuses\r\ndos\r\nline\r\nendings\r\n")); - exec("Save"); - view_init(win_view(EDIT), "testdocs/crlf.txt", ondiagmsg); - CHECK(verify_text(EDIT, "this file\r\nuses\r\ndos\r\nline\r\nendings\r\n")); - } - - TEST(Save should save changes to disk with lf line endings) { - setup_view(TAGS, "", CRLF, 0); - view_init(win_view(EDIT), "testdocs/lf.txt", ondiagmsg); - CHECK(verify_text(EDIT, "this file\nuses\nunix\nline\nendings\n")); - exec("Save"); - view_init(win_view(EDIT), "testdocs/lf.txt", ondiagmsg); - CHECK(verify_text(EDIT, "this file\nuses\nunix\nline\nendings\n")); - } - - TEST(Cut and Paste tags should move selection to new location) { - IGNORE("paste callback isn't happening"); - setup_view(EDIT, "", CRLF, 0); - insert(EDIT, "foo\nbar\nbaz\n"); - win_view(EDIT)->selection = (Sel){ 0, 8, 0 }; - exec("Cut"); - win_view(EDIT)->selection = (Sel){ 4, 4, 0 }; - exec("Paste"); - CHECK(win_sel(EDIT)->beg == 4); - CHECK(win_sel(EDIT)->end == 12); - CHECK(verify_text(EDIT, "baz\r\nfoo\r\nbar\r\n")); - } - - TEST(Copy and Paste tags should copy selection to new location) { - IGNORE("paste callback isn't happening"); - setup_view(EDIT, "", CRLF, 0); - insert(EDIT, "foo\nbar\nbaz\n"); - win_view(EDIT)->selection = (Sel){ 0, 8, 0 }; - exec("Copy"); - win_view(EDIT)->selection = (Sel){ 12, 12, 0 }; - exec("Paste"); - CHECK(win_sel(EDIT)->beg == 12); - CHECK(win_sel(EDIT)->end == 20); - CHECK(verify_text(EDIT, "foo\r\nbar\r\nbaz\r\nfoo\r\nbar\r\n")); - } - - TEST(Undo+Redo should undo+redo the previous insert) { - setup_view(EDIT, "", CRLF, 0); - insert(EDIT, "foo"); - exec("Undo"); - CHECK(verify_text(EDIT, "")); - exec("Redo"); - CHECK(verify_text(EDIT, "foo")); - } - - TEST(Undo+Redo should undo+redo the previous delete) { - setup_view(EDIT, "foo", CRLF, 0); - win_view(EDIT)->selection = (Sel){ 0, 3, 0 }; - send_keys(ModNone, XK_Delete); - exec("Undo"); - CHECK(verify_text(EDIT, "foo")); - exec("Redo"); - CHECK(verify_text(EDIT, "")); - } - - TEST(Undo+Redo should undo+redo the previous delete with two non-contiguous deletes logged) { - setup_view(EDIT, "foobarbaz", CRLF, 0); - win_view(EDIT)->selection = (Sel){ 0, 3, 0 }; - send_keys(ModNone, XK_Delete); - win_view(EDIT)->selection = (Sel){ 3, 6, 0 }; - send_keys(ModNone, XK_Delete); - CHECK(verify_text(EDIT, "bar")); - exec("Undo"); - CHECK(verify_text(EDIT, "barbaz")); - exec("Redo"); - CHECK(verify_text(EDIT, "bar")); - } - - TEST(Undo+Redo should undo+redo the previous delete performed with backspace) { - setup_view(EDIT, "foo", CRLF, 0); - win_view(EDIT)->selection = (Sel){ 3, 3, 0 }; - for(int i = 0; i < 3; i++) - send_keys(ModNone, XK_BackSpace); - CHECK(verify_text(EDIT, "")); - exec("Undo"); - CHECK(verify_text(EDIT, "foo")); - exec("Redo"); - CHECK(verify_text(EDIT, "")); - } - - - TEST(Find should find next occurrence of text selected in EDIT view) { - setup_view(EDIT, "foobarfoo", CRLF, 0); - win_view(EDIT)->selection = (Sel){ 0, 3, 0 }; - exec("Find"); - CHECK(win_view(EDIT)->selection.beg == 6); - CHECK(win_view(EDIT)->selection.end == 9); - } - - TEST(Find should find wrap around to beginning of EDIT buffer) { - setup_view(EDIT, "foobarbazfoo", CRLF, 0); - win_view(EDIT)->selection = (Sel){ 9, 12, 0 }; - exec("Find"); - CHECK(win_view(EDIT)->selection.beg == 0); - CHECK(win_view(EDIT)->selection.end == 3); - } - - TEST(Find should find next occurrence of text selected in TAGS view) { - setup_view(TAGS, "foo", CRLF, 0); - win_view(TAGS)->selection = (Sel){ 0, 3, 0 }; - setup_view(EDIT, "barfoo", CRLF, 0); - exec("Find"); - CHECK(win_view(EDIT)->selection.beg == 3); - CHECK(win_view(EDIT)->selection.end == 6); - } - - TEST(Find should find next occurrence of text selected after tag) { - setup_view(EDIT, "barfoo", CRLF, 0); - exec("Find foo"); - CHECK(win_view(EDIT)->selection.beg == 3); - CHECK(win_view(EDIT)->selection.end == 6); - } - - TEST(Find should do nothing if nothing selected) { - setup_view(EDIT, "foo bar baz", CRLF, 0); - setup_view(TAGS, "Find", CRLF, 0); - win_view(TAGS)->selection = (Sel){ 0, 4, 0 }; - win_view(EDIT)->selection = (Sel){ 0, 0, 0 }; - send_keys(ModCtrl, 'f'); - CHECK(win_view(EDIT)->selection.beg == 0); - CHECK(win_view(EDIT)->selection.end == 0); - } - - TEST(Tabs should set indent style to tabs) { - setup_view(TAGS, "Tabs", CRLF, 0); - win_view(TAGS)->selection = (Sel){ 0, 4, 0 }; - win_buf(EDIT)->expand_tabs = true; - win_buf(TAGS)->expand_tabs = true; - send_keys(ModCtrl, 'd'); - CHECK(win_buf(EDIT)->expand_tabs == false); - CHECK(win_buf(TAGS)->expand_tabs == false); - } - - TEST(Tabs should set indent style to spaces) { - setup_view(TAGS, "Tabs", CRLF, 0); - win_view(TAGS)->selection = (Sel){ 0, 4, 0 }; - win_buf(EDIT)->expand_tabs = false; - win_buf(TAGS)->expand_tabs = false; - send_keys(ModCtrl, 'd'); - CHECK(win_buf(EDIT)->expand_tabs == true); - CHECK(win_buf(TAGS)->expand_tabs == true); - } - - TEST(Indent should disable copyindent) { - setup_view(TAGS, "Indent", CRLF, 0); - win_view(TAGS)->selection = (Sel){ 0, 6, 0 }; - win_buf(EDIT)->copy_indent = true; - win_buf(TAGS)->copy_indent = true; - send_keys(ModCtrl, 'd'); - CHECK(win_buf(EDIT)->copy_indent == false); - CHECK(win_buf(TAGS)->copy_indent == false); - } - - TEST(Indent should enable copyindent) { - setup_view(TAGS, "Indent", CRLF, 0); - win_view(TAGS)->selection = (Sel){ 0, 6, 0 }; - win_buf(EDIT)->copy_indent = false; - win_buf(TAGS)->copy_indent = false; - send_keys(ModCtrl, 'd'); - CHECK(win_buf(EDIT)->copy_indent == true); - CHECK(win_buf(TAGS)->copy_indent == true); - } -} - -// fake out the exit routine -void exit(int code) { - if (ExitExpected) { - ExitCode = code; - ExitExpected = false; - longjmp(ExitPad, 1); - } else { - assert(!"Unexpected exit. Something went wrong"); - } -} - -int main(int argc, char** argv) { - initialize(); - atf_init(argc,argv); - RUN_TEST_SUITE(UnitTests); - _Exit(atf_print_results()); - return 0; -} diff --git a/tide.c b/tide.c index 3c1340e..ee4469b 100644 --- a/tide.c +++ b/tide.c @@ -1,3 +1,4 @@ +#define _XOPEN_SOURCE 700 #include #include #include @@ -93,7 +94,7 @@ void exec(char* cmd) { Tag* tag = tag_lookup(cmd); if (tag) { while (*cmd && !isspace(*cmd++)); - tag_exec(tag, (*cmd ? stringdup(cmd) : NULL)); + tag_exec(tag, (*cmd ? strdup(cmd) : NULL)); } else { cmd_exec(cmd); } @@ -285,7 +286,7 @@ static void search(char* arg) { char* str; SearchDir *= (x11_keymodsset(ModShift) ? UP : DOWN); if (x11_keymodsset(ModAlt) && SearchTerm) - str = stringdup(SearchTerm); + str = strdup(SearchTerm); else str = view_getctx(win_view(FOCUSED)); view_findstr(win_view(EDIT), SearchDir, str); -- 2.52.0