diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Doc/Zsh/zle.yo | 42 | ||||
-rw-r--r-- | Src/Zle/iwidgets.list | 1 | ||||
-rw-r--r-- | Src/Zle/zle_main.c | 152 |
4 files changed, 135 insertions, 66 deletions
diff --git a/ChangeLog b/ChangeLog index d4d213167..b90f8cef6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2002-07-01 Peter Stephenson <pws@csr.com> + + * 17384: Src/Zle/zle_main.c, Src/Zle/iwidgets.list, + Doc/Zsh/zle.yo: new `recursive-edit' widget allows a user-defined + widget to pass control back to zle as a subcommand. + 2002-07-01 Sven Wischnowsky <wischnow@zsh.org> * 17387: Completion/Zsh/Context/.distfiles, diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index f7210e7a6..0cc1b52df 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -1620,6 +1620,48 @@ At a secondary (tt(PS2)) prompt, move the entire current multiline construct into the editor buffer. The latter is equivalent to tt(push-input) followed by tt(get-line). ) +tindex(recursive-edit) +item(tt(recursive-edit))( +Only useful from a user-defined widget. At this point in the function, +the editor regains control until one of the standard widgets which would +normally cause zle to exit (typically an tt(accept-line) caused by +hitting the return key) is executed. Instead, control returns to the +user-defined widget. The status returned is non-zero if the return was +caused by an error, but the function still continues executing and hence +may tidy up. This makes it safe for the user-defined widget to alter +the command line or key bindings temporarily. + + +The following widget, tt(caps-lock), serves as an example. +example(self-insert-ucase() { + LBUFFER+=${(U)KEYS[-1]} +} + +integer stat + +zle -N self-insert self-insert-ucase +zle -A caps-lock save-caps-lock +zle -A accept-line caps-lock + +zle recursive-edit +stat=$? + +zle -A .self-insert self-insert +zle -A save-caps-lock caps-lock +zle -D save-caps-lock + +(( stat )) && zle send-break + +return $stat +) +This causes typed letters to be inserted capitalised until either +tt(accept-line) (i.e. typically the return key) is typed or the +tt(caps-lock) widget is invoked again; the later is handled by saving +the old definition of tt(caps-lock) as tt(save-caps-lock) and then +rebinding it to invoke tt(accept-line). Note that an error from the +recursive edit is detected as a non-zero return status and propagated by +using the tt(send-break) widget. +) tindex(redisplay) item(tt(redisplay) (unbound) (^R) (^R))( Redisplays the edit buffer. diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list index da5bcc531..fbd45dacc 100644 --- a/Src/Zle/iwidgets.list +++ b/Src/Zle/iwidgets.list @@ -85,6 +85,7 @@ "quoted-insert", quotedinsert, ZLE_MENUCMP | ZLE_KEEPSUFFIX "quote-line", quoteline, 0 "quote-region", quoteregion, 0 +"recursive-edit", recursiveedit, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL "redisplay", redisplay, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL "redo", redo, ZLE_KEEPSUFFIX "reverse-menu-complete", reversemenucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 782bd472c..9332b509d 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -89,10 +89,11 @@ mod_export int eofchar; static int eofsent; static long keytimeout; -#ifdef HAVE_SELECT +#if defined(HAVE_SELECT) || defined(HAVE_POLL) /* Terminal baud rate */ static int baud; +static long costmult; #endif /* flags associated with last command */ @@ -631,6 +632,74 @@ getkey(int keytmout) return ret; } +/**/ +void +zlecore(void) +{ +#if !defined(HAVE_POLL) && defined(HAVE_SELECT) + struct timeval tv; + fd_set foofd; + + FD_ZERO(&foofd); +#endif + + zrefresh(); + + while (!done && !errflag) { + + statusline = NULL; + vilinerange = 0; + reselectkeymap(); + selectlocalmap(NULL); + bindk = getkeycmd(); + if (!ll && isfirstln && unset(IGNOREEOF) && c == eofchar) { + eofsent = 1; + break; + } + if (bindk) { + if (execzlefunc(bindk, zlenoargs)) + handlefeep(zlenoargs); + handleprefixes(); + /* for vi mode, make sure the cursor isn't somewhere illegal */ + if (invicmdmode() && cs > findbol() && + (cs == ll || line[cs] == '\n')) + cs--; + if (undoing) + handleundo(); + } else { + errflag = 1; + break; + } +#ifdef HAVE_POLL + if (baud && !(lastcmd & ZLE_MENUCMP)) { + struct pollfd pfd; + int to = cost * costmult / 1000; /* milliseconds */ + + if (to > 500) + to = 500; + pfd.fd = SHTTY; + pfd.events = POLLIN; + if (!kungetct && poll(&pfd, 1, to) <= 0) + zrefresh(); + } else +#else +# ifdef HAVE_SELECT + if (baud && !(lastcmd & ZLE_MENUCMP)) { + FD_SET(SHTTY, &foofd); + tv.tv_sec = 0; + if ((tv.tv_usec = cost * costmult) > 500000) + tv.tv_usec = 500000; + if (!kungetct && select(SHTTY+1, (SELECT_ARG_2_T) & foofd, + NULL, NULL, &tv) <= 0) + zrefresh(); + } else +# endif +#endif + if (!kungetct) + zrefresh(); + } +} + /* Read a line. It is returned metafied. */ /**/ @@ -641,14 +710,7 @@ zleread(char *lp, char *rp, int flags) int old_errno = errno; int tmout = getiparam("TMOUT"); -#if defined(HAVE_SELECT) || defined(HAVE_POLL) - long costmult; -# ifdef HAVE_POLL -# else - struct timeval tv; - fd_set foofd; -# endif - +#if defined(HAVE_POLL) || defined(HAVE_SELECT) baud = getiparam("BAUD"); costmult = (baud) ? 3840000L / baud : 0; #endif @@ -693,11 +755,6 @@ zleread(char *lp, char *rp, int flags) zlereadflags = flags; histline = curhist; -#ifndef HAVE_POLL -# ifdef HAVE_SELECT - FD_ZERO(&foofd); -# endif -#endif undoing = 1; line = (unsigned char *)zalloc((linesz = 256) + 2); virangeflag = lastcmd = done = cs = ll = mark = 0; @@ -732,60 +789,9 @@ zleread(char *lp, char *rp, int flags) lastcol = -1; initmodifier(&zmod); prefixflag = 0; - zrefresh(); - while (!done && !errflag) { - statusline = NULL; - vilinerange = 0; - reselectkeymap(); - selectlocalmap(NULL); - bindk = getkeycmd(); - if (!ll && isfirstln && unset(IGNOREEOF) && c == eofchar) { - eofsent = 1; - break; - } - if (bindk) { - if (execzlefunc(bindk, zlenoargs)) - handlefeep(zlenoargs); - handleprefixes(); - /* for vi mode, make sure the cursor isn't somewhere illegal */ - if (invicmdmode() && cs > findbol() && - (cs == ll || line[cs] == '\n')) - cs--; - if (undoing) - handleundo(); - } else { - errflag = 1; - break; - } -#ifdef HAVE_POLL - if (baud && !(lastcmd & ZLE_MENUCMP)) { - struct pollfd pfd; - int to = cost * costmult / 1000; /* milliseconds */ + zlecore(); - if (to > 500) - to = 500; - pfd.fd = SHTTY; - pfd.events = POLLIN; - if (!kungetct && poll(&pfd, 1, to) <= 0) - zrefresh(); - } else -#else -# ifdef HAVE_SELECT - if (baud && !(lastcmd & ZLE_MENUCMP)) { - FD_SET(SHTTY, &foofd); - tv.tv_sec = 0; - if ((tv.tv_usec = cost * costmult) > 500000) - tv.tv_usec = 500000; - if (!kungetct && select(SHTTY+1, (SELECT_ARG_2_T) & foofd, - NULL, NULL, &tv) <= 0) - zrefresh(); - } else -# endif -#endif - if (!kungetct) - zrefresh(); - } statusline = NULL; invalidatelist(); trashzle(); @@ -1234,6 +1240,20 @@ whereis(char **args) } /**/ +int +recursiveedit(char **args) +{ + int locerror; + + zlecore(); + + locerror = errflag; + errflag = done = 0; + + return locerror; +} + +/**/ mod_export void trashzle(void) { |