17390: new zle parameters $PREDISPLAY, $POSTDISPLAY

This commit is contained in:
Peter Stephenson 2002-07-01 16:50:41 +00:00
parent 964f819070
commit 1a1b108b34
4 changed files with 132 additions and 22 deletions

View file

@ -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.

View file

@ -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.

View file

@ -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);
}

View file

@ -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';