From 9b923cccea05b93eeade4a69694985880d5affa2 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 5 Jan 2012 20:01:24 +0000 Subject: 30084: `zle -T tc func' for zle testing of termcap output --- ChangeLog | 12 +++++++- Doc/Zsh/zle.yo | 28 ++++++++++++++++++ Src/Zle/zle_main.c | 2 +- Src/Zle/zle_refresh.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++-- Src/Zle/zle_thingy.c | 64 ++++++++++++++++++++++++++++++++++++++++ Src/init.c | 13 +++++++++ 6 files changed, 196 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index a4e2c2931..22dcf483d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2012-01-05 Peter Stephenson + + * 30084: Doc/Zsh/zle.yo, Src/init.c, Src/Zle/zle_main.c, + Src/Zle/zle_refresh.c, Src/Zle/zle_thingy.c: `zle -T tc func' + defines function to be used insted of termcap output for + testing. + + * 30081: Completion/Base/Core/_main_complete: remove necessity + to have IGNORE_CLOSE_BRACES unset when loaded. + 2012-01-04 Frank Terbeck * 30079: Src/params.c: Restore `LC_ALL' when setting `LANG'. @@ -15819,5 +15829,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5554 $ +* $Revision: 1.5555 $ ***************************************************** diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 752247461..d3624b1ce 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -370,6 +370,7 @@ xitem(tt(zle) tt(-U) var(string)) xitem(tt(zle) tt(-K) var(keymap)) xitem(tt(zle) tt(-F) [ tt(-L) ] [ var(fd) [ var(handler) ] ]) xitem(tt(zle) tt(-I)) +xitem(tt(zle) tt(-T) [ tt(tc) var(function) | tt(-r) tt(tc) | tt(-L) ] ) item(tt(zle) var(widget) tt([ -n) var(num) tt(]) tt([ -Nw ] [ -K) var(keymap) tt(]) var(args) ...)( The tt(zle) builtin performs a number of different actions concerning ZLE. @@ -572,6 +573,33 @@ this may have been by a previous call to `tt(zle -I)' or by a system notification. To test if a zle widget may be called at this point, execute tt(zle) with no arguments and examine the return status. ) +item(tt(-T))( +This is used to add, list or remove internal transformations on the +processing performed by the line editor. It is typically used only for +debugging or testing and is therefore of little interest to the general +user. + +`tt(zle -T) var(transformation) var(func)' specifies that the +given var(transformation) (see below) is effected by shell function +var(func). + +`tt(zle -Tr) var(transformation)' removes the given var(transformation) +if it was present (it is not an error if none was). + +`tt(zle -TL)' can be used to list all transformations currently in +operation. + +Currently the only transformation is tt(tc). This is used instead +of outputting termcap codes to the terminal. When the transformation is +in operation the shell function is passed the termcap code that would be +output as its first argument; if the operation required a numeric +argument, that is passed as a second argument. The function should set +the shell variable tt(REPLY) to the transformed termcap code. Typically +this is used to produce some simply formatted version of the code and +optional argument for debugging or testing. Note that this +transformation is not applied to other non-printing characters such as +carriage returns and newlines. +) item(var(widget) tt([ -n) var(num) tt(]) tt([ -Nw ] [ -K) var(keymap) tt(]) var(args) ...)( Invoke the specified widget. This can only be done when ZLE is active; normally this will be within a user-defined widget. diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index e570d1d8c..e1a575bdb 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -1927,7 +1927,7 @@ zle_main_entry(int cmd, va_list ap) static struct builtin bintab[] = { BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaM:ldDANmrsLRp", NULL), BUILTIN("vared", 0, bin_vared, 1, 1, 0, "aAcehM:m:p:r:t:", NULL), - BUILTIN("zle", 0, bin_zle, 0, -1, 0, "aAcCDFgGIKlLmMNRU", NULL), + BUILTIN("zle", 0, bin_zle, 0, -1, 0, "aAcCDFgGIKlLmMNrRTU", NULL), }; /* The order of the entries in this table has to match the *HOOK diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 260df8bf6..17b78ce59 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -233,6 +233,12 @@ int n_region_highlights; /**/ int region_active; +/* + * Name of function to use to output termcap values, if defined. + */ +/**/ +char *tcout_func_name; + #ifdef HAVE_SELECT /* cost of last update */ /**/ @@ -2271,11 +2277,78 @@ tc_downcurs(int ct) return ret; } +/* + * Output a termcap value using a function defined by "zle -T tc". + * Loosely inspired by subst_string_by_func(). + * + * cap is the internal index for the capability; it will be looked up + * in the table and the string passed to the function. + * + * arg is eithr an argument to the capability or -1 if there is none; + * if it is not -1 it will be passed as an additional argument to the + * function. + * + * outc is the output function; currently this is always putshout + * but in principle it may be used to output to a string. + */ + +/**/ +static void +tcout_via_func(int cap, int arg, int (*outc)(int)) +{ + Shfunc tcout_func; + int osc, osm, old_incompfunc; + + osc = sfcontext; + osm = stopmsg; + old_incompfunc = incompfunc; + + sfcontext = SFC_SUBST; + incompfunc = 0; + + if ((tcout_func = getshfunc(tcout_func_name))) { + LinkList l = newlinklist(); + char buf[DIGBUFSIZE], *str; + + addlinknode(l, tcout_func_name); + addlinknode(l, tccap_get_name(cap)); + + if (arg != -1) { + sprintf(buf, "%d", arg); + addlinknode(l, buf); + } + + (void)doshfunc(tcout_func, l, 1); + + str = getsparam("REPLY"); + if (str) { + while (*str) { + int chr; + if (*str == Meta) { + chr = str[1] ^ 32; + str += 2; + } else { + chr = *str++; + } + (void)outc(chr); + } + } + } + + sfcontext = osc; + stopmsg = osm; + incompfunc = old_incompfunc; +} + /**/ mod_export void tcout(int cap) { - tputs(tcstr[cap], 1, putshout); + if (tcout_func_name) { + tcout_via_func(cap, -1, putshout); + } else { + tputs(tcstr[cap], 1, putshout); + } SELECT_ADD_COST(tclen[cap]); } @@ -2286,7 +2359,11 @@ tcoutarg(int cap, int arg) char *result; result = tgoto(tcstr[cap], arg, arg); - tputs(result, 1, putshout); + if (tcout_func_name) { + tcout_via_func(cap, arg, putshout); + } else { + tputs(result, 1, putshout); + } SELECT_ADD_COST(strlen(result)); } diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c index 03e73b4ca..49d715e06 100644 --- a/Src/Zle/zle_thingy.c +++ b/Src/Zle/zle_thingy.c @@ -353,6 +353,7 @@ bin_zle(char *name, char **args, Options ops, UNUSED(int func)) { 'K', bin_zle_keymap, 1, 1 }, { 'I', bin_zle_invalidate, 0, 0 }, { 'F', bin_zle_fd, 0, 2 }, + { 'T', bin_zle_transform, 0, 2}, { 0, bin_zle_call, 0, -1 }, }; struct opn const *op, *opp; @@ -856,6 +857,69 @@ bin_zle_fd(char *name, char **args, Options ops, UNUSED(char func)) return 0; } +/**/ +static int +bin_zle_transform(char *name, char **args, Options ops, UNUSED(char func)) +{ + /* + * -1: too few arguments + * 0: just right + * 1: too many arguments + * 2: first argument not recognised + */ + int badargs = 0; + + if (OPT_ISSET(ops,'L')) { + if (args[0]) { + if (args[1]) { + badargs = 1; + } else if (strcmp(args[0], "tc")) { + badargs = 2; + } + } + if (!badargs && tcout_func_name) { + fputs("zle -T tc ", stdout); + quotedzputs(tcout_func_name, stdout); + putchar('\n'); + } + } else if (OPT_ISSET(ops,'r')) { + if (!args[0]) { + badargs = -1; + } else if (args[1]) { + badargs = 1; + } else if (tcout_func_name) { + zsfree(tcout_func_name); + tcout_func_name = NULL; + } + } else { + if (!args[0] || !args[1]) { + badargs = -1; + /* we've already checked args <= 2 */ + } else { + if (!strcmp(args[0], "tc")) { + if (tcout_func_name) { + zsfree(tcout_func_name); + } + tcout_func_name = ztrdup(args[1]); + } else { + badargs = 2; + } + } + } + + if (badargs) { + if (badargs == 2) { + zwarnnam(name, "-T: no such transformation '%s'", args[0]); + } else { + char *way = (badargs > 0) ? "many" : "few"; + zwarnnam(name, "too %s arguments for option -T", way); + } + return 1; + } + + return 0; +} + /*******************/ /* initialiasation */ /*******************/ diff --git a/Src/init.c b/Src/init.c index 29191410e..9820070fb 100644 --- a/Src/init.c +++ b/Src/init.c @@ -558,6 +558,19 @@ static char *tccapnams[TC_COUNT] = { "ku", "kd", "kl", "kr", "sc", "rc", "bc", "AF", "AB" }; +/**/ +mod_export char * +tccap_get_name(int cap) +{ + if (cap >= TC_COUNT) { +#ifdef DEBUG + dputs("name of invalid capability %d requested", cap); +#endif + return ""; + } + return tccapnams[cap]; +} + /* Initialise termcap */ /**/ -- cgit 1.4.1