From c96e31a707ffdc675688be2feaae1428aee72a02 Mon Sep 17 00:00:00 2001 From: tg Date: Wed, 2 Aug 2006 13:32:18 +0000 Subject: [PATCH] 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 --- edit.c | 39 +++++++++++++++++++++++++++++---------- mksh.1 | 17 ++++++++++++----- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/edit.c b/edit.c index ee020f3..772f5e0 100644 --- a/edit.c +++ b/edit.c @@ -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 */ diff --git a/mksh.1 b/mksh.1 index 3e03310..f766abd 100644 --- a/mksh.1 +++ b/mksh.1 @@ -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