diff options
Diffstat (limited to 'Src/Zle')
-rw-r--r-- | Src/Zle/zle_refresh.c | 337 |
1 files changed, 184 insertions, 153 deletions
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index a8c47e843..bb8945192 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -253,65 +253,20 @@ scrollwindow(int tline) return; } -/* this is the messy part. */ -/* this define belongs where it's used!!! */ - -#define nextline \ -{ \ - *s = ZWC('\0'); \ - if (ln != winh - 1) \ - ln++; \ - else { \ - if (!canscroll) { \ - if (nvln != -1 && nvln != winh - 1 \ - && (numscrolls != onumscrolls - 1 \ - || nvln <= winh / 2)) \ - break; \ - numscrolls++; \ - canscroll = winh / 2; \ - } \ - canscroll--; \ - scrollwindow(0); \ - if (nvln != -1) \ - nvln--; \ - } \ - if (!nbuf[ln]) \ - nbuf[ln] = (ZLE_STRING_T)zalloc((winw + 2) * sizeof(**nbuf)); \ - s = nbuf[ln]; \ - sen = s + winw; \ -} - -#define snextline \ -{ \ - *s = ZWC('\0'); \ - if (ln != winh - 1) \ - ln++; \ - else \ - if (tosln > ln) { \ - tosln--; \ - if (nvln > 1) { \ - scrollwindow(0); \ - nvln--; \ - } else \ - more_end = 1; \ - } else if (tosln > 2 && nvln > 1) { \ - tosln--; \ - if (tosln <= nvln) { \ - scrollwindow(0); \ - nvln--; \ - } else { \ - scrollwindow(tosln); \ - more_end = 1; \ - } \ - } else { \ - more_status = 1; \ - scrollwindow(tosln + 1); \ - } \ - if (!nbuf[ln]) \ - nbuf[ln] = (ZLE_STRING_T)zalloc((winw + 2) * sizeof(**nbuf)); \ - s = nbuf[ln]; \ - sen = s + winw; \ -} +/* + * Parameters in zrefresh used for communicating with next-line functions. + */ +struct rparams { + int canscroll; /* number of lines we are allowed to scroll */ + int ln; /* current line we're working on */ + int more_status; /* more stuff in status line */ + int nvcs; /* video cursor column */ + int nvln; /* video cursor line */ + int tosln; /* tmp in statusline stuff */ + ZLE_STRING_T s; /* pointer into the video buffer */ + ZLE_STRING_T sen; /* pointer to end of the video buffer (eol) */ +}; +typedef struct rparams *Rparams; static int cleareol, /* clear to end-of-line (if can't cleareod) */ clearf, /* alwayslastprompt used immediately before */ @@ -321,6 +276,75 @@ static int cleareol, /* clear to end-of-line (if can't cleareod) */ numscrolls, onumscrolls; /* + * Go to the next line in the main display area. Return 1 if we should abort + * processing the line loop at this point, else 0. + */ +static int +nextline(Rparams rpms) +{ + *rpms->s = ZWC('\0'); + if (rpms->ln != winh - 1) + rpms->ln++; + else { + if (!rpms->canscroll) { + if (rpms->nvln != -1 && rpms->nvln != winh - 1 + && (numscrolls != onumscrolls - 1 + || rpms->nvln <= winh / 2)) + return 1; + numscrolls++; + rpms->canscroll = winh / 2; + } + rpms->canscroll--; + scrollwindow(0); + if (rpms->nvln != -1) + rpms->nvln--; + } + if (!nbuf[rpms->ln]) + nbuf[rpms->ln] = (ZLE_STRING_T)zalloc((winw + 2) * sizeof(**nbuf)); + rpms->s = nbuf[rpms->ln]; + rpms->sen = rpms->s + winw; + + return 0; +} + + +/* + * Go to the next line in the status area. + */ +static void +snextline(Rparams rpms) +{ + *rpms->s = ZWC('\0'); + if (rpms->ln != winh - 1) + rpms->ln++; + else + if (rpms->tosln > rpms->ln) { + rpms->tosln--; + if (rpms->nvln > 1) { + scrollwindow(0); + rpms->nvln--; + } else + more_end = 1; + } else if (rpms->tosln > 2 && rpms->nvln > 1) { + rpms->tosln--; + if (rpms->tosln <= rpms->nvln) { + scrollwindow(0); + rpms->nvln--; + } else { + scrollwindow(rpms->tosln); + more_end = 1; + } + } else { + rpms->more_status = 1; + scrollwindow(rpms->tosln + 1); + } + if (!nbuf[rpms->ln]) + nbuf[rpms->ln] = (ZLE_STRING_T)zalloc((winw + 2) * sizeof(**nbuf)); + rpms->s = nbuf[rpms->ln]; + rpms->sen = rpms->s + winw; +} + +/* * TODO currently it assumes sceenwidth 1 for every character * (except for characters in the prompt which are correctly handled * by wcwidth()). @@ -330,15 +354,9 @@ mod_export void zrefresh(void) { static int inlist; /* avoiding recursion */ - int canscroll = 0, /* number of lines we are allowed to scroll */ - ln = 0, /* current line we're working on */ - more_status = 0, /* more stuff in status line */ - nvcs = 0, nvln = -1, /* video cursor column and line */ - t0 = -1, /* tmp */ - tosln = 0; /* tmp in statusline stuff */ - ZLE_STRING_T s, /* pointer into the video buffer */ - sen, /* pointer to end of the video buffer (eol) */ - t, /* pointer into the real buffer */ + int iln; /* current line as index in loops */ + int t0 = -1; /* tmp */ + ZLE_STRING_T t, /* pointer into the real buffer */ scs, /* pointer to cursor position in real buffer */ u; /* pointer for status line stuff */ ZLE_STRING_T tmpline, /* line with added pre/post text */ @@ -346,6 +364,7 @@ zrefresh(void) 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 */ + struct rparams rpms; if (trashedzle) reexpandprompt(); @@ -514,120 +533,129 @@ zrefresh(void) if (!*nbuf) *nbuf = (ZLE_STRING_T)zalloc((winw + 2) * sizeof(**nbuf)); - s = nbuf[ln = 0] + lpromptw; + memset(&rpms, 0, sizeof(rpms)); + rpms.nvln = -1; + + rpms.s = nbuf[rpms.ln = 0] + lpromptw; t = tmpline; - sen = *nbuf + winw; + rpms.sen = *nbuf + winw; for (; t < tmpline+tmpll; t++) { if (t == scs) /* if cursor is here, remember it */ - nvcs = s - (nbuf[nvln = ln]); + rpms.nvcs = rpms.s - (nbuf[rpms.nvln = rpms.ln]); if (*t == ZWC('\n')){ /* newline */ - nbuf[ln][winw + 1] = ZWC('\0'); /* text not wrapped */ - nextline + nbuf[rpms.ln][winw + 1] = ZWC('\0'); /* text not wrapped */ + if (nextline(&rpms)) + break; } else if (*t == ZWC('\t')) { /* tab */ - t0 = s - nbuf[ln]; + t0 = rpms.s - nbuf[rpms.ln]; if ((t0 | 7) + 1 >= winw) { - nbuf[ln][winw + 1] = ZWC('\n'); /* text wrapped */ - nextline + nbuf[rpms.ln][winw + 1] = ZWC('\n'); /* text wrapped */ + if (nextline(&rpms)) + break; } else do - *s++ = ZWC(' '); + *rpms.s++ = ZWC(' '); while ((++t0) & 7); } else if (ZC_icntrl(*t)) { /* other control character */ - *s++ = ZWC('^'); - if (s == sen) { - nbuf[ln][winw + 1] = ZWC('\n'); /* text wrapped */ - nextline + *rpms.s++ = ZWC('^'); + if (rpms.s == rpms.sen) { + nbuf[rpms.ln][winw + 1] = ZWC('\n'); /* text wrapped */ + if (nextline(&rpms)) + break; } #ifdef ZLE_UNICODE_SUPPORT - *s++ = ((*t == 127) || (*t > 255)) ? ZWC('?') : (*t | ZWC('@')); + *rpms.s++ = ((*t == 127) || (*t > 255)) ? ZWC('?') : + (*t | ZWC('@')); #else - *s++ = (*t == 127) ? ZWC('?') : (*t | ZWC('@')); + *rpms.s++ = (*t == 127) ? ZWC('?') : (*t | ZWC('@')); #endif } else { /* normal character */ - *s++ = *t; + *rpms.s++ = *t; } - if (s == sen) { - nbuf[ln][winw + 1] = ZWC('\n'); /* text wrapped */ - nextline + if (rpms.s == rpms.sen) { + nbuf[rpms.ln][winw + 1] = ZWC('\n'); /* text wrapped */ + if (nextline(&rpms)) + break; } } /* if we're really on the next line, don't fake it; do everything properly */ - if (t == scs && (nvcs = s - (nbuf[nvln = ln])) == winw) { - nbuf[ln][winw + 1] = ZWC('\n'); /* text wrapped */ - switch ('\0') { /* a sad hack to make the break */ - case '\0': /* in nextline work */ - nextline - } - *s = ZWC('\0'); - nvcs = 0; - nvln++; + if (t == scs && (rpms.nvcs = rpms.s - (nbuf[rpms.nvln = rpms.ln])) + == winw) { + nbuf[rpms.ln][winw + 1] = ZWC('\n'); /* text wrapped */ + (void)nextline(&rpms); + *rpms.s = ZWC('\0'); + rpms.nvcs = 0; + rpms.nvln++; } if (t != tmpline + tmpll) more_end = 1; if (statusline) { - tosln = ln + 1; - nbuf[ln][winw + 1] = ZWC('\0'); /* text not wrapped */ - snextline + rpms.tosln = rpms.ln + 1; + nbuf[rpms.ln][winw + 1] = ZWC('\0'); /* text not wrapped */ + snextline(&rpms); u = statusline; for (; u < statusline + statusll; u++) { if (ZC_icntrl(*u)) { /* simplified processing in the status line */ - *s++ = ZWC('^'); - if (s == sen) { - nbuf[ln][winw + 1] = ZWC('\n'); /* text wrapped */ - snextline + *rpms.s++ = ZWC('^'); + if (rpms.s == rpms.sen) { + nbuf[rpms.ln][winw + 1] = ZWC('\n');/* text wrapped */ + snextline(&rpms); } - *s++ = (*u == 127) ? ZWC('?') : (*u | ZWC('@')); + *rpms.s++ = (*u == 127) ? ZWC('?') : (*u | ZWC('@')); } else - *s++ = *u; - if (s == sen) { - nbuf[ln][winw + 1] = ZWC('\n'); /* text wrapped */ - snextline + *rpms.s++ = *u; + if (rpms.s == rpms.sen) { + nbuf[rpms.ln][winw + 1] = ZWC('\n'); /* text wrapped */ + snextline(&rpms); } } - if (s == sen) - snextline + if (rpms.s == rpms.sen) + snextline(&rpms); } - *s = ZWC('\0'); + *rpms.s = ZWC('\0'); /* insert <.... at end of last line if there is more text past end of screen */ if (more_end) { if (!statusline) - tosln = winh; - s = nbuf[tosln - 1]; - sen = s + winw - 7; - for (; s < sen; s++) { - if (*s == ZWC('\0')) { - for (; s < sen; ) - *s++ = ZWC(' '); + rpms.tosln = winh; + rpms.s = nbuf[rpms.tosln - 1]; + rpms.sen = rpms.s + winw - 7; + for (; rpms.s < rpms.sen; rpms.s++) { + if (*rpms.s == ZWC('\0')) { + for (; rpms.s < rpms.sen; ) + *rpms.s++ = ZWC(' '); break; } } - ZS_strncpy(sen, ZWS(" <.... "), 7); - nbuf[tosln - 1][winw] = nbuf[tosln - 1][winw + 1] = ZWC('\0'); + ZS_strncpy(rpms.sen, ZWS(" <.... "), 7); + nbuf[rpms.tosln - 1][winw] = nbuf[rpms.tosln - 1][winw + 1] + = ZWC('\0'); } /* insert <....> at end of first status line if status is too big */ - if (more_status) { - s = nbuf[tosln]; - sen = s + winw - 8; - for (; s < sen; s++) { - if (*s == ZWC('\0')) { - for (; s < sen; ) - *s++ = ZWC(' '); + if (rpms.more_status) { + rpms.s = nbuf[rpms.tosln]; + rpms.sen = rpms.s + winw - 8; + for (; rpms.s < rpms.sen; rpms.s++) { + if (*rpms.s == ZWC('\0')) { + for (; rpms.s < rpms.sen; ) + *rpms.s++ = ZWC(' '); break; } } - ZS_strncpy(sen, ZWS(" <....> "), 8); - nbuf[tosln][winw] = nbuf[tosln][winw + 1] = ZWC('\0'); + ZS_strncpy(rpms.sen, ZWS(" <....> "), 8); + nbuf[rpms.tosln][winw] = nbuf[rpms.tosln][winw + 1] = ZWC('\0'); } - nlnct = ln + 1; - for (ln = nlnct; ln < winh; ln++) - zfree(nbuf[ln], (winw + 2) * sizeof(**nbuf)), nbuf[ln] = NULL; + nlnct = rpms.ln + 1; + for (iln = nlnct; iln < winh; iln++) { + zfree(nbuf[iln], (winw + 2) * sizeof(**nbuf)); + nbuf[iln] = NULL; + } /* determine whether the right-prompt exists and can fit on the screen */ if (!more_start) { @@ -647,23 +675,25 @@ zrefresh(void) nbuf[0][winw] = nbuf[0][winw + 1] = ZWC('\0'); } - for (ln = 0; ln < nlnct; ln++) { + for (iln = 0; iln < nlnct; iln++) { /* if we have more lines than last time, clear the newly-used lines */ - if (ln >= olnct) + if (iln >= olnct) cleareol = 1; /* if old line and new line are different, see if we can insert/delete a line to speed up update */ - if (!clearf && ln > 0 && ln < olnct - 1 && !(hasam && vcs == winw) && - nbuf[ln] && obuf[ln] && - ZS_strncmp(nbuf[ln], obuf[ln], 16)) { - if (tccan(TCDELLINE) && obuf[ln + 1] && obuf[ln + 1][0] && - nbuf[ln] && !ZS_strncmp(nbuf[ln], obuf[ln + 1], 16)) { - moveto(ln, 0); + if (!clearf && iln > 0 && iln < olnct - 1 && + !(hasam && vcs == winw) && + nbuf[iln] && obuf[iln] && + ZS_strncmp(nbuf[iln], obuf[iln], 16)) { + if (tccan(TCDELLINE) && obuf[iln + 1] && + obuf[iln + 1][0] && nbuf[iln] && + !ZS_strncmp(nbuf[iln], obuf[iln + 1], 16)) { + moveto(iln, 0); tcout(TCDELLINE); - zfree(obuf[ln], (winw + 2) * sizeof(**obuf)); - for (t0 = ln; t0 != olnct; t0++) + zfree(obuf[iln], (winw + 2) * sizeof(**obuf)); + for (t0 = iln; t0 != olnct; t0++) obuf[t0] = obuf[t0 + 1]; obuf[--olnct] = NULL; } @@ -671,22 +701,23 @@ zrefresh(void) of lines that have been displayed by this routine) so that we don't go off the end of the screen. */ - else if (tccan(TCINSLINE) && olnct < vmaxln && nbuf[ln + 1] && - obuf[ln] && !ZS_strncmp(nbuf[ln + 1], obuf[ln], 16)) { - moveto(ln, 0); + else if (tccan(TCINSLINE) && olnct < vmaxln && nbuf[iln + 1] && + obuf[iln] && !ZS_strncmp(nbuf[iln + 1], + obuf[iln], 16)) { + moveto(iln, 0); tcout(TCINSLINE); - for (t0 = olnct; t0 != ln; t0--) + for (t0 = olnct; t0 != iln; t0--) obuf[t0] = obuf[t0 - 1]; - obuf[ln] = NULL; + obuf[iln] = NULL; olnct++; } } /* update the single line */ - refreshline(ln); + refreshline(iln); /* output the right-prompt if appropriate */ - if (put_rpmpt && !ln && !oput_rpmpt) { + if (put_rpmpt && !iln && !oput_rpmpt) { moveto(0, winw - 1 - rpromptw); zputs(rpromptbuf, shout); vcs = winw - 1; @@ -712,8 +743,8 @@ individually */ if (olnct > nlnct) { cleareol = 1; - for (ln = nlnct; ln < olnct; ln++) - refreshline(ln); + for (iln = nlnct; iln < olnct; iln++) + refreshline(iln); } /* reset character attributes */ @@ -737,14 +768,14 @@ individually */ oput_rpmpt = put_rpmpt; /* move to the new cursor position */ - moveto(nvln, nvcs); + moveto(rpms.nvln, rpms.nvcs); /* swap old and new buffers - better than freeing/allocating every time */ qbuf = nbuf; nbuf = obuf; obuf = qbuf; /* store current values so we can use them next time */ - ovln = nvln; + ovln = rpms.nvln; olnct = nlnct; onumscrolls = numscrolls; if (nlnct > vmaxln) |