implement a hack whereas you can now bind functions (and macros)

to keys with a trailing tilde (after prefix + control char); the
function is then invoked after prefices, control char and one more
character X are entered; if X is not a tilde, it is ungetc(3)d
This commit is contained in:
tg 2006-08-02 13:32:18 +00:00
parent b99aa06d9b
commit c96e31a707
2 changed files with 41 additions and 15 deletions

39
edit.c
View File

@ -5,7 +5,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.31 2006/08/02 12:54:48 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.32 2006/08/02 13:32:17 tg Exp $");
/* tty driver characters we are interested in */
typedef struct {
@ -1015,6 +1015,8 @@ static void bind_if_not_bound(int, int, int);
#define XFUNC_comment 54
#define XFUNC_version 55
/* XFUNC_* must be < 128 */
static int x_abort (int);
static int x_beg_hist (int);
static int x_comp_comm (int);
@ -1214,6 +1216,9 @@ static struct x_defbindings const x_defbindings[] = {
{ XFUNC_next_com, 2, 'B' },
{ XFUNC_mv_forw, 2, 'C' },
{ XFUNC_mv_back, 2, 'D' },
{ XFUNC_mv_begin | 0x80, 2, '1' },
{ XFUNC_mv_end | 0x80, 2, '4' },
{ XFUNC_eot_del | 0x80, 2, '3' },
};
int
@ -1266,6 +1271,11 @@ x_emacs(char *buf, size_t len)
}
f = x_curprefix == -1 ? XFUNC_insert :
x_tab[x_curprefix][c & CHARMASK];
if (f & 0x80) {
f &= 0x7F;
if ((i = x_e_getc()) != '~')
x_e_ungetc(i);
}
if (!(x_ftab[f].xf_flags & XF_PREFIX) &&
x_last_command != XFUNC_set_arg) {
@ -1795,6 +1805,11 @@ x_search_hist(int c)
if ((c = x_e_getc()) < 0)
return KSTD;
f = x_tab[0][c & CHARMASK];
if (f & 0x80) {
f &= 0x7F;
if ((c = x_e_getc()) != '~')
x_e_ungetc(c);
}
if (c == MKCTRL('['))
break;
else if (f == XFUNC_search_hist)
@ -2210,13 +2225,15 @@ x_mapout(int c)
static void
x_print(int prefix, int key)
{
int f = x_tab[prefix][key];
if (prefix == 1)
shprintf("%s", x_mapout(x_prefix1));
if (prefix == 2)
shprintf("%s", x_mapout(x_prefix2));
shprintf("%s = ", x_mapout(key));
if (x_tab[prefix][key] != XFUNC_ins_string)
shprintf("%s\n", x_ftab[x_tab[prefix][key]].xf_name);
shprintf("%s%s = ", x_mapout(key), (f & 0x80) ? "~" : "");
if ((f & 0x7F) != XFUNC_ins_string)
shprintf("%s\n", x_ftab[f & 0x7F].xf_name);
else
shprintf("'%s'\n", x_atab[prefix][key]);
}
@ -2246,7 +2263,7 @@ x_bind(const char *a1, const char *a2,
if (a1 == NULL) {
for (prefix = 0; prefix < X_NTABS; prefix++)
for (key = 0; key < X_TABSZ; key++) {
f = x_tab[prefix][key];
f = x_tab[prefix][key] & 0x7F;
if (f == XFUNC_insert || f == XFUNC_error ||
(macro && f != XFUNC_ins_string))
continue;
@ -2258,14 +2275,15 @@ x_bind(const char *a1, const char *a2,
prefix = key = 0;
for (;; m1++) {
key = *m1 & CHARMASK;
if (x_tab[prefix][key] == XFUNC_meta1)
f = x_tab[prefix][key] & 0x7F;
if (f == XFUNC_meta1)
prefix = 1;
else if (x_tab[prefix][key] == XFUNC_meta2)
else if (f == XFUNC_meta2)
prefix = 2;
else
break;
}
if (*++m1) {
if (*++m1 && ((*m1 != '~') || *(m1+1))) {
char msg[256] = "bind: key sequence '";
const char *c = a1;
while (*c)
@ -2295,9 +2313,10 @@ x_bind(const char *a1, const char *a2,
sp = str_save(m2, AEDIT);
}
if (x_tab[prefix][key] == XFUNC_ins_string && x_atab[prefix][key])
if ((x_tab[prefix][key] & 0x7F) == XFUNC_ins_string &&
x_atab[prefix][key])
afree((void *)x_atab[prefix][key], AEDIT);
x_tab[prefix][key] = f;
x_tab[prefix][key] = f | ((*m1) ? 0x80 : 0);
x_atab[prefix][key] = sp;
/* Track what the user has bound so x_emacs_keys() won't toast things */

17
mksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.45 2006/08/02 11:50:28 tg Exp $
.\" $MirOS: src/bin/mksh/mksh.1,v 1.46 2006/08/02 13:32:18 tg Exp $
.\" $OpenBSD: ksh.1,v 1.116 2006/07/26 10:13:25 jmc Exp $
.\" $OpenBSD: sh.1tbl,v 1.53 2004/12/10 01:56:56 jaredy Exp $
.\"
@ -2451,7 +2451,8 @@ for more information.
The specified editing command is bound to the given
.Ar string ,
which should consist of a control character
optionally preceded by one of the two prefix characters.
optionally preceded by one of the two prefix characters
and optionally succeded by a tilde character.
Future input of the
.Ar string
will cause the editing command to be immediately invoked.
@ -2462,14 +2463,17 @@ flag is given, the specified input
will afterwards be immediately replaced by the given
.Ar substitute
string which may contain editing commands.
If a tilde postfix is given, a tilde trailing the one or
two prefices and the control character is ignored, any
other trailing character will be processed afterwards.
.Pp
Control characters may be written using caret notation
i.e. ^X represents Control-X.
Note that although only two prefix characters (usually ESC and ^X)
are supported, some multi-character sequences can be supported.
.Pp
The following default bindings show how the arrow keys
on an ANSI terminal or xterm are bound
The following default bindings show how the arrow keys, the
home, end and delete key on an ANSI terminal or xterm are bound
(of course some escape sequences won't work out quite this nicely):
.Bd -literal -offset indent
bind '^[['=prefix-2
@ -2477,6 +2481,9 @@ bind '^XA'=up-history
bind '^XB'=down-history
bind '^XC'=forward-char
bind '^XD'=backward-char
bind '^X1~'=beginning-of-line
bind '^X3~'=eot-or-delete
bind '^X4~'=end-of-line
.Ed
.Pp
.It Ic break Op Ar level
@ -5268,7 +5275,7 @@ projects and patches and suggestions from users
and many other persons.
.Sh BUGS
This document attempts to describe
.Nm "" R27 .
.Nm "" R28 .
The O'Reilly book documents the
.At
.Nm KSH88