src/lib/job.o \
src/lib/view.o \
src/lib/draw.o \
+ src/lib/shortcuts.o \
src/lib/x11.o \
src/lib/x11_gc.o \
src/lib/x11_sel.o
void job_spawn(int fd, jobfn_t readfn, jobfn_t writefn, void* data);
void job_start(char** cmd, char* data, size_t ndata, View* dest);
int job_run(char** cmd);
+
+/* Common Shortcuts
+ *****************************************************************************/
+void select_line(char* arg);
+void join_lines(char* arg);
+void delete(char* arg);
+void cut(char* arg);
+void paste(char* arg);
+void copy(char* arg);
+void del_to_bol(char* arg);
+void del_to_eol(char* arg);
+void del_to_bow(char* arg);
+void backspace(char* arg);
+void cursor_bol(char* arg);
+void cursor_eol(char* arg);
+void cursor_mvlr(int dir);
+void cursor_mvupdn(int dir);
+void cursor_home(char* arg);
+void cursor_end(char* arg);
+void cursor_up(char* arg);
+void cursor_dn(char* arg);
+void cursor_left(char* arg);
+void cursor_right(char* arg);
+void page_up(char* arg);
+void page_dn(char* arg);
+void select_prev(char* arg);
+void undo(char* arg);
+void redo(char* arg);
+
char* arg;
} KeyBinding;
+extern struct XConf X;
+
int x11_init(XConf* x);
void x11_error_clear(void);
XErrorEvent* x11_error_get(void);
--- /dev/null
+#include <utf.h>
+#include <edit.h>
+#include <win.h>
+#include <x11.h>
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+
+void select_line(char* arg) {
+ buf_selln(win_buf(FOCUSED));
+}
+
+void join_lines(char* arg) {
+ View* view = win_view(FOCUSED);
+ buf_logstart(win_buf(FOCUSED));
+ view_eol(view, false);
+ view_delete(view, RIGHT, false);
+ Rune r = view_getrune(view);
+ for (; r == '\t' || r == ' '; r = view_getrune(view))
+ view_byrune(view, RIGHT, true);
+ if (r != '\n')
+ buf_putc(win_buf(FOCUSED), ' ');
+ buf_logstop(win_buf(FOCUSED));
+}
+
+void delete(char* arg) {
+ bool byword = win_keymodsset(ModCtrl);
+ view_delete(win_view(FOCUSED), RIGHT, byword);
+}
+
+static void onpaste(char* text) {
+ view_paste(win_view(FOCUSED), text);
+}
+
+void cut(char* arg) {
+ View* view = win_view(FOCUSED);
+ /* select the current line if no selection */
+ if (!view_selsize(view))
+ select_line(arg);
+ /* now perform the cut */
+ char* str = view_getstr(view);
+ x11_sel_set(&X, CLIPBOARD, str);
+ if (str && *str) delete(arg);
+}
+
+void paste(char* arg) {
+ int pasted = x11_sel_get(&X, CLIPBOARD, onpaste);
+ assert(pasted);
+}
+
+void copy(char* arg) {
+ /* select the current line if no selection */
+ if (!view_selsize(win_view(FOCUSED)))
+ select_line(arg);
+ char* str = view_getstr(win_view(FOCUSED));
+ x11_sel_set(&X, CLIPBOARD, str);
+}
+
+static void del_to(void (*tofn)(View*, bool)) {
+ tofn(win_view(FOCUSED), true);
+ if (view_selsize(win_view(FOCUSED)) > 0)
+ delete(NULL);
+}
+
+void del_to_bol(char* arg) {
+ del_to(view_bol);
+}
+
+void del_to_eol(char* arg) {
+ del_to(view_eol);
+}
+
+void del_to_bow(char* arg) {
+ view_byword(win_view(FOCUSED), LEFT, true);
+ if (view_selsize(win_view(FOCUSED)) > 0)
+ delete(arg);
+}
+
+void backspace(char* arg) {
+ view_delete(win_view(FOCUSED), LEFT, win_keymodsset(ModCtrl));
+}
+
+void cursor_bol(char* arg) {
+ view_bol(win_view(FOCUSED), false);
+}
+
+void cursor_eol(char* arg) {
+ view_eol(win_view(FOCUSED), false);
+}
+
+void cursor_mvlr(int dir) {
+ bool extsel = win_keymodsset(ModShift);
+ if (win_keymodsset(ModCtrl))
+ view_byword(win_view(FOCUSED), dir, extsel);
+ else
+ view_byrune(win_view(FOCUSED), dir, extsel);
+}
+
+void cursor_mvupdn(int dir) {
+ bool extsel = win_keymodsset(ModShift);
+ view_byline(win_view(FOCUSED), dir, extsel);
+}
+
+static void cursor_home_end(
+ void (*docfn)(View*, bool),
+ void (*linefn)(View*, bool)
+) {
+ bool extsel = win_keymodsset(ModShift);
+ if (win_keymodsset(ModCtrl))
+ docfn(win_view(FOCUSED), extsel);
+ else
+ linefn(win_view(FOCUSED), extsel);
+}
+
+void cursor_home(char* arg) {
+ cursor_home_end(view_bof, view_bol);
+}
+
+void cursor_end(char* arg) {
+ cursor_home_end(view_eof, view_eol);
+}
+
+void cursor_up(char* arg) {
+ cursor_mvupdn(UP);
+}
+
+void cursor_dn(char* arg) {
+ cursor_mvupdn(DOWN);
+}
+
+void cursor_left(char* arg) {
+ cursor_mvlr(LEFT);
+}
+
+void cursor_right(char* arg) {
+ cursor_mvlr(RIGHT);
+}
+
+void page_up(char* arg) {
+ view_scrollpage(win_view(FOCUSED), UP);
+}
+
+void page_dn(char* arg) {
+ view_scrollpage(win_view(FOCUSED), DOWN);
+}
+
+void select_prev(char* arg) {
+ view_selprev(win_view(FOCUSED));
+}
+
+void undo(char* arg) {
+ view_undo(win_view(FOCUSED));
+}
+
+void redo(char* arg) {
+ view_redo(win_view(FOCUSED));
+}
+#pragma GCC diagnostic pop
#include <sys/types.h>
#include <sys/wait.h>
+struct XConf X;
static Bool Has_Error = False;
static XErrorEvent Error = {0};
#define INCLUDE_DEFS
#include "config.h"
-static struct XConf X;
static View Tags;
static int Divider;
static int FontSel;
Window Child = 0;
int retile = 0;
+static KeyBinding Bindings[41];
+
/* X11 Font Code
******************************************************************************/
}
static void xkeypress(XConf* x, XEvent* e) {
- uint32_t key = x11_process_key(x, e, NULL);
+ uint32_t key = x11_process_key(x, e, Bindings);
if (key != RUNE_ERR)
view_insert(&Tags, key);
}
/* Main Routine
******************************************************************************/
+
+View* win_view(WinRegion id) {
+ (void)id;
+ return &(Tags);
+}
+
+Buf* win_buf(WinRegion id) {
+ (void)id;
+ return &(Tags.buffer);
+}
+
+bool win_keymodsset(int mask) {
+ return ((X.mods & mask) == mask);
+}
+
+static void new_win(char* arg) {
+ (void)arg;
+ char* cmd[] = { "tide", 0 };
+ if (fork() == 0)
+ execvp(cmd[0], cmd);
+}
+
+static KeyBinding Bindings[41] = {
+ /* Cursor Movements */
+ { .mods = ModAny, .key = KEY_HOME, .fn = cursor_home },
+ { .mods = ModAny, .key = KEY_END, .fn = cursor_end },
+ { .mods = ModAny, .key = KEY_UP, .fn = cursor_up },
+ { .mods = ModAny, .key = KEY_DOWN, .fn = cursor_dn },
+ { .mods = ModAny, .key = KEY_LEFT, .fn = cursor_left },
+ { .mods = ModAny, .key = KEY_RIGHT, .fn = cursor_right },
+
+ /* Standard Unix Shortcuts */
+ { .mods = ModCtrl, .key = 'u', .fn = del_to_bol },
+ { .mods = ModCtrl, .key = 'k', .fn = del_to_eol },
+ { .mods = ModCtrl, .key = 'w', .fn = del_to_bow },
+ { .mods = ModCtrl, .key = 'a', .fn = cursor_bol },
+ { .mods = ModCtrl, .key = 'e', .fn = cursor_eol },
+
+ /* Standard Text Editing Shortcuts */
+ { .mods = ModCtrl, .key = 'z', .fn = undo },
+ { .mods = ModCtrl, .key = 'y', .fn = redo },
+ { .mods = ModCtrl, .key = 'x', .fn = cut },
+ { .mods = ModCtrl, .key = 'c', .fn = copy },
+ { .mods = ModCtrl, .key = 'v', .fn = paste },
+ { .mods = ModCtrl, .key = 'j', .fn = join_lines },
+ { .mods = ModCtrl, .key = 'l', .fn = select_line },
+
+ /* Common Special Keys */
+ { .mods = ModNone, .key = KEY_PGUP, .fn = page_up },
+ { .mods = ModNone, .key = KEY_PGDN, .fn = page_dn },
+ { .mods = ModAny, .key = KEY_DELETE, .fn = delete },
+ { .mods = ModAny, .key = KEY_BACKSPACE, .fn = backspace },
+
+// /* External command shortcuts */
+// { .mods = ModCtrl, .key = '[', .fn = lnexec, .arg = "|i-" },
+// { .mods = ModCtrl, .key = ']', .fn = lnexec, .arg = "|i+" },
+// { .mods = ModCtrl, .key = '/', .fn = lnexec, .arg = "|c+" },
+// { .mods = ModCtrl|ModShift, .key = '?', .fn = lnexec, .arg = "|c-" },
+
+ { .mods = ModCtrl, .key = 'n', .fn = new_win },
+// { .mods = ModOneOrMore, .key = '\n', .fn = newline },
+
+ { 0, 0, 0, 0 }
+};
+
+
int main(void) {
/* create the window */
win_init();
view_resize(&Tags, 640, 1);
buf_logclear(&(Tags.buffer));
+ /* inform child windows to embed themselves */
char window_id[64];
sprintf(window_id, "%lu", X.self);
setenv("TIDE_PARENT", window_id, 1);
-// for (int i = 0; i < 1; i++) {
- if (fork() == 0) {
- char* tidecmd[] = { "tide", 0 };
- execvp(tidecmd[0], tidecmd);
- fprintf(stderr, "error: can't execute child process!\n");
- exit(1);
- }
-// }
-
/* now create the window and start the event loop */
xupdate(NULL);
win_loop();
char* ARGV0;
static Tag Builtins[18];
-static KeyBinding Bindings[];
-static struct XConf X;
+static KeyBinding Bindings[41];
static WinRegion Focused = EDIT;
static View Regions[NREGIONS];
static int Divider;
/* Keyboard Editing Handlers
******************************************************************************/
-static void select_line(char* arg) {
- (void)arg;
- buf_selln(win_buf(FOCUSED));
-}
-
-static void join_lines(char* arg) {
- (void)arg;
- View* view = win_view(FOCUSED);
- buf_logstart(win_buf(FOCUSED));
- view_eol(view, false);
- view_delete(view, RIGHT, false);
- Rune r = view_getrune(view);
- for (; r == '\t' || r == ' '; r = view_getrune(view))
- view_byrune(view, RIGHT, true);
- if (r != '\n')
- buf_putc(win_buf(FOCUSED), ' ');
- buf_logstop(win_buf(FOCUSED));
-}
-
-static void delete(char* arg) {
- (void)arg;
- bool byword = win_keymodsset(ModCtrl);
- view_delete(win_view(FOCUSED), RIGHT, byword);
-}
-
-static void onpaste(char* text) {
- view_paste(win_view(FOCUSED), text);
-}
-
-void cut(char* arg) {
- View* view = win_view(FOCUSED);
- /* select the current line if no selection */
- if (!view_selsize(view))
- select_line(arg);
- /* now perform the cut */
- char* str = view_getstr(view);
- x11_sel_set(&X, CLIPBOARD, str);
- if (str && *str) delete(arg);
-}
-
-void paste(char* arg) {
- (void)arg;
- int pasted = x11_sel_get(&X, CLIPBOARD, onpaste);
- assert(pasted);
-}
-
-static void copy(char* arg) {
- /* select the current line if no selection */
- if (!view_selsize(win_view(FOCUSED)))
- select_line(arg);
- char* str = view_getstr(win_view(FOCUSED));
- x11_sel_set(&X, CLIPBOARD, str);
-}
-
-static void del_to(void (*tofn)(View*, bool)) {
- tofn(win_view(FOCUSED), true);
- if (view_selsize(win_view(FOCUSED)) > 0)
- delete(NULL);
-}
-
-static void del_to_bol(char* arg) {
- (void)arg;
- del_to(view_bol);
-}
-
-static void del_to_eol(char* arg) {
- (void)arg;
- del_to(view_eol);
-}
-
-static void del_to_bow(char* arg) {
- view_byword(win_view(FOCUSED), LEFT, true);
- if (view_selsize(win_view(FOCUSED)) > 0)
- delete(arg);
-}
-
-static void backspace(char* arg) {
- (void)arg;
- view_delete(win_view(FOCUSED), LEFT, win_keymodsset(ModCtrl));
-}
-
-static void cursor_bol(char* arg) {
- (void)arg;
- view_bol(win_view(FOCUSED), false);
-}
-
-static void cursor_eol(char* arg) {
- (void)arg;
- view_eol(win_view(FOCUSED), false);
-}
-
-static void cursor_mvlr(int dir) {
- bool extsel = win_keymodsset(ModShift);
- if (win_keymodsset(ModCtrl))
- view_byword(win_view(FOCUSED), dir, extsel);
- else
- view_byrune(win_view(FOCUSED), dir, extsel);
-}
-
-static void cursor_mvupdn(int dir) {
- bool extsel = win_keymodsset(ModShift);
- view_byline(win_view(FOCUSED), dir, extsel);
-}
-
-static void cursor_home_end(
- void (*docfn)(View*, bool),
- void (*linefn)(View*, bool)
-) {
- bool extsel = win_keymodsset(ModShift);
- if (win_keymodsset(ModCtrl))
- docfn(win_view(FOCUSED), extsel);
- else
- linefn(win_view(FOCUSED), extsel);
-}
-
-static void cursor_home(char* arg) {
- (void)arg;
- cursor_home_end(view_bof, view_bol);
-}
-
-static void cursor_end(char* arg) {
- (void)arg;
- cursor_home_end(view_eof, view_eol);
-}
-
-static void cursor_up(char* arg) {
- (void)arg;
- cursor_mvupdn(UP);
-}
-
-static void cursor_dn(char* arg) {
- (void)arg;
- cursor_mvupdn(DOWN);
-}
-
-static void cursor_left(char* arg) {
- (void)arg;
- cursor_mvlr(LEFT);
-}
-
-static void cursor_right(char* arg) {
- (void)arg;
- cursor_mvlr(RIGHT);
-}
-
-static void page_up(char* arg) {
- (void)arg;
- view_scrollpage(win_view(FOCUSED), UP);
-}
-
-static void page_dn(char* arg) {
- (void)arg;
- view_scrollpage(win_view(FOCUSED), DOWN);
-}
-
-static void select_prev(char* arg) {
- (void)arg;
- view_selprev(win_view(FOCUSED));
-}
-
-static void undo(char* arg) {
- (void)arg;
- view_undo(win_view(FOCUSED));
-}
-
-static void redo(char* arg) {
- (void)arg;
- view_redo(win_view(FOCUSED));
-}
/* Keyboard and Tag Handlers
******************************************************************************/
{ .tag = NULL, .action = NULL }
};
-static KeyBinding Bindings[] = {
+static KeyBinding Bindings[41] = {
/* Cursor Movements */
{ .mods = ModAny, .key = KEY_HOME, .fn = cursor_home },
{ .mods = ModAny, .key = KEY_END, .fn = cursor_end },
if (!gethostname(host, sizeof(host)))
win_prop_set("HOST", "host", host);
- /* check if we should embede in a parent */
+ /* check if we should embed in a parent */
char* winid = getenv("TIDE_PARENT");
if (winid) {
XReparentWindow(X.display, X.self, strtoul(winid, 0, 0), 0, 0);