aboutsummaryrefslogtreecommitdiffstats
path: root/pw.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-05-13 21:25:24 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-05-13 21:25:24 -0700
commitb972b24f3e0a85cd7f7cfe0eb2125ccf4c2efbc3 (patch)
tree0eb9cef8e1ae05cfe75891dbae5360fba9a3bdef /pw.c
parent72fd3ddba37a2369d52cdacf4f6b29ffba81a0bd (diff)
downloadpw-b972b24f3e0a85cd7f7cfe0eb2125ccf4c2efbc3.tar.gz
pw-b972b24f3e0a85cd7f7cfe0eb2125ccf4c2efbc3.tar.bz2
pw-b972b24f3e0a85cd7f7cfe0eb2125ccf4c2efbc3.zip
New feature: highlight differences between snapshots.
Diffstat (limited to 'pw.c')
-rw-r--r--pw.c70
1 files changed, 57 insertions, 13 deletions
diff --git a/pw.c b/pw.c
index d1a652f..4c52ab8 100644
--- a/pw.c
+++ b/pw.c
@@ -410,17 +410,28 @@ static void hloff(int *phlite)
hloff(&hlite); \
} while (0)
-static void drawline(pwstate *pw, const char *line, int lineno, char *diffline)
+#define with_hlonoff(onoff, hlite, expr) \
+ do { \
+ (onoff ? hlon : hloff)(&hlite); \
+ expr; \
+ } while(0)
+
+static int diff(const char *line, const char *dline, int dlen, int i)
+{
+ return i >= dlen || line[i] != dline[i];
+}
+
+static void drawline(pwstate *pw, const char *line, int lineno, char *dline)
{
- const char *oline = line;
int olen = (int) dslen(line), len = olen, pos = 0;
+ int dlen = dslen(dline);
int columns = pw->columns;
int vsplit1 = pw->vsplit1;
int vsplit2 = pw->vsplit2;
int vs2pos = pw->vs2pos;
int endmark = 0;
int hlpanel = (pw->stat & stat_hlite) != 0;
- int hldiff = (pw->stat & stat_diff) != 0 && diffline != 0;
+ int hldiff = (pw->stat & stat_diff) != 0 && dline != 0;
int hlite = 0;
if (lineno >= 0)
@@ -429,11 +440,21 @@ static void drawline(pwstate *pw, const char *line, int lineno, char *diffline)
if (vsplit1 > 0) {
if (len <= vsplit1) {
if (!vsplit2) {
- fputs(line, stdout);
+ if (!hldiff)
+ fputs(line, stdout);
+ else
+ for (int i = 0; i < len; i++)
+ with_hlonoff (diff(line, dline, dlen, i), hlite, putchar(line[i]));
columns -= len;
} else {
int spaces = vsplit1 - len;
- fputs(line, stdout);
+ if (!hldiff)
+ fputs(line, stdout);
+ else
+ for (int i = 0; i < len; i++)
+ with_hlonoff (diff(line, dline, dlen, i), hlite, putchar(line[i]));
+ if (spaces)
+ hloff(&hlite);
for (int i = 0; i < spaces; i++)
putchar(' ');
columns -= vsplit1;
@@ -441,8 +462,12 @@ static void drawline(pwstate *pw, const char *line, int lineno, char *diffline)
pos += len;
len = 0;
} else {
- for (int i = 0; i < vsplit1; i++)
- putchar(line[i]);
+ if (!hldiff)
+ for (int i = 0; i < vsplit1; i++)
+ putchar(line[i]);
+ else
+ for (int i = 0; i < vsplit1; i++)
+ with_hlonoff (diff(line, dline, dlen, i), hlite, putchar(line[i]));
len -= vsplit1;
pos += vsplit1;
columns -= vsplit1;
@@ -461,13 +486,19 @@ static void drawline(pwstate *pw, const char *line, int lineno, char *diffline)
if (vs2pos < olen) {
int nchar = min(olen - vs2pos, width);
- const char *ptr = oline + vs2pos + i;
- for (; i < nchar; i++)
- putchar(*ptr++);
+ if (!hldiff)
+ for (; i < nchar; i++)
+ putchar(line[vs2pos + i]);
+ else
+ for (; i < nchar; i++)
+ with_hlonoff (diff(line, dline, dlen, vs2pos + i), hlite,
+ putchar(line[vs2pos + i]));
endmark = 1;
}
if (len > vsplit2 + pw->hpos) {
+ if (i < width)
+ hloff(&hlite);
for (; i < width; i++)
putchar(' ');
@@ -489,12 +520,23 @@ static void drawline(pwstate *pw, const char *line, int lineno, char *diffline)
with_hl (hlpanel, hldiff, hlite, putchar('>'));
columns--;
}
+
if (len < columns) {
- fputs(line + pos, stdout);
+ if (!hldiff)
+ fputs(line + pos, stdout);
+ else
+ for (; pos < olen; pos++)
+ with_hlonoff (diff(line, dline, dlen, pos), hlite,
+ putchar(line[pos]));
clreol(1);
} else {
- for (int i = 0; i < columns - 1; i++)
- putchar(line[pos + i]);
+ if (!hldiff)
+ for (int i = 0; i < columns - 1; i++)
+ putchar(line[pos + i]);
+ else
+ for (int i = 0; i < columns - 1; i++)
+ with_hlonoff (diff(line, dline, dlen, pos + i), hlite,
+ putchar(line[pos + i]));
with_hl (hlpanel, hldiff, hlite, putchar('<'));
putchar('\n');
}
@@ -598,6 +640,8 @@ static void redraw(pwstate *pw)
pw->stat |= stat_susp;
pw->stat &= ~(stat_dirty | stat_trgrd | stat_oneshot);
updln = 1;
+ if (pw->prevhist == 0 && pw->hist == 0)
+ pw->prevhist = 1;
} else if ((pw->stat & stat_force)) {
pw->stat &= ~stat_force;
updln = 1;