aboutsummaryrefslogtreecommitdiffstats
path: root/pw.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-05-05 21:30:34 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-05-05 21:30:34 -0700
commite5c48d3b66a434156699402031c0cd78628a9850 (patch)
treed769f3f5ae33e161d2819b0a1848f3e2e0d2a99c /pw.c
parent6c1b8e6f26c5c66eb83d410005cdff8ce5ebea56 (diff)
downloadpw-e5c48d3b66a434156699402031c0cd78628a9850.tar.gz
pw-e5c48d3b66a434156699402031c0cd78628a9850.tar.bz2
pw-e5c48d3b66a434156699402031c0cd78628a9850.zip
New feature: double vertical split.
Diffstat (limited to 'pw.c')
-rw-r--r--pw.c109
1 files changed, 99 insertions, 10 deletions
diff --git a/pw.c b/pw.c
index cb3e2be..9daaf5e 100644
--- a/pw.c
+++ b/pw.c
@@ -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;