diff options
Diffstat (limited to 'pw.c')
-rw-r--r-- | pw.c | 109 |
1 files changed, 99 insertions, 10 deletions
@@ -83,6 +83,7 @@ typedef struct pwstate { char **circbuf; int nlines; unsigned hpos; + unsigned vsplit1, vsplit2, vs2pos; unsigned hist; int columns; unsigned stat; @@ -338,16 +339,65 @@ static void clreol(int nl) static void drawline(pwstate *pw, const char *line, int lineno) { + const char *oline = line; size_t len = dslen(line); int columns = pw->columns; + unsigned vsplit1 = pw->vsplit1; + unsigned vsplit2 = pw->vsplit2; + unsigned vs2pos = pw->vs2pos; + int endmark = 0; if (lineno >= 0) columns -= printf("%3d ", lineno); - if ((size_t) pw->hpos <= len) { - if (pw->hpos) { - line += pw->hpos; - len -= pw->hpos; + if (vsplit1 > 0) { + if (len <= vsplit1) { + fputs(line, stdout); + columns -= len; + len = 0; + } else { + for (unsigned i = 0; i < vsplit1; i++) + putchar(line[i]); + len -= vsplit1; + line += vsplit1; + columns -= vsplit1; + endmark = 1; + } + } + + if (vsplit2 > 0) { + unsigned pos = line - oline; + unsigned delta = vs2pos - pos; + if (pos + len <= vs2pos) { + len = 0; + } else if (len - delta <= vsplit2) { + if (vsplit1) { + putchar('|'); + delta++; + } + fputs(line + delta, stdout); + columns -= len; + len = 0; + endmark = 0; + } else { + unsigned start = 0; + if (vsplit1) { + putchar('|'); + start++; + } + for (unsigned i = start; i < vsplit2; i++) + putchar(line[delta + i]); + line += vsplit2; + len -= vsplit2; + columns -= vsplit2; + endmark = 1; + } + } + + if ((size_t) pw->hpos + 1 <= len) { + if (pw->hpos || vsplit1 || vsplit2) { + line += pw->hpos + 1; + len -= pw->hpos + 1; putchar('>'); columns--; } @@ -360,7 +410,8 @@ static void drawline(pwstate *pw, const char *line, int lineno) puts("<"); } } else { - putchar('>'); + if (endmark) + putchar('>'); clreol(1); } } @@ -1097,14 +1148,52 @@ int main(int argc, char **argv) } break; case 'h': - if (pw.hpos >= 8) { - pw.hpos -= 8; + if (cmdcount == UINT_MAX) + cmdcount = 8; + if (pw.hpos >= cmdcount) + pw.hpos -= cmdcount; + else + pw.hpos = 0; + pw.stat |= stat_force; + break; + case 'l': + if (cmdcount == UINT_MAX) + cmdcount = 8; + if (pw.hpos < 10000) + pw.hpos += cmdcount; + pw.stat |= stat_force; + break; + case ']': + if ((int) pw.vsplit1 < pw.columns - 2) { + pw.vsplit1++; + if (pw.vsplit2 > 0) { + pw.vsplit2--; + pw.vs2pos++; + } pw.stat |= stat_force; } break; - case 'l': - if (pw.hpos < 10000) { - pw.hpos += 8; + case '[': + if (pw.vsplit1 > 0) { + pw.vsplit1--; + if (pw.vsplit2 > 0) { + pw.vsplit2++; + pw.vs2pos--; + } + pw.stat |= stat_force; + } + break; + case '>': + if ((int) (pw.vsplit1 + pw.vsplit2) < pw.columns - 2) { + if (pw.vsplit2 == 0) + pw.vs2pos = pw.hpos + pw.vsplit1; + pw.vsplit2++; + pw.stat |= stat_force; + } + break; + case '<': + if (pw.vsplit2 > 0) { + pw.vsplit2--; pw.stat |= stat_force; } break; |