summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--Doc/Zsh/zle.yo16
-rw-r--r--Src/Zle/zle_params.c54
-rw-r--r--Src/Zle/zle_refresh.c80
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';