Add support for sending commands to the editor. - 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 a52daf1643c6759b60847b7466e0d57ddf833cd6
(DIR) parent 4b8e52f78d6efadffefb275c547bc20ba17b65c9
(HTM) Author: Rob King <jking@deadpixi.com>
Date: Mon, 19 Sep 2016 16:43:33 -0500
Add support for sending commands to the editor.
Diffstat:
doc/samrc | 12 +++++++++++-
doc/samrc.5 | 31 ++++++++++++++++++++++++-------
include/libg.h | 6 ++++--
libXg/Gwin.h | 2 +-
libXg/gwin.c | 20 ++++++++++++--------
libXg/xtbinit.c | 5 +++--
samterm/main.c | 83 +++++++++++++++++--------------
samterm/samrc.c | 159 ++++++++++++++++---------------
samterm/samterm.h | 4 ++--
9 files changed, 184 insertions(+), 138 deletions(-)
---
(DIR) diff --git a/doc/samrc b/doc/samrc
@@ -42,7 +42,17 @@ bind * Next command scrolldown
# except for Control-D. Let's remove any special handling for that binding.
unbind C d
-# I like 13pt Inconsolata
+# Control-Z sends an undo command.
+bind C z command send u
+
+# Control-Return inserts a line below the current one
+bind C Enter command send +-a/\n/
+
+# Control-S writes the file, Control-Shift-S writes all files.
+bind C s command send w
+bind CS s command send X w
+
+# I like 13pt Inconsolata (I need new glasses)
font Inconsolata:size=13
# Use black for text and borders, and an angry fruit salad for backgrounds
(DIR) diff --git a/doc/samrc.5 b/doc/samrc.5
@@ -28,6 +28,7 @@ Bind a key sequence to a command or a raw character.
The forms are:
.Bd -literal
+ bind M K command C A
bind M K command C
bind M K raw C
@@ -43,7 +44,6 @@ below
.Em K
is the name of a keyboard symbol suitable for passing to
.Xr XStringToKeysym 3 ","
-and
.Em C
is either a command name
.Po
@@ -58,9 +58,13 @@ or hexadecimal
as in
.Xr keyboard 5
.Pc
-specification of a character.
+specification of a character,
+and
+.Em A
+is an arbitrary string to use as an argument to a bound command.
.Pp
-Note that keyboard symbol names are implementation-defined and often case-sensitive.
+Note that keyboard symbol names are implementation-defined and often case-sensitive,
+and that not all commands will make use of arguments.
.It unbind
Remove all bindings associated with a key sequence.
The form is:
@@ -204,12 +208,12 @@ meaning Control, or
meaning shift.
.Pp
For example,
-bind the "write" command to
-.Em Control-Shift-W ","
+bind the "exchange" command to
+.Em Control-Shift-E ","
the following directive could be used:
.Bd -literal
- bind CS w command write
+ bind CS w command exchange
.Ed
.Pp
@@ -237,10 +241,10 @@ cut Cut selection Control-Y
snarf Snarf selection Control-C
paste Paste snarf buffer Control-V
exchange Exchange snarf buffer Control-Q
-write Write current file None
eol Move to end of line None
bol Move to beginning of line None
tab Insert a (possibly expanded) tab Tab
+send Send a command to the editor None
.TE
.Pp
Additionally,
@@ -251,6 +255,19 @@ means that the given binding should perform no action
and the command name
.Dq default
means that the given binding should perform whatever action was previously defined for it.
+.Pp
+For the
+.Em send
+command,
+the command to send is specified in the argument of the binding.
+For example, to bind
+.Em Control-Z
+to undo the last 10 changes, the following line binding could be used:
+.Bd -literal
+
+ bind C z command send u10
+
+.Ed
.Ss "Mouse Button States"
Chords are described using two states:
a beginning state and an end state.
(DIR) diff --git a/include/libg.h b/include/libg.h
@@ -63,6 +63,7 @@ struct Mouse
int buttons; /* bit array: LMR=124 */
Point xy;
unsigned long msec;
+ char *a;
};
struct Keystroke
@@ -71,6 +72,7 @@ struct Keystroke
int c;
int t;
Point p;
+ const char *a;
};
struct Menu
@@ -247,8 +249,8 @@ extern XftColor bgcolor;
#define BPSHORT(p, v) ((p)[0]=(v), (p)[1]=((v)>>8))
#define BPLONG(p, v) (BPSHORT(p, (v)), BPSHORT(p+2, (v)>>16))
-extern int installbinding(int, KeySym, int, int);
-extern int installchord(int, int, int, int);
+extern int installbinding(int, KeySym, int, int, const char *);
+extern int installchord(int, int, int, int, const char *);
extern int removebinding(int, KeySym);
extern int removechord(int, int);
(DIR) diff --git a/libXg/Gwin.h b/libXg/Gwin.h
@@ -34,7 +34,7 @@ typedef struct {
} Gwinmouse;
typedef void (*Reshapefunc)(int, int, int, int);
-typedef void (*Charfunc)(int, int, int, int, int);
+typedef void (*Charfunc)(int, int, int, int, int, const char *);
typedef void (*Mousefunc)(Gwinmouse*);
/* Method declarations */
(DIR) diff --git a/libXg/gwin.c b/libXg/gwin.c
@@ -159,7 +159,7 @@ Mappingaction(Widget w, XEvent *e, String *p, Cardinal *np)
f = ((GwinWidget)w)->gwin.gotchar; \
if (f) \
for (c = 0; c < composing; c++) \
- (*f)(compose[c], 0, Tcurrent, 0, 0)
+ (*f)(compose[c], 0, Tcurrent, 0, 0, NULL)
typedef struct Unikeysym Unikeysym;
struct Unikeysym{
@@ -190,17 +190,19 @@ struct Keymapping{
KeySym s;
int k;
int c;
+ char a[];
};
static Keymapping *keymappings = NULL;
int
-installbinding(int m, KeySym s, int k, int c)
+installbinding(int m, KeySym s, int k, int c, const char *a)
{
if (m < 0 || s == NoSymbol || k < 0 || c < 0)
return -1;
- Keymapping *km = calloc(1, sizeof(Keymapping));
+ a = a ? a : "";
+ Keymapping *km = calloc(1, sizeof(Keymapping) + strlen(a) + 1);
if (!km)
return -1;
@@ -208,7 +210,7 @@ installbinding(int m, KeySym s, int k, int c)
km->s = s;
km->k = k;
km->c = c;
-
+ strcpy(km->a, a);
km->next = keymappings;
keymappings = km;
@@ -285,7 +287,7 @@ Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
default:
f = ((GwinWidget)w)->gwin.gotchar;
if (f)
- (*f)(m->c, m->k, Tcurrent, 0, 0);
+ (*f)(m->c, m->k, Tcurrent, 0, 0, m->a);
return;
}
}
@@ -364,7 +366,7 @@ Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
f = ((GwinWidget)w)->gwin.gotchar;
if(f)
- (*f)(c, kind, Tcurrent, 0, 0);
+ (*f)(c, kind, Tcurrent, 0, 0, NULL);
}
typedef struct Chordmapping Chordmapping;
@@ -374,12 +376,13 @@ struct Chordmapping{
int s2;
int c;
int t;
+ const char *a;
};
static Chordmapping *chordmap = NULL;
int
-installchord(int s1, int s2, int c, int t)
+installchord(int s1, int s2, int c, int t, const char *a)
{
if (s1 < 0 || s2 < 0 || c < 0 || (t != Tmouse && t != Tcurrent))
return -1;
@@ -392,6 +395,7 @@ installchord(int s1, int s2, int c, int t)
m->s2 = s2;
m->c = c;
m->t = t;
+ m->a = a;
m->next = chordmap;
chordmap = m;
@@ -504,7 +508,7 @@ Mouseaction(Widget w, XEvent *e, String *p, Cardinal *np)
default:
kf = ((GwinWidget)w)->gwin.gotchar;
if (kf)
- (*kf)(cm->c, Kcommand, cm->t, m.xy.x, m.xy.y);
+ (*kf)(cm->c, Kcommand, cm->t, m.xy.x, m.xy.y, NULL);
m.buttons = 0;
chording = true;
(DIR) diff --git a/libXg/xtbinit.c b/libXg/xtbinit.c
@@ -109,7 +109,7 @@ static int Stimer = -1;
static void reshaped(int, int, int, int);
-static void gotchar(int, int, int, int, int);
+static void gotchar(int, int, int, int, int, const char *);
static void gotmouse(Gwinmouse *);
static int ilog2(int);
@@ -309,7 +309,7 @@ reshaped(int minx, int miny, int maxx, int maxy)
}
static void
-gotchar(int c, int kind, int target, int x, int y)
+gotchar(int c, int kind, int target, int x, int y, const char *arg)
{
Ebuf *eb;
Keystroke k;
@@ -323,6 +323,7 @@ gotchar(int c, int kind, int target, int x, int y)
k.k = kind;
k.t = target;
k.p = Pt(x, y);
+ k.a = arg;
memcpy(eb->buf, &k, sizeof(Keystroke));
esrc[Skeyboard].count++;
}
(DIR) diff --git a/samterm/main.c b/samterm/main.c
@@ -103,11 +103,11 @@ main(int argc, char *argv[])
;
current(&cmd.l[i]);
flsetselect(which, cmd.rasp.nrunes, cmd.rasp.nrunes);
- type(which, RExtern);
+ type(which);
}
if(got&RKeyboard){
if(which)
- type(which, RKeyboard);
+ type(which);
else
kbdblock();
}
@@ -481,7 +481,7 @@ flushtyping(int clearesc)
}
static long
-cmdscrolldown(Flayer *l, long a, Text *t)
+cmdscrolldown(Flayer *l, long a, Text *t, const char *arg)
{
flushtyping(0);
center(l, l->origin + l->f.nchars + 1);
@@ -489,7 +489,7 @@ cmdscrolldown(Flayer *l, long a, Text *t)
}
static long
-cmdscrollup(Flayer *l, long a, Text *t)
+cmdscrollup(Flayer *l, long a, Text *t, const char *arg)
{
flushtyping(0);
if (oldcompat)
@@ -500,7 +500,7 @@ cmdscrollup(Flayer *l, long a, Text *t)
}
static long
-cmdcharleft(Flayer *l, long a, Text *t)
+cmdcharleft(Flayer *l, long a, Text *t, const char *arg)
{
flsetselect(l, a, a);
flushtyping(0);
@@ -513,7 +513,7 @@ cmdcharleft(Flayer *l, long a, Text *t)
}
static long
-cmdcharright(Flayer *l, long a, Text *t)
+cmdcharright(Flayer *l, long a, Text *t, const char *arg)
{
flsetselect(l, a, a);
flushtyping(0);
@@ -526,7 +526,7 @@ cmdcharright(Flayer *l, long a, Text *t)
}
static long
-cmdeol(Flayer *l, long a, Text *t)
+cmdeol(Flayer *l, long a, Text *t, const char *arg)
{
flsetselect(l, a, a);
flushtyping(1);
@@ -543,7 +543,7 @@ cmdeol(Flayer *l, long a, Text *t)
}
static long
-cmdbol(Flayer *l, long a, Text *t)
+cmdbol(Flayer *l, long a, Text *t, const char *arg)
{
flsetselect(l, a, a);
flushtyping(1);
@@ -561,7 +561,7 @@ cmdbol(Flayer *l, long a, Text *t)
}
static long
-cmdscrollupline(Flayer *l, long a, Text *t)
+cmdscrollupline(Flayer *l, long a, Text *t, const char *arg)
{
if (l->origin > 0)
hmoveto(t->tag, l->origin - 1, l);
@@ -569,7 +569,7 @@ cmdscrollupline(Flayer *l, long a, Text *t)
}
static long
-cmdscrolldownline(Flayer *l, long a, Text *t)
+cmdscrolldownline(Flayer *l, long a, Text *t, const char *arg)
{
long e = t->rasp.nrunes;
@@ -584,7 +584,7 @@ cmdscrolldownline(Flayer *l, long a, Text *t)
}
static long
-cmdlineup(Flayer *l, long a, Text *t)
+cmdlineup(Flayer *l, long a, Text *t, const char *arg)
{
flsetselect(l, a, a);
flushtyping(1);
@@ -611,7 +611,7 @@ cmdlineup(Flayer *l, long a, Text *t)
}
static long
-cmdlinedown(Flayer *l, long a, Text *t)
+cmdlinedown(Flayer *l, long a, Text *t, const char *arg)
{
flsetselect(l, a, a);
flushtyping(1);
@@ -645,7 +645,7 @@ cmdlinedown(Flayer *l, long a, Text *t)
}
static long
-cmdjump(Flayer *l, long a, Text *u)
+cmdjump(Flayer *l, long a, Text *u, const char *arg)
{
Text *t = NULL;
@@ -665,7 +665,7 @@ cmdjump(Flayer *l, long a, Text *u)
}
static long
-cmdescape(Flayer *l, long a, Text *t)
+cmdescape(Flayer *l, long a, Text *t, const char *arg)
{
if (typeesc >= 0){
l->p0 = typeesc;
@@ -681,7 +681,7 @@ cmdescape(Flayer *l, long a, Text *t)
}
static long
-cmddelword(Flayer *l, long a, Text *t)
+cmddelword(Flayer *l, long a, Text *t, const char *arg)
{
if (l->f.p0 > 0 && a > 0)
l->p0 = ctlw(&t->rasp, l->origin, a);
@@ -703,7 +703,7 @@ cmddelword(Flayer *l, long a, Text *t)
}
static long
-cmddelbol(Flayer *l, long a, Text *t)
+cmddelbol(Flayer *l, long a, Text *t, const char *arg)
{
if (l->f.p0 > 0 && a > 0)
l->p0 = ctlu(&t->rasp, l->origin, a);
@@ -725,7 +725,7 @@ cmddelbol(Flayer *l, long a, Text *t)
}
static long
-cmddel(Flayer *l, long a, Text *t)
+cmddel(Flayer *l, long a, Text *t, const char *arg)
{
if (l->f.p0 > 0 && a > 0)
l->p0 = a - 1;
@@ -758,7 +758,7 @@ getlayer(const Flayer *l, const Text *t)
}
static long
-cmdexchange(Flayer *l, long a, Text *t)
+cmdexchange(Flayer *l, long a, Text *t, const char *arg)
{
int w = getlayer(l, t);
if (w >= 0){
@@ -771,7 +771,7 @@ cmdexchange(Flayer *l, long a, Text *t)
}
static long
-cmdsnarf(Flayer *l, long a, Text *t)
+cmdsnarf(Flayer *l, long a, Text *t, const char *arg)
{
flushtyping(0);
@@ -783,7 +783,7 @@ cmdsnarf(Flayer *l, long a, Text *t)
}
static long
-cmdcut(Flayer *l, long a, Text *t)
+cmdcut(Flayer *l, long a, Text *t, const char *arg)
{
flushtyping(0);
@@ -795,7 +795,7 @@ cmdcut(Flayer *l, long a, Text *t)
}
static long
-cmdpaste(Flayer *l, long a, Text *t)
+cmdpaste(Flayer *l, long a, Text *t, const char *arg)
{
flushtyping(0);
@@ -807,16 +807,7 @@ cmdpaste(Flayer *l, long a, Text *t)
}
static long
-cmdwrite(Flayer *l, long a, Text *t)
-{
- flushtyping(0);
- outTs(Twrite, ((Text *)l->user1)->tag);
- setlock();
- return a;
-}
-
-static long
-cmdtab(Flayer *l, long a, Text *t)
+cmdtab(Flayer *l, long a, Text *t, const char *arg)
{
flushtyping(0);
@@ -837,12 +828,28 @@ cmdtab(Flayer *l, long a, Text *t)
}
static long
-cmdnone(Flayer *l, long a, Text *t)
+cmdsend(Flayer *l, long a, Text *t, const char *arg)
+{
+ flushtyping(0);
+ cmdjump(l, a, t, NULL);
+ for (const char *c = arg; *c != 0; c++){
+ pushkbd(*c);
+ type(&cmd.l[cmd.front]);
+ }
+ pushkbd('\n');
+ type(&cmd.l[cmd.front]);
+ cmdjump(l, a, t, NULL);
+
+ return a;
+}
+
+static long
+cmdnone(Flayer *l, long a, Text *t, const char *arg)
{
return a;
}
-typedef long (*Commandfunc)(Flayer *, long, Text *);
+typedef long (*Commandfunc)(Flayer *, long, Text *, const char *);
typedef struct CommandEntry CommandEntry;
struct CommandEntry{
Commandfunc f;
@@ -869,15 +876,15 @@ CommandEntry commands[Cmax] ={
[Cdelword] = {cmddelword, true, false},
[Cdelbol] = {cmddelbol, true, false},
[Cdel] = {cmddel, true, true},
- [Cwrite] = {cmdwrite, true, false},
[Ceol] = {cmdeol, false, false},
[Cbol] = {cmdbol, false, false},
- [Ctab] = {cmdtab, false, false}
+ [Ctab] = {cmdtab, false, false},
+ [Csend] = {cmdsend, false, false}
};
void
-type(Flayer *l, int res) /* what a bloody mess this is -- but it's getting better! */
+type(Flayer *l) /* what a bloody mess this is -- but it's getting better! */
{
Text *t = (Text *)l->user1;
Rune buf[100];
@@ -914,11 +921,11 @@ type(Flayer *l, int res) /* what a bloody mess this is -- but it's getting be
CommandEntry *e = &commands[k.c];
if (!e->unlocked || !lock){
if (k.t == Tcurrent || oldcompat)
- a = e->f(l, a, t);
+ a = e->f(l, a, t, k.a);
else{
Flayer *lt = flwhich(k.p);
if (lt)
- lt->p0 = e->f(lt, lt->p0, (Text *)lt->user1);
+ lt->p0 = e->f(lt, lt->p0, (Text *)lt->user1, k.a);
}
}
}
(DIR) diff --git a/samterm/samrc.c b/samterm/samrc.c
@@ -40,10 +40,10 @@ static Namemapping commandmapping[] ={
{"cut", Ccut},
{"paste", Cpaste},
{"exchange", Cexchange},
- {"write", Cwrite},
{"eol", Ceol},
{"bol", Cbol},
{"tab", Ctab},
+ {"send", Csend},
{NULL, 0}
};
@@ -96,68 +96,69 @@ struct Defaultbinding{
KeySym keysym;
int kind;
int command;
+ const char *arg;
};
static Defaultbinding defaultbindings[] ={
/* Suppress control key combinations unless explicitly bound. */
- {ControlMask, XK_VoidSymbol, Kcommand, Cnone},
+ {ControlMask, XK_VoidSymbol, Kcommand, Cnone, NULL},
/* Motion commands following the WordStar diamond. */
- {ControlMask, XK_e, Kcommand, Clineup},
- {ControlMask, XK_x, Kcommand, Clinedown},
- {ControlMask, XK_d, Kcommand, Ccharright},
- {ControlMask, XK_s, Kcommand, Ccharleft},
- {ControlMask, XK_u, Kcommand, Cdelbol},
- {ControlMask, XK_w, Kcommand, Cdelword},
- {ControlMask, XK_k, Kcommand, Cjump},
- {ControlMask, XK_BackSpace, Kcommand, Cdelword},
- {ControlMask, XK_y, Kcommand, Ccut},
- {ControlMask, XK_c, Kcommand, Csnarf},
- {ControlMask, XK_v, Kcommand, Cpaste},
- {ControlMask, XK_q, Kcommand, Cexchange},
+ {ControlMask, XK_e, Kcommand, Clineup, NULL},
+ {ControlMask, XK_x, Kcommand, Clinedown, NULL},
+ {ControlMask, XK_d, Kcommand, Ccharright, NULL},
+ {ControlMask, XK_s, Kcommand, Ccharleft, NULL},
+ {ControlMask, XK_u, Kcommand, Cdelbol, NULL},
+ {ControlMask, XK_w, Kcommand, Cdelword, NULL},
+ {ControlMask, XK_k, Kcommand, Cjump, NULL},
+ {ControlMask, XK_BackSpace, Kcommand, Cdelword, NULL},
+ {ControlMask, XK_y, Kcommand, Ccut, NULL},
+ {ControlMask, XK_c, Kcommand, Csnarf, NULL},
+ {ControlMask, XK_v, Kcommand, Cpaste, NULL},
+ {ControlMask, XK_q, Kcommand, Cexchange, NULL},
/* Handle arrow keys, page up/down, and escape. */
- {0, XK_Up, Kcommand, Cscrollup},
- {0, XK_Prior, Kcommand, Cscrollup},
- {0, XK_Left, Kcommand, Cscrollup},
- {0, XK_Down, Kcommand, Cscrolldown},
- {0, XK_Next, Kcommand, Cscrolldown},
- {0, XK_Right, Kcommand, Cscrolldown},
- {0, XK_Escape, Kcommand, Cescape},
+ {0, XK_Up, Kcommand, Cscrollup, NULL},
+ {0, XK_Prior, Kcommand, Cscrollup, NULL},
+ {0, XK_Left, Kcommand, Cscrollup, NULL},
+ {0, XK_Down, Kcommand, Cscrolldown, NULL},
+ {0, XK_Next, Kcommand, Cscrolldown, NULL},
+ {0, XK_Right, Kcommand, Cscrolldown, NULL},
+ {0, XK_Escape, Kcommand, Cescape, NULL},
/* More fundamental stuff: backspace, delete, etc. */
- {0, XK_BackSpace, Kcommand, Cdel},
- {0, XK_Delete, Kcommand, Cdel},
- {0, XK_Tab, Kcommand, Ctab},
- {0, XK_Return, Kraw, '\n'},
- {0, XK_KP_Enter, Kraw, '\n'},
- {0, XK_Linefeed, Kraw, '\r'},
- {0, XK_KP_0, Kraw, '0'},
- {0, XK_KP_1, Kraw, '1'},
- {0, XK_KP_2, Kraw, '2'},
- {0, XK_KP_3, Kraw, '3'},
- {0, XK_KP_4, Kraw, '4'},
- {0, XK_KP_5, Kraw, '5'},
- {0, XK_KP_6, Kraw, '6'},
- {0, XK_KP_7, Kraw, '7'},
- {0, XK_KP_8, Kraw, '8'},
- {0, XK_KP_9, Kraw, '9'},
- {0, XK_KP_Divide, Kraw, '/'},
- {0, XK_KP_Multiply, Kraw, '*'},
- {0, XK_KP_Subtract, Kraw, '-'},
- {0, XK_KP_Add, Kraw, '+'},
- {0, XK_KP_Decimal, Kraw, '.'},
- {0, XK_hyphen, Kraw, '-'},
+ {0, XK_BackSpace, Kcommand, Cdel, NULL},
+ {0, XK_Delete, Kcommand, Cdel, NULL},
+ {0, XK_Tab, Kcommand, Ctab, NULL},
+ {0, XK_Return, Kraw, '\n', NULL},
+ {0, XK_KP_Enter, Kraw, '\n', NULL},
+ {0, XK_Linefeed, Kraw, '\r', NULL},
+ {0, XK_KP_0, Kraw, '0', NULL},
+ {0, XK_KP_1, Kraw, '1', NULL},
+ {0, XK_KP_2, Kraw, '2', NULL},
+ {0, XK_KP_3, Kraw, '3', NULL},
+ {0, XK_KP_4, Kraw, '4', NULL},
+ {0, XK_KP_5, Kraw, '5', NULL},
+ {0, XK_KP_6, Kraw, '6', NULL},
+ {0, XK_KP_7, Kraw, '7', NULL},
+ {0, XK_KP_8, Kraw, '8', NULL},
+ {0, XK_KP_9, Kraw, '9', NULL},
+ {0, XK_KP_Divide, Kraw, '/', NULL},
+ {0, XK_KP_Multiply, Kraw, '*', NULL},
+ {0, XK_KP_Subtract, Kraw, '-', NULL},
+ {0, XK_KP_Add, Kraw, '+', NULL},
+ {0, XK_KP_Decimal, Kraw, '.', NULL},
+ {0, XK_hyphen, Kraw, '-', NULL},
/* Support traditional control sequences. */
- {ControlMask, XK_bracketleft, Kcommand, Cescape},
- {ControlMask, XK_h, Kcommand, Cdel},
- {ControlMask, XK_i, Kcommand, Ctab},
- {ControlMask, XK_j, Kraw, '\n'},
- {ControlMask, XK_m, Kraw, '\r'},
+ {ControlMask, XK_bracketleft, Kcommand, Cescape, NULL},
+ {ControlMask, XK_h, Kcommand, Cdel, NULL},
+ {ControlMask, XK_i, Kcommand, Ctab, NULL},
+ {ControlMask, XK_j, Kraw, '\n', NULL},
+ {ControlMask, XK_m, Kraw, '\r', NULL},
/* Use Control-Tab to insert a literal tab when tab expansion is enabled. */
- {ControlMask, XK_Tab, Kraw, '\t'},
+ {ControlMask, XK_Tab, Kraw, '\t', NULL},
{0, 0, Kend, 0}
};
@@ -166,7 +167,7 @@ void
installdefaultbindings(void)
{
for (Defaultbinding *b = defaultbindings; b->kind != Kend; b++)
- installbinding(b->modifiers, b->keysym, b->kind, b->command);
+ installbinding(b->modifiers, b->keysym, b->kind, b->command, b->arg);
}
typedef struct Defaultchord Defaultchord;
@@ -175,25 +176,26 @@ struct Defaultchord{
int state2;
int command;
int target;
+ const char *arg;
};
static Defaultchord defaultchords[] ={
- {B1, B1|B2, Ccut, Tcurrent},
- {B1, B1|B3, Cpaste, Tcurrent},
- {B1|B2, B1, Cnone, Tcurrent},
- {B1|B3, B1, Cnone, Tcurrent},
+ {B1, B1|B2, Ccut, Tcurrent, NULL},
+ {B1, B1|B3, Cpaste, Tcurrent, NULL},
+ {B1|B2, B1, Cnone, Tcurrent, NULL},
+ {B1|B3, B1, Cnone, Tcurrent, NULL},
- {B4, 0, Cscrollupline, Tmouse},
- {B5, 0, Cscrolldownline, Tmouse},
+ {B4, 0, Cscrollupline, Tmouse, NULL},
+ {B5, 0, Cscrolldownline, Tmouse, NULL},
- {0, 0, Kend, 0}
+ {0, 0, Kend, 0, NULL}
};
void
installdefaultchords(void)
{
for (Defaultchord *c = defaultchords; c->state1 != 0; c++)
- installchord(c->state1, c->state2, c->command, c->target);
+ installchord(c->state1, c->state2, c->command, c->target, c->arg);
}
static int
@@ -225,45 +227,45 @@ nametokeysym(const char *n)
}
static int
-dirchord(const char *s1, const char *s2, const char *s3, const char *s4)
+dirchord(const char *s1, const char *s2, const char *s3, const char *s4, const char *s5)
{
- return installchord(buttontomask(s1), buttontomask(s2), nametocommand(s3), nametotarget(s4));
+ return installchord(buttontomask(s1), buttontomask(s2), nametocommand(s3), nametotarget(s4), s5);
}
static int
-dirraw(const char *s1, const char *s2, const char *s3, const char *s4)
+dirraw(const char *s1, const char *s2, const char *s3, const char *s4, const char *s5)
{
- return installbinding(modtomask(s1), nametokeysym(s2), Kraw, strtol(s3, NULL, 16));
+ return installbinding(modtomask(s1), nametokeysym(s2), Kraw, strtol(s3, NULL, 16), NULL);
}
static int
-dirrawliteral(const char *s1, const char *s2, const char *s3, const char *s4)
+dirrawliteral(const char *s1, const char *s2, const char *s3, const char *s4, const char *s5)
{
if (strlen(s3) != 1)
return -1;
- return installbinding(modtomask(s1), nametokeysym(s2), Kraw, s3[0]);
+ return installbinding(modtomask(s1), nametokeysym(s2), Kraw, s3[0], NULL);
}
static int
-dirbind(const char *s1, const char *s2, const char *s3, const char *s4)
+dirbind(const char *s1, const char *s2, const char *s3, const char *s4, const char *s5)
{
- return installbinding(modtomask(s1), nametokeysym(s2), Kcommand, nametocommand(s3));
+ return installbinding(modtomask(s1), nametokeysym(s2), Kcommand, nametocommand(s3), s4);
}
static int
-dirunbind(const char *s1, const char *s2, const char *s3, const char *s4)
+dirunbind(const char *s1, const char *s2, const char *s3, const char *s4, const char *s5)
{
return removebinding(modtomask(s1), nametokeysym(s2));
}
static int
-dirunchord(const char *s1, const char *s2, const char *s3, const char *s4)
+dirunchord(const char *s1, const char *s2, const char *s3, const char *s4, const char *s5)
{
return removechord(buttontomask(s1), buttontomask(s2));
}
static int
-dirforeground(const char *s1, const char *s2, const char *s3, const char *s4)
+dirforeground(const char *s1, const char *s2, const char *s3, const char *s4, const char *s5)
{
if (strlen(s1) == 0)
return -1;
@@ -273,7 +275,7 @@ dirforeground(const char *s1, const char *s2, const char *s3, const char *s4)
}
static int
-dirbackground(const char *s1, const char *s2, const char *s3, const char *s4)
+dirbackground(const char *s1, const char *s2, const char *s3, const char *s4, const char *s5)
{
if (strlen(s1) == 0)
return -1;
@@ -283,7 +285,7 @@ dirbackground(const char *s1, const char *s2, const char *s3, const char *s4)
}
static int
-dirborder(const char *s1, const char *s2, const char *s3, const char *s4)
+dirborder(const char *s1, const char *s2, const char *s3, const char *s4, const char *s5)
{
if (strlen(s1) == 0)
return -1;
@@ -293,7 +295,7 @@ dirborder(const char *s1, const char *s2, const char *s3, const char *s4)
}
static int
-dirfont(const char *s1, const char *s2, const char *s3, const char *s4)
+dirfont(const char *s1, const char *s2, const char *s3, const char *s4, const char *s5)
{
if (strlen(s1) == 0)
return -1;
@@ -303,7 +305,7 @@ dirfont(const char *s1, const char *s2, const char *s3, const char *s4)
}
static int
-dirtabs(const char *s1, const char *s2, const char *s3, const char *s4)
+dirtabs(const char *s1, const char *s2, const char *s3, const char *s4, const char *s5)
{
int i = atoi(s1);
if (i <= 0 || i > 12)
@@ -314,7 +316,7 @@ dirtabs(const char *s1, const char *s2, const char *s3, const char *s4)
}
static int
-direxpandtabs(const char *s1, const char *s2, const char *s3, const char *s4)
+direxpandtabs(const char *s1, const char *s2, const char *s3, const char *s4, const char *s5)
{
if (strcasecmp(s1, "true") != 0 && strcasecmp(s1, "false") != 0)
return -1;
@@ -327,14 +329,16 @@ typedef struct Directive Directive;
struct Directive{
const char *format;
int result;
- int (*action)(const char *, const char *, const char *, const char *);
+ int (*action)(const char *, const char *, const char *, const char *, const char *);
};
Directive directives[] ={
+ {" chord %5[Nn12345] %5[Nn12345] %99s %99s %1023[^\n]", 5, dirchord},
{" chord %5[Nn12345] %5[Nn12345] %99s %99s", 4, dirchord},
{" unchord %5[Nn12345] %5[Nn12345]", 2, dirunchord},
{" bind %5[*camshNCAMSH12345] %99s raw 0x%4[0-9a-fA-F]", 3, dirraw},
{" bind %5[*camshNCAMSH12345] %99s raw %1s", 3, dirrawliteral},
+ {" bind %5[*camshNCAMSH12345] %99s command %99s %1023[^\n]", 4, dirbind},
{" bind %5[*camshNCAMSH12345] %99s command %99s", 3, dirbind},
{" unbind %5[*camshNCAMSH12345] %99s", 2, dirunbind},
{" foreground %1023s", 1, dirforeground},
@@ -359,6 +363,7 @@ loadrcfile(FILE *f)
char s2[1024] = {0};
char s3[1024] = {0};
char s4[1024] = {0};
+ char s5[1024] = {0};
int rc = 0;
bool found = false;
@@ -367,8 +372,8 @@ loadrcfile(FILE *f)
continue;
for (Directive *d = directives; d->format && !found; d++){
- if (sscanf(l, d->format, s1, s2, s3, s4) == d->result){
- rc = d->action(s1, s2, s3, s4);
+ if (sscanf(l, d->format, s1, s2, s3, s4, s5) == d->result){
+ rc = d->action(s1, s2, s3, s4, s5);
found = true;
}
}
(DIR) diff --git a/samterm/samterm.h b/samterm/samterm.h
@@ -24,10 +24,10 @@ enum{
Ccut, /* cut dot */
Cpaste, /* paste from snarf buffer */
Cexchange, /* exchange snarf buffer with OS */
- Cwrite, /* write file */
Ceol, /* move to beginning of line */
Cbol, /* move to end of line */
Ctab, /* insert a possibly expanded tab */
+ Csend, /* send a command to the editor */
Cmax /* invalid command */
};
@@ -130,7 +130,7 @@ void Strgrow(Rune**, long*, int);
int RESHAPED(void);
void reshape(void);
void rcv(void);
-void type(Flayer*, int);
+void type(Flayer*);
void menu2hit(void);
void menu3hit(void);
void scroll(Flayer*, int, int);