]> git.mdlowis.com Git - projs/tide.git/commitdiff
Checkpoint commit. unit tests back to building and running but with several confusing...
authorMichael D. Lowis <mike@mdlowis.com>
Mon, 6 Feb 2017 00:13:47 +0000 (19:13 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Mon, 6 Feb 2017 00:13:47 +0000 (19:13 -0500)
Makefile
config.mk
docs/crlf.txt
docs/lf.txt
lib/x11.c
tests/xedit.c
xedit.c

index 0fb7c1aec9e460dd130786fadc1691c995caf22a..f188a8c842162174252d530f2e10d60fa2f4b17f 100644 (file)
--- 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
 
index df3f115b2520d3dd5083ade0b943ad7e8261001b..e85fca2ef11980d2b12765016265bd865fbc329f 100644 (file)
--- 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
index dab8c54834f67ab46a81f3dab41b2ad25159d94d..e6c3387d26c4e9e5ac97ccfef1cbb5883df76250 100644 (file)
Binary files a/docs/crlf.txt and b/docs/crlf.txt differ
index d8027d5e9219eeac408fb77c753dd6d644fe810c..e44b242ac08300453d82417530a078ea4225821c 100644 (file)
Binary files a/docs/lf.txt and b/docs/lf.txt differ
index 6e57eee66f3b210fbc5f3720326627c6c4900149..05346ee25669371aa0083ab53a84849c85fb81fc 100644 (file)
--- 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);
     }
 }
 
index fe0a2a171c1d04f8e808422286bdc5669a3be1ab..8cc6a6a7b234ab8e61c2d64080d1b24f182b4731 100644 (file)
@@ -2,6 +2,10 @@
 #include <atf.h>
 #include <time.h>
 #include <setjmp.h>
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+
+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, "<echo bar", CRLF, 0);
-//        getview(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, "<echo bar", CRLF, 0);
+        win_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 8c09ccdb1d4716703c34c93592cdc666dabd9c57..9e4adfb10b19b2013b376959cfabf73573f2bb27 100644 (file)
--- 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
 
-
-
-
-
-
-
-