Add keyboard shortcuts for snarf, cut, paste, and exchange. - sam - An updated version of the sam text editor.
(HTM) git clone git://vernunftzentrum.de/sam.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) LICENSE
---
(DIR) commit 5ec62bf406a1c2aaffb1d54315c91b5ef871447d
(DIR) parent 69987ee5a8f00c4bdaf7bec8daab8fa5b2152d6d
(HTM) Author: Rob King <jking@deadpixi.com>
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(-)
---
(DIR) 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 logically.
+{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 logically.
-{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},
(DIR) diff --git a/include/commands.h b/include/commands.h
@@ -25,6 +25,7 @@ enum{
Csnarf,
Ccut,
Cpaste,
+ Cexchange,
Cmax
}; /* virtual command keystrokes */
(DIR) diff --git a/libXg/gwin.c b/libXg/gwin.c
@@ -392,23 +392,7 @@ SendSel(Widget w, Atom *sel, Atom *target, Atom *rtype, XtPointer *ans,
*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;
}
(DIR) 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};
(DIR) 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 getting better! */
{
Text *t = (Text *)l->user1;
Rune buf[100];
@@ -712,6 +776,7 @@ type(Flayer *l, int res) /* what a bloody mess this is */
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 is */
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 is */
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 is */
}
void
-outcmd(void){
+outcmd(void)
+{
if(work)
outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work->p1);
}
(DIR) 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);