mirror of
https://github.com/zsh-users/zsh
synced 2024-10-15 04:13:34 +00:00
17390: new zle parameters $PREDISPLAY, $POSTDISPLAY
This commit is contained in:
parent
964f819070
commit
1a1b108b34
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
Loading…
Reference in a new issue