Add keyboard shortcuts for snarf, cut, paste, and exchange. - sam - An updated … | |
git clone git://vernunftzentrum.de/sam.git | |
Log | |
Files | |
Refs | |
LICENSE | |
--- | |
commit 5ec62bf406a1c2aaffb1d54315c91b5ef871447d | |
parent 69987ee5a8f00c4bdaf7bec8daab8fa5b2152d6d | |
Author: Rob King <[email protected]> | |
Date: Fri, 12 Aug 2016 15:11:44 -0500 | |
Add keyboard shortcuts for snarf, cut, paste, and exchange. | |
Diffstat: | |
commands.h.def | 25 +++++++++++++++++-------- | |
include/commands.h | 1 + | |
libXg/gwin.c | 30 ++++-------------------------- | |
samterm/io.c | 6 ++++++ | |
samterm/main.c | 86 ++++++++++++++++++++++++++++--- | |
samterm/samterm.h | 1 + | |
6 files changed, 107 insertions(+), 42 deletions(-) | |
--- | |
diff --git a/commands.h.def b/commands.h.def | |
@@ -3,7 +3,9 @@ | |
* | |
* {mask, keysym, kind, action} | |
* | |
- * mask - one of the X modifier masks, or the user-configured COMMANDMASK | |
+ * mask - one of the X modifier masks | |
+ * or the user-defined COMMANDMASK (see config.h) | |
+ * or 0, for no modifier | |
* keysym - one of the X symbolic keysym names | |
* kind - Kcommand for commands | |
* Kraw for literal characters | |
@@ -23,6 +25,10 @@ | |
* Cdel - delete previous character | |
* Cjump - jump to and from the command window | |
* Cescape - highlight recently typed text | |
+ * Csnarf - copy text to the snarf buffer | |
+ * Cpaste - paste text from the snarf buffer | |
+ * Ccut - cut text to the snarf buffer | |
+ * Cexchange - exchange operating system and sam snarf buffers | |
* | |
* The default configuration shipped with sam has the keyboard commands mapped | |
* to the "classic" Unix sam of the 1980s, plus the WordStar Diamond for cursor | |
@@ -40,6 +46,9 @@ | |
{COMMANDMASK, XK_w, Kcommand, Cdelword}, | |
{COMMANDMASK, XK_k, Kcommand, Cjump}, | |
{COMMANDMASK, XK_BackSpace, Kcommand, Cdelword}, | |
+{COMMANDMASK, XK_c, Kcommand, Csnarf}, | |
+{COMMANDMASK, XK_v, Kcommand, Cpaste}, | |
+{COMMANDMASK, XK_q, Kcommand, Cexchange}, | |
/* Use COMMAND-Tab to insert a literal tab when tab expansion is enabled. */ | |
{COMMANDMASK, XK_Tab, Kcomposed, '\t'}, | |
@@ -52,7 +61,13 @@ | |
{COMMANDMASK, XK_space, Kcommand, Cescape}, | |
{0, XK_Escape, Kcommand, Cjump}, */ | |
-/* Less commonly changed commands. See below for a common change. */ | |
+/* Some users might like to make the arrow keys move the selection more logica… | |
+{0, XK_Up, Kcommand, Cscrollup}, | |
+{0, XK_Down, Kcommand, Cscrolldown}, | |
+{0, XK_Left, Kcommand, Ccharleft}, | |
+{0, XK_Right, Kcommand, Ccharright}, */ | |
+ | |
+/* Less commonly changed commands (though see above about the arrow keys). */ | |
{0, XK_Up, Kcommand, Cscrollup}, | |
{0, XK_Prior, Kcommand, Cscrollup}, | |
{0, XK_Left, Kcommand, Cscrollup}, | |
@@ -61,12 +76,6 @@ | |
{0, XK_Right, Kcommand, Cscrolldown}, | |
{0, XK_Escape, Kcommand, Cescape}, | |
-/* Some users might like to make the arrow keys move the selection more logica… | |
-{0, XK_Up, Kcommand, Cscrollup}, | |
-{0, XK_Down, Kcommand, Cscrolldown}, | |
-{0, XK_Left, Kcommand, Ccharleft}, | |
-{0, XK_Right, Kcommand, Ccharright}, */ | |
- | |
/* You probably shouldn't change these. */ | |
{0, XK_BackSpace, Kcommand, Cdel}, | |
{0, XK_Delete, Kcommand, Cdel}, | |
diff --git a/include/commands.h b/include/commands.h | |
@@ -25,6 +25,7 @@ enum{ | |
Csnarf, | |
Ccut, | |
Cpaste, | |
+ Cexchange, | |
Cmax | |
}; /* virtual command keystrokes */ | |
diff --git a/libXg/gwin.c b/libXg/gwin.c | |
@@ -392,23 +392,7 @@ SendSel(Widget w, Atom *sel, Atom *target, Atom *rtype, Xt… | |
*ansfmt = 8; | |
return TRUE; | |
} | |
-#ifndef R3 | |
- if(targets == 0){ | |
- src.addr = "TARGETS"; | |
- src.size = strlen(src.addr)+1; | |
- dst.size = sizeof(Atom); | |
- dst.addr = (XtPointer) &targets; | |
- XtConvertAndStore(w, XtRString, &src, XtRAtom, &dst); | |
- } | |
- if(*target == targets){ | |
- *rtype = XA_ATOM; | |
- *ans = (XtPointer) XtNew(Atom); | |
- *(Atom*) *ans = XA_STRING; | |
- *anslen = 1; | |
- *ansfmt = 32; | |
- return TRUE; | |
- } | |
-#endif | |
+ | |
return FALSE; | |
} | |
@@ -423,24 +407,18 @@ SelectSwap(Widget w, String s) | |
XtFree(gw->gwin.selection); | |
gw->gwin.selection = 0; | |
} | |
-#ifdef R3 | |
- XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, SelCallback, 0, | |
- CurrentTime); | |
-#else | |
XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, SelCallback, 0, | |
XtLastTimestampProcessed(XtDisplay(w))); | |
-#endif | |
+ | |
while(gw->gwin.selection == 0) | |
XtAppProcessEvent(XtWidgetToApplicationContext(w) , XtIMAll); | |
ans = gw->gwin.selection; | |
gw->gwin.selection = XtMalloc(strlen(s)+1); | |
strcpy(gw->gwin.selection, s); | |
-#ifdef R3 | |
- XtOwnSelection(w, XA_PRIMARY, CurrentTime, SendSel, NULL, NULL); | |
-#else | |
+ | |
XtOwnSelection(w, XA_PRIMARY, XtLastTimestampProcessed(XtDisplay(w)), | |
SendSel, NULL, NULL); | |
-#endif | |
+ | |
return ans; | |
} | |
diff --git a/samterm/io.c b/samterm/io.c | |
@@ -146,6 +146,12 @@ externchar(void) | |
} | |
Keystroke | |
+qpeekc(void) | |
+{ | |
+ return keystroke; | |
+} | |
+ | |
+Keystroke | |
kbdchar(void) | |
{ | |
Keystroke k = {0}; | |
diff --git a/samterm/main.c b/samterm/main.c | |
@@ -676,6 +676,66 @@ cmddel(Flayer *l, long a, Text *t) | |
return a; | |
} | |
+static inline int | |
+getlayer(const Flayer *l, const Text *t) | |
+{ | |
+ int i; | |
+ for (i = 0; i < NL; i++) | |
+ if (&t->l[i] == l) | |
+ return i; | |
+ | |
+ return -1; | |
+} | |
+ | |
+static long | |
+cmdexchange(Flayer *l, long a, Text *t) | |
+{ | |
+ int w = getlayer(l, t); | |
+ if (w >= 0){ | |
+ snarf(t, w); | |
+ outT0(Tstartsnarf); | |
+ setlock(); | |
+ } | |
+ | |
+ return a; | |
+} | |
+ | |
+static long | |
+cmdsnarf(Flayer *l, long a, Text *t) | |
+{ | |
+ flushtyping(0); | |
+ | |
+ int w = getlayer(l, t); | |
+ if (w >= 0) | |
+ snarf(t, w); | |
+ | |
+ return a; | |
+} | |
+ | |
+static long | |
+cmdcut(Flayer *l, long a, Text *t) | |
+{ | |
+ flushtyping(0); | |
+ | |
+ int w = getlayer(l, t); | |
+ if (w >= 0) | |
+ cut(t, w, 1, 1); | |
+ | |
+ return a; | |
+} | |
+ | |
+static long | |
+cmdpaste(Flayer *l, long a, Text *t) | |
+{ | |
+ flushtyping(0); | |
+ | |
+ int w = getlayer(l, t); | |
+ if (w >= 0) | |
+ paste(t, w); | |
+ | |
+ return a; | |
+} | |
+ | |
typedef long (*Commandfunc)(Flayer *, long, Text *); | |
typedef struct CommandEntry CommandEntry; | |
struct CommandEntry{ | |
@@ -692,13 +752,17 @@ CommandEntry commands[Cmax] ={ | |
[Clinedown] = {cmdlinedown, 0}, | |
[Cjump] = {cmdjump, 0}, | |
[Cescape] = {cmdescape, 0}, | |
+ [Csnarf] = {cmdsnarf, 0}, | |
+ [Ccut] = {cmdcut, 0}, | |
+ [Cpaste] = {cmdpaste, 0}, | |
+ [Cexchange] = {cmdexchange, 0}, | |
[Cdelword] = {cmddelword, 1}, | |
[Cdelbol] = {cmddelbol, 1}, | |
[Cdel] = {cmddel, 1} | |
}; | |
void | |
-type(Flayer *l, int res) /* what a bloody mess this is */ | |
+type(Flayer *l, int res) /* what a bloody mess this is -- but it's gett… | |
{ | |
Text *t = (Text *)l->user1; | |
Rune buf[100]; | |
@@ -712,6 +776,7 @@ type(Flayer *l, int res) /* what a bloody mess this … | |
return; | |
} | |
+ k = qpeekc(); | |
a = l->p0; | |
if (a != l->p1 && k.k != Kcommand){ | |
flushtyping(1); | |
@@ -740,6 +805,16 @@ type(Flayer *l, int res) /* what a bloody mess this… | |
break; | |
} | |
+ if (k.k == Kcommand){ | |
+ if (k.c < 0 || k.c >= Cmax) | |
+ panic("command table miss"); | |
+ | |
+ CommandEntry *e = &commands[k.c]; | |
+ if (!e->unlocked || !lock) | |
+ a = e->f(l, a, t); | |
+ return; | |
+ } | |
+ | |
if (p > buf){ | |
if (typestart < 0) | |
typestart = a; | |
@@ -759,12 +834,6 @@ type(Flayer *l, int res) /* what a bloody mess this… | |
onethird(l, a); | |
} | |
- if (k.k == Kcommand){ | |
- CommandEntry *e = &commands[k.c]; | |
- if (!e->unlocked || !lock) | |
- a = e->f(l, a, t); | |
- } | |
- | |
if (typeesc >= l->p0) | |
typeesc = l->p0; | |
@@ -781,7 +850,8 @@ type(Flayer *l, int res) /* what a bloody mess this … | |
} | |
void | |
-outcmd(void){ | |
+outcmd(void) | |
+{ | |
if(work) | |
outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work-… | |
} | |
diff --git a/samterm/samterm.h b/samterm/samterm.h | |
@@ -90,6 +90,7 @@ int load(char*, int); | |
int waitforio(void); | |
int rcvchar(void); | |
int getch(void); | |
+Keystroke qpeekc(void); | |
Keystroke kbdchar(void); | |
void mouseexit(void); | |
void cut(Text*, int, int, int); |