diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | Doc/Zsh/zle.yo | 16 | ||||
-rw-r--r-- | Src/Zle/zle_params.c | 54 | ||||
-rw-r--r-- | Src/Zle/zle_refresh.c | 80 |
4 files changed, 132 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog index b81d847ac..d0d1fc742 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,10 @@ 2002-07-01 Peter Stephenson <pws@csr.com> + * 17390: Src/Zle/zle_params.c, Src/Zle/zle_refresh.c, + Doc/Zsh/zle.yo: $PREDISPLAY and $POSTDISPLAY are used to + add text before and after the editable chunk of the zle buffer. + * 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. diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 0cc1b52df..8022a1bdd 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -662,6 +662,22 @@ In a multi-line input at the secondary prompt, this read-only parameter contains the contents of the lines before the one the cursor is currently in. ) +vindex(PREDISPLAY) +item(tt(PREDISPLAY) (scalar))( +Text to be displayed before the start of the editable text buffer. This +does not have to be a complete line; to display a complete line, a newline +must be appended explicitly. Note that the text survives between calls to zle +and hence must be removed explicitly by assigning an empty value to the +parameter. +) +vindex(POSTDISPLAY) +item(tt(POSTDISPLAY) (scalar))( +Text to be displayed after the end of the editable text buffer. This +does not have to be a complete line; to display a complete line, a newline +must be prepended explicitly. Note that the text survives between calls to +zle and hence must be removed explicitly by assigning an empty value to the +parameter. +) vindex(RBUFFER) item(tt(RBUFFER) (scalar))( The part of the buffer that lies to the right of the cursor position. diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c index e2bbdd20b..ef8a98139 100644 --- a/Src/Zle/zle_params.c +++ b/Src/Zle/zle_params.c @@ -85,6 +85,10 @@ static struct zleparam { unset_cutbuffer, NULL }, { "killring", PM_ARRAY, FN(set_killring), FN(get_killring), unset_killring, NULL }, + { "PREDISPLAY", PM_SCALAR, FN(set_predisplay), FN(get_predisplay), + zleunsetfn, NULL }, + { "POSTDISPLAY", PM_SCALAR, FN(set_postdisplay), FN(get_postdisplay), + zleunsetfn, NULL }, { NULL, 0, NULL, NULL, NULL, NULL } }; @@ -462,3 +466,53 @@ unset_killring(Param pm, int exp) stdunsetfn(pm, exp); } } + +static void +set_prepost(unsigned char **textvar, int *lenvar, char *x) +{ + if (*lenvar) { + zfree(*textvar, *lenvar); + *textvar = NULL; + *lenvar = 0; + } + if (x) { + unmetafy(x, lenvar); + *textvar = (unsigned char *)zalloc(*lenvar); + memcpy((char *)*textvar, x, *lenvar); + free(x); + } +} + +static char * +get_prepost(unsigned char *text, int len) +{ + return metafy((char *)text, len, META_HEAPDUP); +} + +/**/ +static void +set_predisplay(Param pm, char *x) +{ + set_prepost(&predisplay, &predisplaylen, x); +} + +/**/ +static char * +get_predisplay(Param pm) +{ + return get_prepost(predisplay, predisplaylen); +} + +/**/ +static void +set_postdisplay(Param pm, char *x) +{ + set_prepost(&postdisplay, &postdisplaylen, x); +} + +/**/ +static char * +get_postdisplay(Param pm) +{ + return get_prepost(postdisplay, postdisplaylen); +} diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 17c373732..2223a35f4 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -81,6 +81,16 @@ mod_export int clearlist; /**/ int trashedzle; +/* + * Information used by PREDISPLAY and POSTDISPLAY parameters which + * add non-editable text to that being displayed. + */ +/**/ +unsigned char *predisplay, *postdisplay; +/**/ +int predisplaylen, postdisplaylen; + + #ifdef HAVE_SELECT /* cost of last update */ /**/ @@ -278,6 +288,10 @@ zrefresh(void) *sen, /* pointer to end of the video buffer (eol) */ *scs; /* pointer to cursor position in real buffer */ char **qbuf; /* tmp */ + unsigned char *tmpline; /* line with added pre/post text */ + int tmpcs, tmpll; /* ditto cursor position and line length */ + int tmpalloced; /* flag to free tmpline when finished */ + /* If this is called from listmatches() (indirectly via trashzle()), and * * that was called from the end of zrefresh(), then we don't need to do * @@ -286,6 +300,25 @@ zrefresh(void) if (inlist) return; + if (predisplaylen || postdisplaylen) { + /* There is extra text to display at the start or end of the line */ + tmpline = zalloc(ll + predisplaylen + postdisplaylen); + if (predisplaylen) + memcpy(tmpline, predisplay, predisplaylen); + if (ll) + memcpy(tmpline+predisplaylen, line, ll); + if (postdisplaylen) + memcpy(tmpline+predisplaylen+ll, postdisplay, postdisplaylen); + tmpcs = cs + predisplaylen; + tmpll = predisplaylen + ll + postdisplaylen; + tmpalloced = 1; + } else { + tmpline = line; + tmpcs = cs; + tmpll = ll; + tmpalloced = 0; + } + if (clearlist && listshown > 0) { if (tccan(TCCLEAREOD)) { int ovln = vln, ovcs = vcs; @@ -392,18 +425,18 @@ zrefresh(void) width comparisons can be made with winw, height comparisons with winh */ if (termflags & TERM_SHORT) { - singlerefresh(); + singlerefresh(tmpline, tmpll, tmpcs); goto singlelineout; } - if (cs < 0) { + if (tmpcs < 0) { #ifdef DEBUG fprintf(stderr, "BUG: negative cursor position\n"); fflush(stderr); #endif - cs = 0; + tmpcs = 0; } - scs = line + cs; + scs = tmpline + tmpcs; numscrolls = 0; /* first, we generate the video line buffers so we know what to put on @@ -414,9 +447,9 @@ zrefresh(void) *nbuf = (char *)zalloc(winw + 2); s = (unsigned char *)(nbuf[ln = 0] + lpromptw); - t = line; + t = tmpline; sen = (unsigned char *)(*nbuf + winw); - for (; t < line+ll; t++) { + for (; t < tmpline+tmpll; t++) { if (t == scs) /* if cursor is here, remember it */ nvcs = s - (unsigned char *)(nbuf[nvln = ln]); @@ -459,7 +492,7 @@ zrefresh(void) nvln++; } - if (t != line + ll) + if (t != tmpline + tmpll) more_end = 1; if (statusline) { @@ -646,6 +679,9 @@ individually */ singlelineout: fflush(shout); /* make sure everything is written out */ + if (tmpalloced) + zfree(tmpline, tmpll); + /* if we have a new list showing, note it; if part of the list has been overwritten, redisplay it. */ if (showinglist == -2 || (showinglist > 0 && showinglist < nlnct)) { @@ -1082,7 +1118,7 @@ redisplay(char **args) /**/ static void -singlerefresh(void) +singlerefresh(unsigned char *tmpline, int tmpll, int tmpcs) { char *vbuf, *vp, /* video buffer and pointer */ **qbuf, /* tmp */ @@ -1093,19 +1129,19 @@ singlerefresh(void) nlnct = 1; /* generate the new line buffer completely */ - for (vsiz = 1 + lpromptw, t0 = 0; t0 != ll; t0++, vsiz++) - if (line[t0] == '\t') + for (vsiz = 1 + lpromptw, t0 = 0; t0 != tmpll; t0++, vsiz++) + if (tmpline[t0] == '\t') vsiz = (vsiz | 7) + 1; - else if (icntrl(line[t0])) + else if (icntrl(tmpline[t0])) vsiz++; vbuf = (char *)zalloc(vsiz); - if (cs < 0) { + if (tmpcs < 0) { #ifdef DEBUG fprintf(stderr, "BUG: negative cursor position\n"); fflush(stderr); #endif - cs = 0; + tmpcs = 0; } /* only use last part of prompt */ @@ -1113,25 +1149,25 @@ singlerefresh(void) vbuf[lpromptw] = '\0'; vp = vbuf + lpromptw; - for (t0 = 0; t0 != ll; t0++) { - if (line[t0] == '\t') + for (t0 = 0; t0 != tmpll; t0++) { + if (tmpline[t0] == '\t') for (*vp++ = ' '; (vp - vbuf) & 7; ) *vp++ = ' '; - else if (line[t0] == '\n') { + else if (tmpline[t0] == '\n') { *vp++ = '\\'; *vp++ = 'n'; - } else if (line[t0] == 0x7f) { + } else if (tmpline[t0] == 0x7f) { *vp++ = '^'; *vp++ = '?'; - } else if (icntrl(line[t0])) { + } else if (icntrl(tmpline[t0])) { *vp++ = '^'; - *vp++ = line[t0] | '@'; + *vp++ = tmpline[t0] | '@'; } else - *vp++ = line[t0]; - if (t0 == cs) + *vp++ = tmpline[t0]; + if (t0 == tmpcs) nvcs = vp - vbuf - 1; } - if (t0 == cs) + if (t0 == tmpcs) nvcs = vp - vbuf; *vp = '\0'; |