From 987321afb2bbcf399781026123a55d8fad477923 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Thu, 9 May 2019 12:27:59 -0400 Subject: [PATCH] added shortcuts.c file for common text editing shortcuts --- Makefile | 1 + inc/edit.h | 29 ++++++++ inc/x11.h | 2 + src/lib/shortcuts.c | 158 +++++++++++++++++++++++++++++++++++++++ src/lib/x11.c | 1 + src/tframe.c | 81 +++++++++++++++++--- src/tide.c | 176 +------------------------------------------- 7 files changed, 264 insertions(+), 184 deletions(-) create mode 100644 src/lib/shortcuts.c diff --git a/Makefile b/Makefile index 8886a89..60f0f8f 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ LIBEDIT_OBJS = \ 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 diff --git a/inc/edit.h b/inc/edit.h index b9e2881..db2a78b 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -179,3 +179,32 @@ bool job_poll(int ms); 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); + diff --git a/inc/x11.h b/inc/x11.h index 50a9129..77dce10 100644 --- a/inc/x11.h +++ b/inc/x11.h @@ -125,6 +125,8 @@ typedef struct { char* arg; } KeyBinding; +extern struct XConf X; + int x11_init(XConf* x); void x11_error_clear(void); XErrorEvent* x11_error_get(void); diff --git a/src/lib/shortcuts.c b/src/lib/shortcuts.c new file mode 100644 index 0000000..f955d15 --- /dev/null +++ b/src/lib/shortcuts.c @@ -0,0 +1,158 @@ +#include +#include +#include +#include + +#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 diff --git a/src/lib/x11.c b/src/lib/x11.c index 586e600..6c2abc4 100644 --- a/src/lib/x11.c +++ b/src/lib/x11.c @@ -5,6 +5,7 @@ #include #include +struct XConf X; static Bool Has_Error = False; static XErrorEvent Error = {0}; diff --git a/src/tframe.c b/src/tframe.c index b1cc21b..f1e6380 100644 --- a/src/tframe.c +++ b/src/tframe.c @@ -10,12 +10,13 @@ #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 ******************************************************************************/ @@ -66,7 +67,7 @@ static void xexpose(XConf* x, XEvent* e) { } 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); } @@ -161,6 +162,72 @@ void win_quit(void) { /* 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(); @@ -171,19 +238,11 @@ int main(void) { 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(); diff --git a/src/tide.c b/src/tide.c index da35809..55ff598 100644 --- a/src/tide.c +++ b/src/tide.c @@ -34,8 +34,7 @@ typedef struct { 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; @@ -399,175 +398,6 @@ static void exec(char* cmd, char* arg) { /* 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 ******************************************************************************/ @@ -769,7 +599,7 @@ static Tag Builtins[18] = { { .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 }, @@ -885,7 +715,7 @@ int main(int argc, char** argv) { 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); -- 2.52.0