summaryrefslogtreecommitdiff
path: root/Src/Zle/zle_refresh.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle/zle_refresh.c')
-rw-r--r--Src/Zle/zle_refresh.c71
1 files changed, 61 insertions, 10 deletions
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index b45047ac2..da9fe45b7 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -333,7 +333,8 @@ zrefresh(void)
*qbuf; /* tmp */
int tmpcs, tmpll; /* ditto cursor position and line length */
int tmpalloced; /* flag to free tmpline when finished */
-
+ int remetafy; /* flag that zle line is metafied */
+
if (trashedzle)
reexpandprompt();
@@ -344,6 +345,17 @@ zrefresh(void)
if (inlist)
return;
+ /*
+ * zrefresh() is called from all over the place, so we can't
+ * be sure if the line is metafied for completion or not.
+ */
+ if (zlemetaline != NULL) {
+ remetafy = 1;
+ unmetafy_line();
+ }
+ else
+ remetafy = 0;
+
if (predisplaylen || postdisplaylen) {
/* There is extra text to display at the start or end of the line */
tmpline = zalloc((zlell + predisplaylen + postdisplaylen)*sizeof(*tmpline));
@@ -743,6 +755,9 @@ singlelineout:
}
if (showinglist == -1)
showinglist = nlnct;
+
+ if (remetafy)
+ metafy_line();
}
#define tcinscost(X) (tccan(TCMULTINS) ? tclen[TCMULTINS] : (X)*tclen[TCINS])
@@ -1189,6 +1204,12 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
int t0, /* tmp */
vsiz, /* size of new video buffer */
nvcs = 0; /* new video cursor column */
+#ifdef ZLE_UNICODE_SUPPORT
+ ZLE_STRING_T lpwbuf, lpwp; /* converted lprompt and pointer */
+ char *lpptr, /* pointer into multibyte lprompt */
+ lpend; /* end of multibyte lprompt */
+ mbstate_t ps; /* shift state */
+#endif
nlnct = 1;
/* generate the new line buffer completely */
@@ -1208,14 +1229,44 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
}
/* only use last part of prompt */
- /* TODO convert prompt to wide char */
#ifdef ZLE_UNICODE_SUPPORT
- t0 = mbtowc(vbuf, strchr(lpromptbuf, 0) - lpromptw, lpromptw);
- if (t0 >= 0) {
- vbuf[t0] = ZWC('\0');
- vp = vbuf + t0;
- } else
- /* FIXME What to do? */ ;
+ /*
+ * Convert the entire lprompt so that we know how to count
+ * characters.
+ *
+ * TODO screen widths are still not correct, indeed lpromptw knows
+ * nothing about multibyte characters so may be too long.
+ */
+ lpend = strchr(lpromptbuf, 0);
+ /* Worst case number of characters, not null-terminated */
+ lpwp = lpwbuf = (ZLE_STRING_T)zalloc((lpend - lpromptbuf)
+ * sizeof(*lpwbuf));
+ /* Reset shift state, maybe. */
+ memset(&ps, '\0', sizeof(ps));
+ for (lpptr = lpromptbuf; lpptr < lpend; ) {
+ t0 = mbrtowc(lpwp, lpptr, lpend - lpptr, &ps);
+ if (t0 > 0) {
+ /* successfully converted */
+ lpptr += t0;
+ lpwp++;
+ } else {
+ /* dunno, try to recover */
+ lpptr++;
+ *lpwp++ = ZWC('?');
+ }
+ }
+ if (lpwp - lpwbuf < lpromptw) {
+ /* Not enough characters for lpromptw. */
+ ZS_memcpy(vbuf, lpwbuf, lpwp - lpwbuf);
+ vp = vbuf + (lpwp - lpwbuf);
+ while (vp < vbuf + lpromptw)
+ *vp++ = ZWC(' ');
+ } else {
+ ZS_memcpy(vbuf, lpwp - lpromptw, lpromptw);
+ vp = vbuf + lpromptw;
+ }
+ *vp = ZWC('\0');
+ zfree(lpwbuf, lpromptw * sizeof(*lpwbuf));
#else
memcpy(vbuf, strchr(lpromptbuf, 0) - lpromptw, lpromptw);
vbuf[lpromptw] = '\0';
@@ -1223,10 +1274,10 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
#endif
for (t0 = 0; t0 < tmpll; t0++) {
- if (tmpline[t0] == ZWC('\t'))
+ if (tmpline[t0] == ZWC('\t')) {
for (*vp++ = ZWC(' '); (vp - vbuf) & 7; )
*vp++ = ZWC(' ');
- else if (tmpline[t0] == ZWC('\n')) {
+ } else if (tmpline[t0] == ZWC('\n')) {
*vp++ = ZWC('\\');
*vp++ = ZWC('n');
} else if (ZC_icntrl(tmpline[t0])) {