Added the unbind and unchord samrc directives. - 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 37bf82df8a1adab4f40e844ddc65d8e977d2ba0d
(DIR) parent 6a54452391a83964a0a5a955185926c56d7dd4e7
(HTM) Author: Rob King <jking@deadpixi.com>
Date: Sat, 10 Sep 2016 16:12:07 -0500
Added the unbind and unchord samrc directives.
Diffstat:
doc/samrc.5 | 39 +++++++++++++++++++++++++++++++
include/libg.h | 8 ++++++++
libXg/gwin.c | 68 ++++++++++++++++++++++++++-----
samterm/samrc.c | 10 ++++++++--
samterm/samterm.h | 44 ++++++++++++++++----------------
5 files changed, 135 insertions(+), 34 deletions(-)
---
(DIR) diff --git a/doc/samrc.5 b/doc/samrc.5
@@ -65,6 +65,23 @@ specification of a character
.Pq "for raw and composed characters" "."
.Pp
Note that keyboard symbol names are implementation-defined and often case-sensitive.
+.It unbind
+Remove all bindings associated with a key sequence.
+The form is:
+.Bd -literal
+
+ unbind M K
+
+.Ed
+where
+.Em M
+is a string describing a set of modifier keys and
+.Em K
+is the name of a keyboard symbol,
+as for
+.Dq bind
+above.
+The key sequence may be subsequently rebound.
.It chord
Bind a mouse chord to a command.
The form is:
@@ -93,6 +110,20 @@ see
.Sx "Targets"
below
.Pc "."
+.It unchord
+Remove all bindings for a given mouse chord.
+The form is:
+.Bd -literal
+
+ unchord S1 S2
+
+.Ed
+where
+.Em S1
+and
+.Em S2
+are strings describing the initial and following mouse button states.
+The chord may be subsequently rebound.
.It foreground
Names the color used to draw text.
It is of the form:
@@ -214,6 +245,14 @@ write Write current file None
eol Move to end of line None
bol Move to beginning of line None
.TE
+.Pp
+Additionally,
+the command name
+.Dq none
+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.
.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
@@ -105,6 +105,12 @@ enum{
};
enum{
+ Cnone, /* no command */
+ Cdefault, /* default action */
+ Csysmax
+};
+
+enum{
Tcurrent, /* command is sent to focused layer */
Tmouse /* command is sent to layer containing the mouse */
};
@@ -244,6 +250,8 @@ extern XftColor bgcolor;
extern int installbinding(int, KeySym, int, int);
extern int installchord(int, int, int, int);
+extern int removebinding(int, KeySym);
+extern int removechord(int, int);
extern char foregroundspec[1024];
extern char backgroundspec[1024];
(DIR) diff --git a/libXg/gwin.c b/libXg/gwin.c
@@ -213,6 +213,20 @@ installbinding(int m, KeySym s, int k, int c)
return 0;
}
+int
+removebinding(int m, KeySym s)
+{
+ if (m < 0 || s == NoSymbol)
+ return -1;
+
+ for (Keymapping *km = keymappings; km; km = km->next){
+ if (km->m == m && km->s == s)
+ km->c = Cdefault;
+ }
+
+ return 0;
+}
+
void
freebindings(void)
{
@@ -255,10 +269,19 @@ Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
if (l == m->s){
if (m->m == 0 || (m->m & ~e->xkey.state) == 0){
- f = ((GwinWidget)w)->gwin.gotchar;
- if (f)
- (*f)(m->c, m->k, Tcurrent, 0, 0);
- return;
+ switch (m->c){
+ case Cnone:
+ return;
+
+ case Cdefault:
+ continue;
+
+ default:
+ f = ((GwinWidget)w)->gwin.gotchar;
+ if (f)
+ (*f)(m->c, m->k, Tcurrent, 0, 0);
+ return;
+ }
}
}
}
@@ -369,6 +392,20 @@ installchord(int s1, int s2, int c, int t)
return 0;
}
+int
+removechord(int s1, int s2)
+{
+ if (s1 < 0 || s2 < 0)
+ return -1;
+
+ for (Chordmapping *m = chordmap; m; m = m->next){
+ if (m->s1 == s1 && m->s2 == s2)
+ m->c = Cdefault;
+ }
+
+ return 0;
+}
+
void
freechords(void)
{
@@ -387,6 +424,7 @@ Mouseaction(Widget w, XEvent *e, String *p, Cardinal *np)
int ps = 0; /* the previous state */
int ob = 0;
static bool chording = false;
+ Charfunc kf;
XButtonEvent *be = (XButtonEvent *)e;
XMotionEvent *me = (XMotionEvent *)e;
@@ -450,12 +488,22 @@ Mouseaction(Widget w, XEvent *e, String *p, Cardinal *np)
/* Check to see if it's a chord first. */
for (Chordmapping *cm = chordmap; cm; cm = cm->next){
if (ob == cm->s1 && m.buttons == cm->s2){
- Charfunc kf = ((GwinWidget)w)->gwin.gotchar;
- if (kf)
- (*kf)(cm->c, Kcommand, cm->t, m.xy.x, m.xy.y);
-
- m.buttons = 0;
- chording = true;
+ switch (cm->c){
+ case Cdefault:
+ continue;
+
+ case Cnone:
+ break;
+
+ default:
+ kf = ((GwinWidget)w)->gwin.gotchar;
+ if (kf)
+ (*kf)(cm->c, Kcommand, cm->t, m.xy.x, m.xy.y);
+
+ m.buttons = 0;
+ chording = true;
+ break;
+ }
}
}
(DIR) diff --git a/samterm/samrc.c b/samterm/samrc.c
@@ -21,6 +21,8 @@ struct Namemapping{
};
static Namemapping commandmapping[] ={
+ {"none", Cnone},
+ {"default", Cdefault},
{"escape", Cescape},
{"scrolldown", Cscrolldown},
{"scrollup", Cscrollup},
@@ -216,8 +218,8 @@ loadrcfile(FILE *f)
size_t ln = 0;
while ((r = getline(&l, &n, f)) >= 0){
- char s1[6] = {0};
- char s2[6] = {0};
+ char s1[100] = {0};
+ char s2[100] = {0};
char cname[1024] = {0};
char tname[1024] = {0};
char c = 0;
@@ -241,6 +243,10 @@ loadrcfile(FILE *f)
rc = installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kcomposed, c);
else if (sscanf(l, " bind %5[*camshNCAMSH12345] %99s command %99s", s1, s2, cname) == 3)
rc = installbinding(statetomask(s1, modmapping), XStringToKeysym(s2), Kcommand, nametocommand(cname));
+ else if (sscanf(l, " unbind %5[*camshNCAMSH12345] %99s", s1, s2) == 2)
+ rc = removebinding(statetomask(s1, modmapping), XStringToKeysym(s2));
+ else if (sscanf(l, " unchord %5[Nn12345] %5[Nn12345]", s1, s2) == 2)
+ rc = removechord(statetomask(s1, buttonmapping), statetomask(s2, buttonmapping));
else if (sscanf(l, " foreground %1023s", cname) == 1)
strncpy(foregroundspec, cname, sizeof(foregroundspec) - 1);
else if (sscanf(l, " background %1023s", cname) == 1)
(DIR) diff --git a/samterm/samterm.h b/samterm/samterm.h
@@ -6,28 +6,28 @@
#define NL 5
enum{
- Cnone, /* invalid command */
- Cescape, /* highlight recently typed text */
- Cscrolldown, /* scroll file down by screen */
- Cscrollup, /* scroll file up by screen */
- Cscrolldownline, /* scroll file down by line */
- Cscrollupline, /* scroll file up by line */
- Cjump, /* jump to/from command file */
- Ccharright, /* move dot right by character */
- Ccharleft, /* move dot left by character */
- Clinedown, /* move dot down by line */
- Clineup, /* move dot up by line */
- Cdelword, /* delete word to left of dot */
- Cdelbol, /* delete to beginning of line */
- Cdel, /* delete character to left of dot */
- Csnarf, /* snarf dot */
- 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 */
- Cmax /* invalid command */
+
+ Cescape = Csysmax + 1, /* highlight recently typed text */
+ Cscrolldown, /* scroll file down by screen */
+ Cscrollup, /* scroll file up by screen */
+ Cscrolldownline, /* scroll file down by line */
+ Cscrollupline, /* scroll file up by line */
+ Cjump, /* jump to/from command file */
+ Ccharright, /* move dot right by character */
+ Ccharleft, /* move dot left by character */
+ Clinedown, /* move dot down by line */
+ Clineup, /* move dot up by line */
+ Cdelword, /* delete word to left of dot */
+ Cdelbol, /* delete to beginning of line */
+ Cdel, /* delete character to left of dot */
+ Csnarf, /* snarf dot */
+ 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 */
+ Cmax /* invalid command */
};
enum{