From: Michael D. Lowis Date: Mon, 6 Feb 2017 00:13:47 +0000 (-0500) Subject: Checkpoint commit. unit tests back to building and running but with several confusing... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=58a3cd32c3f17223df3dc518f429c630bdf247b4;p=projs%2Ftide.git Checkpoint commit. unit tests back to building and running but with several confusing failures --- diff --git a/Makefile b/Makefile index 0fb7c1a..f188a8c 100644 --- a/Makefile +++ b/Makefile @@ -64,5 +64,5 @@ tests/xedit: tests/xedit.o libedit.a tests/xpick: tests/xpick.o libedit.a tests/term: tests/term.o libedit.a --include *.d lib/*.d tests/*.d tests/lib/*.d +#-include *.d lib/*.d tests/*.d tests/lib/*.d diff --git a/config.mk b/config.mk index df3f115..e85fca2 100644 --- a/config.mk +++ b/config.mk @@ -6,7 +6,6 @@ PREFIX = $(HOME) # Compiler Setup CC = cc CFLAGS = --std=c99 -MMD -g -O0 $(INCS) - #CFLAGS += -Wall -Wextra -Werror # Linker Setup diff --git a/docs/crlf.txt b/docs/crlf.txt index dab8c54..e6c3387 100644 Binary files a/docs/crlf.txt and b/docs/crlf.txt differ diff --git a/docs/lf.txt b/docs/lf.txt index d8027d5..e44b242 100644 Binary files a/docs/lf.txt and b/docs/lf.txt differ diff --git a/lib/x11.c b/lib/x11.c index 6e57eee..05346ee 100644 --- a/lib/x11.c +++ b/lib/x11.c @@ -235,9 +235,9 @@ static uint32_t getkey(XEvent* e) { Status status; /* Read the key string */ if (X.xic) - len = Xutf8LookupString(X.xic, &e->xkey, buf, sizeof(buf), &key, &status); + len = Xutf8LookupString(X.xic, &(e->xkey), buf, sizeof(buf), &key, &status); else - len = XLookupString(&e->xkey, buf, sizeof(buf), &key, 0); + len = XLookupString(&(e->xkey), buf, sizeof(buf), &key, 0); /* if it's ascii, just return it */ if (key >= 0x20 && key <= 0x7F) return (uint32_t)key; @@ -286,36 +286,39 @@ static void handle_mouse(XEvent* e) { Config->handle_mouse(action, button, x, y); } +void x11_handle_event(XEvent* e) { + Atom wmDeleteMessage = XInternAtom(X.display, "WM_DELETE_WINDOW", False); + switch (e->type) { + case FocusIn: if (X.xic) XSetICFocus(X.xic); break; + case FocusOut: if (X.xic) XUnsetICFocus(X.xic); break; + case KeyPress: handle_key(e); break; + case ButtonRelease: handle_mouse(e); break; + case ButtonPress: handle_mouse(e); break; + case MotionNotify: handle_mouse(e); break; + case SelectionClear: selclear(e); break; + case SelectionNotify: selnotify(e); break; + case SelectionRequest: selrequest(e); break; + case ClientMessage: + if (e->xclient.data.l[0] == wmDeleteMessage) + Config->shutdown(); + break; + case ConfigureNotify: // Resize the window + if (e->xconfigure.width != X.width || e->xconfigure.height != X.height) { + X.width = e->xconfigure.width; + X.height = e->xconfigure.height; + X.pixmap = XCreatePixmap(X.display, X.window, X.width, X.height, X.depth); + X.xft = XftDrawCreate(X.display, X.pixmap, X.visual, X.colormap); + } + break; + } +} + void x11_handle_events(void) { XEvent e; - Atom wmDeleteMessage = XInternAtom(X.display, "WM_DELETE_WINDOW", False); while (XPending(X.display)) { XNextEvent(X.display, &e); - if (!XFilterEvent(&e, None)) { - switch (e.type) { - case FocusIn: if (X.xic) XSetICFocus(X.xic); break; - case FocusOut: if (X.xic) XUnsetICFocus(X.xic); break; - case KeyPress: handle_key(&e); break; - case ButtonRelease: handle_mouse(&e); break; - case ButtonPress: handle_mouse(&e); break; - case MotionNotify: handle_mouse(&e); break; - case SelectionClear: selclear(&e); break; - case SelectionNotify: selnotify(&e); break; - case SelectionRequest: selrequest(&e); break; - case ClientMessage: - if (e.xclient.data.l[0] == wmDeleteMessage) - Config->shutdown(); - break; - case ConfigureNotify: // Resize the window - if (e.xconfigure.width != X.width || e.xconfigure.height != X.height) { - X.width = e.xconfigure.width; - X.height = e.xconfigure.height; - X.pixmap = XCreatePixmap(X.display, X.window, X.width, X.height, X.depth); - X.xft = XftDrawCreate(X.display, X.pixmap, X.visual, X.colormap); - } - break; - } - } + if (!XFilterEvent(&e, None)) + x11_handle_event(&e); } } diff --git a/tests/xedit.c b/tests/xedit.c index fe0a2a1..8cc6a6a 100644 --- a/tests/xedit.c +++ b/tests/xedit.c @@ -2,6 +2,10 @@ #include #include #include +#include +#include + +void x11_handle_event(XEvent* e); enum { LF = 0, @@ -11,862 +15,875 @@ enum { // Test Globals int ExitCode = 0; jmp_buf ExitPad; +Display* XDisplay; // Inculd the source file so we can access everything #include "../xedit.c" static void initialize(void) { +// ShellCmd[0] = "/bin/sh"; win_init("edit"); + XDisplay = XOpenDisplay(NULL); win_setkeys(Bindings); //win_setmouse(&MouseHandlers); } /* Helper Functions *****************************************************************************/ -//void setup_view(enum RegionId id, char* text, int crlf, unsigned cursor) { -// ShellCmd[0] = "/bin/sh"; -// Focused = id; -// view_init(getview(id), NULL); -// getbuf(id)->crlf = crlf; -// view_putstr(getview(id), text); -// getsel(id)->beg = cursor; -// getsel(id)->end = cursor; -// getsel(id)->col = buf_getcol(getbuf(id), getsel(id)->end); -//} -// -//void send_keys(int mods, Rune key) { -// Mods = mods; -// 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); -// //printf("buftext: '%s'\n", buftext); -// bool result; -// if (buftext == NULL) -// result = (*text == '\0'); -// else -// result = (0 == strcmp(buftext, text)); -// free(buftext); -// return result; -//} +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 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, 'e'); -// CHECK(getsel(EDIT)->beg == 1); -// CHECK(getsel(EDIT)->end == 1); -// } -// -// TEST(input \n chould result in RUNE_CRLF if in crlf mode) { -// setup_view(EDIT, "", CRLF, 0); -// getbuf(EDIT)->crlf = 1; -// send_keys(ModNone, '\n'); -// CHECK(getsel(EDIT)->beg == 1); -// CHECK(getsel(EDIT)->end == 1); -// CHECK(RUNE_CRLF == buf_get(getbuf(EDIT), 0)); -// } -// -// TEST(input \n chould result in \n if not in crlf mode) { -// setup_view(EDIT, "", CRLF, 0); -// getbuf(EDIT)->crlf = 0; -// send_keys(ModNone, '\n'); -// CHECK(getsel(EDIT)->beg == 1); -// CHECK(getsel(EDIT)->end == 1); -// CHECK('\n' == buf_get(getbuf(EDIT), 0)); -// } -// -// /* Key Handling - Cursor Movement - Basic -// *************************************************************************/ -// TEST(left should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModNone, KEY_LEFT); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+left should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModCtrl, KEY_LEFT); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(left should do nothing at beginning of buffer) { -// setup_view(EDIT, "AB", CRLF, 0); -// send_keys(ModNone, KEY_LEFT); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+left should do nothing at beginning of buffer) { -// setup_view(EDIT, "AB", CRLF, 0); -// send_keys(ModCtrl, KEY_LEFT); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+left should move left by one word) { -// setup_view(EDIT, "AB CD", CRLF, 3); -// send_keys(ModCtrl, KEY_LEFT); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(left should move left by one rune) { -// setup_view(EDIT, "AB", CRLF, 1); -// send_keys(ModNone, KEY_LEFT); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(right should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModNone, KEY_RIGHT); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(right should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModCtrl, KEY_RIGHT); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+right should do nothing at end of buffer) { -// setup_view(EDIT, "AB", CRLF, 2); -// send_keys(ModNone, KEY_RIGHT); -// CHECK(getsel(EDIT)->beg == 2); -// CHECK(getsel(EDIT)->end == 2); -// } -// -// TEST(ctrl+right should do nothing at end of buffer) { -// setup_view(EDIT, "AB", CRLF, 2); -// send_keys(ModCtrl, KEY_RIGHT); -// CHECK(getsel(EDIT)->beg == 2); -// CHECK(getsel(EDIT)->end == 2); -// } -// -// TEST(ctrl+right should move right by one word) { -// setup_view(EDIT, "AB CD", CRLF, 0); -// send_keys(ModCtrl, KEY_RIGHT); -// CHECK(getsel(EDIT)->beg == 3); -// CHECK(getsel(EDIT)->end == 3); -// } -// -// TEST(right should move right by one rune) { -// setup_view(EDIT, "AB", CRLF, 1); -// send_keys(ModNone, KEY_RIGHT); -// CHECK(getsel(EDIT)->beg == 2); -// CHECK(getsel(EDIT)->end == 2); -// } -// -// TEST(up should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModNone, KEY_UP); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(up should move cursor up one line) { -// setup_view(EDIT, "AB\nCD", CRLF, 4); -// send_keys(ModNone, KEY_UP); -// CHECK(getsel(EDIT)->beg == 1); -// CHECK(getsel(EDIT)->end == 1); -// } -// -// TEST(up should do nothing for first line) { -// setup_view(EDIT, "AB\nCD", CRLF, 1); -// send_keys(ModNone, KEY_UP); -// CHECK(getsel(EDIT)->beg == 1); -// CHECK(getsel(EDIT)->end == 1); -// } -// -// TEST(down should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModNone, KEY_DOWN); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(down should move down one line) { -// setup_view(EDIT, "AB\nCD", CRLF, 1); -// send_keys(ModNone, KEY_DOWN); -// CHECK(getsel(EDIT)->beg == 4); -// CHECK(getsel(EDIT)->end == 4); -// } -// -// TEST(down should do nothing on last line) { -// setup_view(EDIT, "AB\nCD", CRLF, 4); -// send_keys(ModNone, KEY_DOWN); -// CHECK(getsel(EDIT)->beg == 4); -// CHECK(getsel(EDIT)->end == 4); -// } -// -// TEST(home should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModNone, KEY_HOME); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+home should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModCtrl, KEY_HOME); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+home should move to beginning of buffer) { -// setup_view(EDIT, "ABCD", CRLF, 4); -// send_keys(ModCtrl, KEY_HOME); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(home should move to beginning of indented content) { -// setup_view(EDIT, " ABCD", CRLF, 7); -// send_keys(ModNone, KEY_HOME); -// CHECK(getsel(EDIT)->beg == 4); -// CHECK(getsel(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, KEY_HOME); -// CHECK(getsel(EDIT)->beg == 4); -// CHECK(getsel(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, KEY_HOME); -// CHECK(getsel(EDIT)->beg == 4); -// CHECK(getsel(EDIT)->end == 4); -// } -// -// TEST(end should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModNone, KEY_END); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+end should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModCtrl, KEY_END); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+end should move to end of buffer) { -// setup_view(EDIT, "ABCD", CRLF, 0); -// send_keys(ModCtrl, KEY_END); -// CHECK(getsel(EDIT)->beg == 4); -// CHECK(getsel(EDIT)->end == 4); -// } -// -// TEST(end should do nothing at end of line) { -// setup_view(EDIT, "AB\nCD", CRLF, 2); -// send_keys(ModNone, KEY_END); -// CHECK(getsel(EDIT)->beg == 2); -// CHECK(getsel(EDIT)->end == 2); -// } -// -// TEST(end should move to end of line) { -// setup_view(EDIT, "AB\nCD", CRLF, 0); -// send_keys(ModNone, KEY_END); -// CHECK(getsel(EDIT)->beg == 2); -// CHECK(getsel(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, 'u'); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+u should delete to beginning of line) { -// setup_view(EDIT, "\nABC\n", CRLF, 2); -// send_keys(ModCtrl, 'u'); -// CHECK(getsel(EDIT)->beg == 1); -// CHECK(getsel(EDIT)->end == 1); -// CHECK(buf_end(getbuf(EDIT)) == 4); -// } -// -// TEST(ctrl+u should delete entire lines contents) { -// setup_view(EDIT, "\nABC\n", CRLF, 3); -// send_keys(ModCtrl, 'u'); -// CHECK(getsel(EDIT)->beg == 1); -// CHECK(getsel(EDIT)->end == 1); -// CHECK(buf_end(getbuf(EDIT)) == 3); -// } -// -// TEST(ctrl+k should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModCtrl, 'k'); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// CHECK(buf_end(getbuf(EDIT)) == 0); -// } -// -// TEST(ctrl+k should delete to end of line) { -// setup_view(EDIT, "\nABC\n", CRLF, 2); -// send_keys(ModCtrl, 'k'); -// CHECK(getsel(EDIT)->beg == 2); -// CHECK(getsel(EDIT)->end == 2); -// CHECK(buf_end(getbuf(EDIT)) == 3); -// } -// -// TEST(ctrl+k should delete entire lines contents) { -// setup_view(EDIT, "\nABC\n", CRLF, 1); -// send_keys(ModCtrl, 'k'); -// CHECK(getsel(EDIT)->beg == 1); -// CHECK(getsel(EDIT)->end == 1); -// CHECK(buf_end(getbuf(EDIT)) == 2); -// } -// -// TEST(ctrl+w should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModCtrl, 'w'); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// CHECK(buf_end(getbuf(EDIT)) == 0); -// } -// -// TEST(ctrl+w should delete previous word) { -// setup_view(EDIT, "abc def", CRLF, 4); -// send_keys(ModCtrl, 'w'); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// CHECK(buf_end(getbuf(EDIT)) == 3); -// } -// -// TEST(ctrl+h should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModCtrl, 'h'); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+h should delete previous character) { -// setup_view(EDIT, "AB", CRLF, 1); -// send_keys(ModCtrl, 'h'); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// CHECK(buf_end(getbuf(EDIT)) == 1); -// } -// -// TEST(ctrl+a should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModCtrl, 'a'); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+a should move to beginning of indented content) { -// setup_view(EDIT, " ABCD", CRLF, 7); -// send_keys(ModCtrl, 'a'); -// CHECK(getsel(EDIT)->beg == 4); -// CHECK(getsel(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, 'a'); -// CHECK(getsel(EDIT)->beg == 4); -// CHECK(getsel(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, 'a'); -// CHECK(getsel(EDIT)->beg == 4); -// CHECK(getsel(EDIT)->end == 4); -// } -// -// TEST(ctrl+e should do nothing for empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModCtrl, 'e'); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+e should do nothing at end of line) { -// setup_view(EDIT, "AB\nCD", CRLF, 2); -// send_keys(ModCtrl, 'e'); -// CHECK(getsel(EDIT)->beg == 2); -// CHECK(getsel(EDIT)->end == 2); -// } -// -// TEST(ctrl+e should move to end of line) { -// setup_view(EDIT, "AB\nCD", CRLF, 0); -// send_keys(ModCtrl, 'e'); -// CHECK(getsel(EDIT)->beg == 2); -// CHECK(getsel(EDIT)->end == 2); -// } -// -// TEST(esc should select previously inserted text) { -// setup_view(EDIT, "foo", CRLF, 0); -// send_keys(ModNone, KEY_ESCAPE); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 3); -// } -// -// TEST(esc should select previously edited text) { -// setup_view(EDIT, "foob", CRLF, 4); -// send_keys(ModNone, KEY_BACKSPACE); -// send_keys(ModNone, KEY_ESCAPE); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 3); -// } -// -// /* Key Handling - Standard Text Editing Shortcuts -// *************************************************************************/ + /* 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 chould 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 == 3); + CHECK(win_sel(EDIT)->end == 3); + } + + 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+h should do 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 delete previous character) { + setup_view(EDIT, "AB", CRLF, 1); + send_keys(ModCtrl, XK_h); + CHECK(win_sel(EDIT)->beg == 0); + CHECK(win_sel(EDIT)->end == 0); + CHECK(buf_end(win_buf(EDIT)) == 1); + } + + 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) { + IGNORE("escape must not be mappeing to XK_Escape, dunno why."); + setup_view(EDIT, "", CRLF, 0); + view_putstr(win_view(EDIT), "foo"); + send_keys(ModNone, XK_Escape); + CHECK(win_sel(EDIT)->beg == 0); + CHECK(win_sel(EDIT)->end == 3); + } + + TEST(esc should select previously edited text) { + IGNORE("escape must not be mappeing to XK_Escape, dunno why."); + setup_view(EDIT, "foob", CRLF, 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) { // setup_view(EDIT, "foo\nbar\nbaz\n", CRLF, 0); -// 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 == 4); -// CHECK(getsel(EDIT)->end == 12); +// 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) { -// getbuf(EDIT)->crlf = 1; +// win_buf(EDIT)->crlf = 1; // setup_view(EDIT, "foo\nbar\nbaz\n", CRLF, 0); -// 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 == 12); -// CHECK(getsel(EDIT)->end == 20); +// 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, '['); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+[ should do nothing at beginning of buffer) { -// setup_view(EDIT, "a", CRLF, 0); -// send_keys(ModCtrl, '['); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 1); -// } -// -// TEST(ctrl+] should do nothing on empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModCtrl, ']'); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// } -// -// TEST(ctrl+] should indent the first line) { -// setup_view(EDIT, "a", CRLF, 0); -// send_keys(ModCtrl, ']'); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(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, KEY_BACKSPACE); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(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, KEY_BACKSPACE); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// CHECK(verify_text(EDIT, "abc")); -// } -// -// TEST(backspace should delete previous character) { -// setup_view(EDIT, "abc", CRLF, 1); -// send_keys(ModNone, KEY_BACKSPACE); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(EDIT)->end == 0); -// CHECK(verify_text(EDIT, "bc")); -// } -// -// TEST(backspace should delete selection) { -// setup_view(EDIT, "abcde", CRLF, 0); -// getview(EDIT)->selection = (Sel){ .beg = 1, .end = 4 }; -// send_keys(ModNone, KEY_BACKSPACE); -// CHECK(getsel(EDIT)->beg == 1); -// CHECK(getsel(EDIT)->end == 1); -// CHECK(verify_text(EDIT, "ae")); -// } -// -// TEST(delete should do nothing on empty buffer) { -// setup_view(EDIT, "", CRLF, 0); -// send_keys(ModNone, KEY_DELETE); -// CHECK(getsel(EDIT)->beg == 0); -// CHECK(getsel(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, KEY_DELETE); -// CHECK(getsel(EDIT)->beg == 3); -// CHECK(getsel(EDIT)->end == 3); -// CHECK(verify_text(EDIT, "abc")); -// } -// -// TEST(delete should delete next character) { -// setup_view(EDIT, "abc", CRLF, 2); -// send_keys(ModNone, KEY_DELETE); -// CHECK(getsel(EDIT)->beg == 2); -// CHECK(getsel(EDIT)->end == 2); -// CHECK(verify_text(EDIT, "ab")); -// } -// -// TEST(delete should delete selection) { -// setup_view(EDIT, "abcde", CRLF, 0); -// getview(EDIT)->selection = (Sel){ .beg = 1, .end = 4 }; -// send_keys(ModNone, KEY_DELETE); -// CHECK(getsel(EDIT)->beg == 1); -// CHECK(getsel(EDIT)->end == 1); -// CHECK(verify_text(EDIT, "ae")); -// } -// -// /* Key Handling - Implementation Specific -// *************************************************************************/ -// TEST(ctrl+t should switch focus to EDIT view) { -// Focused = TAGS; -// send_keys(ModCtrl, 't'); -// CHECK(Focused == EDIT); -// } -// -// TEST(ctrl+t should switch focus to TAGs view) { -// Focused = EDIT; -// send_keys(ModCtrl, 't'); -// CHECK(Focused == TAGS); -// } -// -// TEST(ctrl+q should quit) { -// setup_view(TAGS, "", CRLF, 0); -// setup_view(EDIT, "", CRLF, 0); -// getbuf(EDIT)->modified = false; -// ExitCode = 42; -// send_keys(ModCtrl, 'q'); -// CHECK(ExitCode == 0); -// CHECK(verify_text(TAGS, "")); -// } -// -// TEST(ctrl+f should find next occurrence of selected text) { -// setup_view(EDIT, "foobarfoo", CRLF, 0); -// getview(EDIT)->selection = (Sel){ 0, 3, 0 }; -// send_keys(ModCtrl, 'f'); -// CHECK(getview(EDIT)->selection.beg == 6); -// CHECK(getview(EDIT)->selection.end == 9); -// } -// -// TEST(ctrl+f should wrap around to beginning of buffer) { -// setup_view(EDIT, "foobarbazfoo", CRLF, 0); -// getview(EDIT)->selection = (Sel){ 9, 12, 0 }; -// send_keys(ModCtrl, 'f'); -// CHECK(getview(EDIT)->selection.beg == 0); -// CHECK(getview(EDIT)->selection.end == 3); -// } -// -// /* Mouse Input Handling -// *************************************************************************/ -// -// /* Command Execution -// *************************************************************************/ -// TEST(Commands starting with : should be executed as sed scripts) { -// setup_view(EDIT, "foo", CRLF, 0); -// getview(EDIT)->selection = (Sel){ .beg = 0, .end = 3 }; -// setup_view(TAGS, ":s/foo/bar/", CRLF, 0); -// getview(TAGS)->selection = (Sel){ .beg = 0, .end = 11 }; -// send_keys(ModCtrl, 'd'); -// #ifdef __MACH__ -// CHECK(verify_text(EDIT, "bar\r\n")); -// #else -// CHECK(verify_text(EDIT, "bar")); -// #endif -// } -// -// TEST(Commands starting with | should be take selection as input and replace it with output) { -// setup_view(EDIT, "foo", CRLF, 0); -// getview(EDIT)->selection = (Sel){ .beg = 0, .end = 3 }; -// setup_view(TAGS, "|sed -e 's/foo/bar/'", CRLF, 0); -// getview(TAGS)->selection = (Sel){ .beg = 0, .end = 20 }; -// send_keys(ModCtrl, 'd'); -// #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); -// getview(EDIT)->selection = (Sel){ .beg = 0, .end = 3 }; -// setup_view(TAGS, "!ls", CRLF, 0); -// getview(TAGS)->selection = (Sel){ .beg = 0, .end = 3 }; -// send_keys(ModCtrl, 'd'); -// CHECK(verify_text(EDIT, "foo")); -// } -// -//#if 0 -// TEST(Commands starting with > should execute in the background with selection as input) { -// setup_view(EDIT, "foo", CRLF, 0); -// getview(EDIT)->selection = (Sel){ .beg = 0, .end = 3 }; -// setup_view(TAGS, ">cat", CRLF, 0); -// getview(TAGS)->selection = (Sel){ .beg = 0, .end = 4 }; -// send_keys(ModCtrl, 'd'); -// CHECK(verify_text(EDIT, "foo")); -// } -//#endif -// -// TEST(Commands starting with < should replace selection with output) { -// setup_view(EDIT, "foo", CRLF, 0); -// getview(EDIT)->selection = (Sel){ .beg = 0, .end = 3 }; -// setup_view(TAGS, "selection = (Sel){ .beg = 0, .end = 9 }; -// send_keys(ModCtrl, 'd'); -// 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); -// getview(EDIT)->selection = (Sel){ .beg = 0, .end = 8 }; -// send_keys(ModCtrl, 'd'); -// 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); -// getbuf(EDIT)->modified = false; -// ExitCode = 42; -// exec("Quit"); -// 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); -// getbuf(EDIT)->modified = true; -// ExitCode = 42; -// usleep(251 * 1000); -// exec("Quit"); -// CHECK(ExitCode == 42); -// CHECK(verify_text(TAGS, "File is modified. Repeat action twice in < 250ms to quit.")); -// } -// -// TEST(Quit should discard changes if quit executed twice in less than 250 ms) { -// setup_view(TAGS, "", CRLF, 0); -// setup_view(EDIT, "", CRLF, 0); -// getbuf(EDIT)->modified = true; -// ExitCode = 42; -// usleep(251 * 1000); -// exec("Quit"); -// CHECK(ExitCode == 42); -// CHECK(verify_text(TAGS, "File is modified. Repeat action twice in < 250ms to quit.")); -// exec("Quit"); -// CHECK(ExitCode == 0); -// CHECK(verify_text(TAGS, "File is modified. Repeat action twice in < 250ms to quit.")); -// } -// -// TEST(Save should save changes to disk with crlf line endings) { -// setup_view(TAGS, "", CRLF, 0); -// view_init(getview(EDIT), "docs/crlf.txt"); -// CHECK(verify_text(EDIT, "this file\r\nuses\r\ndos\r\nline\r\nendings\r\n")); -// exec("Save"); -// view_init(getview(EDIT), "docs/crlf.txt"); -// 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(getview(EDIT), "docs/lf.txt"); -// CHECK(verify_text(EDIT, "this file\nuses\nunix\nline\nendings\n")); -// exec("Save"); -// view_init(getview(EDIT), "docs/lf.txt"); -// CHECK(verify_text(EDIT, "this file\nuses\nunix\nline\nendings\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; + //if (0 == setjmp(ExitPad)) + // send_keys(ModCtrl, XK_q); + puts("sendkey3"); + 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); + } + + /* 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); + #ifdef __MACH__ + CHECK(verify_text(EDIT, "bar\r\n")); + #else + CHECK(verify_text(EDIT, "bar")); + #endif + } + + TEST(Commands starting with | should be 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); + #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); + CHECK(verify_text(EDIT, "foo")); + } + +#if 0 + 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); + CHECK(verify_text(EDIT, "foo")); + } +#endif + + 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); + 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); + 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; + exec("Quit"); + 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 in < 250ms to quit.")); + } + + TEST(Quit should discard changes if quit executed twice in less than 250 ms) { + 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 in < 250ms to quit.")); + exec("Quit"); + CHECK(ExitCode == 0); + CHECK(verify_text(TAGS, "File is modified. Repeat action twice in < 250ms to quit.")); + } + + TEST(Save should save changes to disk with crlf line endings) { + setup_view(TAGS, "", CRLF, 0); + view_init(win_view(EDIT), "docs/crlf.txt"); + CHECK(verify_text(EDIT, "this file\r\nuses\r\ndos\r\nline\r\nendings\r\n")); + exec("Save"); + view_init(win_view(EDIT), "docs/crlf.txt"); + 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), "docs/lf.txt"); + CHECK(verify_text(EDIT, "this file\nuses\nunix\nline\nendings\n")); + exec("Save"); + view_init(win_view(EDIT), "docs/lf.txt"); + CHECK(verify_text(EDIT, "this file\nuses\nunix\nline\nendings\n")); + } + // TEST(Cut and Paste tags should move selection to new location) { // setup_view(EDIT, "foo\nbar\nbaz\n", CRLF, 0); -// getview(EDIT)->selection = (Sel){ 0, 8, 0 }; +// win_view(EDIT)->selection = (Sel){ 0, 8, 0 }; // exec("Cut"); -// getview(EDIT)->selection = (Sel){ 4, 4, 0 }; +// win_view(EDIT)->selection = (Sel){ 4, 4, 0 }; // exec("Paste"); -// CHECK(getsel(EDIT)->beg == 4); -// CHECK(getsel(EDIT)->end == 12); +// 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) { // setup_view(EDIT, "foo\nbar\nbaz\n", CRLF, 0); -// getview(EDIT)->selection = (Sel){ 0, 8, 0 }; +// win_view(EDIT)->selection = (Sel){ 0, 8, 0 }; // exec("Copy"); -// getview(EDIT)->selection = (Sel){ 12, 12, 0 }; +// win_view(EDIT)->selection = (Sel){ 12, 12, 0 }; // exec("Paste"); -// CHECK(getsel(EDIT)->beg == 12); -// CHECK(getsel(EDIT)->end == 20); +// 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, "foo", CRLF, 0); -// 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); -// getview(EDIT)->selection = (Sel){ 0, 3, 0 }; -// send_keys(ModNone, KEY_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); -// getview(EDIT)->selection = (Sel){ 0, 3, 0 }; -// send_keys(ModNone, KEY_DELETE); -// getview(EDIT)->selection = (Sel){ 3, 6, 0 }; -// send_keys(ModNone, KEY_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); -// getview(EDIT)->selection = (Sel){ 3, 3, 0 }; -// for(int i = 0; i < 3; i++) -// send_keys(ModNone, KEY_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); -// getview(EDIT)->selection = (Sel){ 0, 3, 0 }; -// exec("Find"); -// CHECK(getview(EDIT)->selection.beg == 6); -// CHECK(getview(EDIT)->selection.end == 9); -// } -// -// TEST(Find should find wrap around to beginning of EDIT buffer) { -// setup_view(EDIT, "foobarbazfoo", CRLF, 0); -// getview(EDIT)->selection = (Sel){ 9, 12, 0 }; -// exec("Find"); -// CHECK(getview(EDIT)->selection.beg == 0); -// CHECK(getview(EDIT)->selection.end == 3); -// } -// -// TEST(Find should find next occurrence of text selected in TAGS view) { -// setup_view(TAGS, "foo", CRLF, 0); -// getview(TAGS)->selection = (Sel){ 0, 3, 0 }; -// setup_view(EDIT, "barfoo", CRLF, 0); -// exec("Find"); -// CHECK(getview(EDIT)->selection.beg == 3); -// CHECK(getview(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(getview(EDIT)->selection.beg == 3); -// CHECK(getview(EDIT)->selection.end == 6); -// } -// -//#if 0 -// TEST(Find should do nothing if nothing selected) { -// setup_view(TAGS, "Find", CRLF, 0); -// getview(TAGS)->selection = (Sel){ 0, 4, 0 }; -// send_keys(ModCtrl, 'f'); -// } -//#endif -// -// TEST(Tabs should set indent style to tabs) { -// setup_view(TAGS, "Tabs", CRLF, 0); -// getview(TAGS)->selection = (Sel){ 0, 4, 0 }; -// getbuf(EDIT)->expand_tabs = true; -// getbuf(TAGS)->expand_tabs = true; -// send_keys(ModCtrl, 'd'); -// CHECK(getbuf(EDIT)->expand_tabs == false); -// CHECK(getbuf(TAGS)->expand_tabs == false); -// } -// -// TEST(Tabs should set indent style to spaces) { -// setup_view(TAGS, "Tabs", CRLF, 0); -// getview(TAGS)->selection = (Sel){ 0, 4, 0 }; -// getbuf(EDIT)->expand_tabs = false; -// getbuf(TAGS)->expand_tabs = false; -// send_keys(ModCtrl, 'd'); -// CHECK(getbuf(EDIT)->expand_tabs == true); -// CHECK(getbuf(TAGS)->expand_tabs == true); -// } -// -// TEST(Indent should disable copyindent) { -// setup_view(TAGS, "Indent", CRLF, 0); -// getview(TAGS)->selection = (Sel){ 0, 6, 0 }; -// getbuf(EDIT)->copy_indent = true; -// getbuf(TAGS)->copy_indent = true; -// send_keys(ModCtrl, 'd'); -// CHECK(getbuf(EDIT)->copy_indent == false); -// CHECK(getbuf(TAGS)->copy_indent == false); -// } -// -// TEST(Indent should enable copyindent) { -// setup_view(TAGS, "Indent", CRLF, 0); -// getview(TAGS)->selection = (Sel){ 0, 6, 0 }; -// getbuf(EDIT)->copy_indent = false; -// getbuf(TAGS)->copy_indent = false; -// send_keys(ModCtrl, 'd'); -// CHECK(getbuf(EDIT)->copy_indent == true); -// CHECK(getbuf(TAGS)->copy_indent == true); -// } + + TEST(Undo+Redo should undo+redo the previous insert) { + setup_view(EDIT, "foo", CRLF, 0); + 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); + } + +#if 0 + TEST(Find should do nothing if nothing selected) { + setup_view(TAGS, "Find", CRLF, 0); + win_view(TAGS)->selection = (Sel){ 0, 4, 0 }; + send_keys(ModCtrl, 'f'); + } +#endif + + 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) { ExitCode = code; - longjmp(ExitPad, 0); + longjmp(ExitPad, 1); } int main(int argc, char** argv) { diff --git a/xedit.c b/xedit.c index 8c09ccd..9e4adfb 100644 --- a/xedit.c +++ b/xedit.c @@ -132,7 +132,11 @@ static void quit(void) { static uint64_t before = 0; uint64_t now = getmillis(); if (!win_buf(EDIT)->modified || (now-before) <= 250) { + #ifndef TEST x11_deinit(); + #else + exit(0); + #endif } else { view_append(win_view(TAGS), "File is modified. Repeat action twice in < 250ms to quit."); @@ -487,10 +491,3 @@ int main(int argc, char** argv) { } #endif - - - - - - -