aboutsummaryrefslogtreecommitdiffstats
path: root/pw.c
diff options
context:
space:
mode:
Diffstat (limited to 'pw.c')
-rw-r--r--pw.c122
1 files changed, 83 insertions, 39 deletions
diff --git a/pw.c b/pw.c
index baa62c5..2f19e25 100644
--- a/pw.c
+++ b/pw.c
@@ -52,6 +52,7 @@ typedef struct grep {
#define cmdsize 256
#define maxgrep 64
#define maxtrig 100
+#define snhistsize 20
typedef struct dstr {
int refs;
@@ -65,8 +66,8 @@ static int poll_interval = 1000;
static int long_interval = 10000;
static int regex_flags = 0;
-static char **snapshot;
-static int snaplines;
+static char **snapshot[snhistsize];
+static int snaplines[snhistsize];
static grep grepstack[maxgrep];
static int ngrep;
@@ -246,7 +247,7 @@ static void clreol(int nl)
putchar('\n');
}
-static void drawline(const char *line, int hpos, int columns)
+static void drawline(const char *line, unsigned hpos, int columns)
{
size_t len = dslen(line);
@@ -271,7 +272,7 @@ static void drawline(const char *line, int hpos, int columns)
}
}
-static void drawstatus(int columns, unsigned stat, char *cmd)
+static void drawstatus(unsigned hist, int columns, unsigned stat, char *cmd)
{
char status[cmdsize] = "", *ptr = status;
size_t lim = sizeof status;
@@ -283,9 +284,13 @@ static void drawstatus(int columns, unsigned stat, char *cmd)
if (cmd) {
snprintf(status, lim, "%s", cmd);
- } else if ((stat & (stat_eof | stat_susp | stat_htmode | stat_ttmode |
+ } else if (hist > 0 ||
+ (stat & (stat_eof | stat_susp | stat_htmode | stat_ttmode |
stat_grep)))
{
+ if (hist > 0)
+ ptr += snprintf(ptr, end - ptr, "HIST%u ", hist);
+
if ((stat & stat_eof))
ptr += snprintf(ptr, end - ptr, "EOF ");
@@ -325,33 +330,42 @@ static void drawstatus(int columns, unsigned stat, char *cmd)
fflush(stdout);
}
-static unsigned redraw(char **circbuf, int nlines, int hpos,
+static void freebuf(char **buf, size_t size)
+{
+ for (size_t i = 0; i < size; i++)
+ dsdrop(buf[i]);
+}
+
+static unsigned redraw(char **circbuf, int nlines, unsigned hpos, unsigned hist,
int columns, unsigned stat, char *cmd)
{
if ((stat & (stat_dirty | stat_susp)) == stat_dirty &&
(stat & (stat_htmode | stat_trgrd)) != stat_htmode &&
(stat & (stat_ttmode | stat_trgrd)) != stat_ttmode)
{
- if (snapshot) {
- for (int i = 0; i < snaplines; i++)
- dsdrop(snapshot[i]);
+ if (snapshot[snhistsize - 1]) {
+ freebuf(snapshot[snhistsize - 1], snaplines[snhistsize - 1]);
+ free(snapshot[snhistsize - 1]);
}
- snaplines = nlines;
+ memmove(snapshot + 1, snapshot, sizeof *snapshot * (snhistsize - 1));
+ memmove(snaplines + 1, snaplines, sizeof *snaplines * (snhistsize - 1));
+ snapshot[0] = calloc(sizeof *snapshot[0], nlines);
+ snaplines[0] = nlines;
printf("\r\033[%dA", nlines);
for (int i = 0; i < nlines; i++) {
- drawline(circbuf[i], hpos, columns);
- snapshot[i] = dsref(circbuf[i]);
+ snapshot[0][i] = dsref(circbuf[i]);
+ drawline(snapshot[hist][i], hpos, columns);
}
stat &= ~(stat_dirty | stat_trgrd);
} else if ((stat & stat_force)) {
- printf("\r\033[%dA", snaplines);
- for (int i = 0; i < snaplines; i++)
- drawline(snapshot[i], hpos, columns);
+ printf("\r\033[%dA", snaplines[hist]);
+ for (int i = 0; i < snaplines[hist]; i++)
+ drawline(snapshot[hist][i], hpos, columns);
stat &= ~stat_force;
} else {
clrline();
}
- drawstatus(columns, stat, cmd);
+ drawstatus(hist, columns, stat, cmd);
return stat;
}
@@ -409,7 +423,7 @@ static int getms(const char *str, char **err)
return msec;
}
-static void execute(char *cmd, unsigned *pstat)
+static void execute(char *cmd, unsigned *pstat, unsigned hist)
{
char *arg = cmd + 2 + strspn(cmd + 2, " \t");
@@ -430,8 +444,8 @@ static void execute(char *cmd, unsigned *pstat)
break;
}
- for (int i = 0; ok && i < snaplines; i++)
- if (fprintf(f, "%s\n", snapshot[i]) < 0) {
+ for (int i = 0; ok && i < snaplines[hist]; i++)
+ if (fprintf(f, "%s\n", snapshot[hist][i]) < 0) {
sprintf(cmd, "write error!");
ok = 0;
break;
@@ -456,8 +470,8 @@ static void execute(char *cmd, unsigned *pstat)
break;
}
- for (int i = 0; i < snaplines && ok; i++)
- if (fprintf(p, "%s\n", snapshot[i]) < 0) {
+ for (int i = 0; i < snaplines[hist] && ok; i++)
+ if (fprintf(p, "%s\n", snapshot[hist][i]) < 0) {
sprintf(cmd, "write error!");
ok = 0;
break;
@@ -645,7 +659,7 @@ int main(int argc, char **argv)
if ((circbuf = calloc(sizeof *circbuf, maxlines)) == 0)
panic("out of memory");
- if ((snapshot = calloc(sizeof *snapshot, maxlines)) == 0)
+ if ((snapshot[0] = calloc(sizeof *snapshot[0], maxlines)) == 0)
panic("out of memory");
if (isatty(fd)) {
@@ -688,7 +702,7 @@ int main(int argc, char **argv)
sigaction(SIGWINCH, &sa, NULL);
#endif
- for (unsigned stat = stat_dirty, hpos = 0,
+ for (unsigned stat = stat_dirty, hpos = 0, hist = 0,
kbd_state = kbd_cmd, kbd_prev = kbd_cmd, lasttime = ~0U,
workbout = 1024, work = workbout, histpos = 0,
cmdcount = UINT_MAX;
@@ -708,7 +722,7 @@ int main(int argc, char **argv)
if (feof(stdin) || (errno != EAGAIN && errno != EWOULDBLOCK)) {
nfds = 1;
stat |= stat_eof;
- stat = redraw(circbuf, nlines, hpos, columns, stat, curcmd);
+ stat = redraw(circbuf, nlines, hpos, hist, columns, stat, curcmd);
if (!ferror(stdin))
exit_status = 0;
if (auto_quit) {
@@ -766,10 +780,11 @@ int main(int argc, char **argv)
} else {
circbuf[nlines++] = line;
if ((stat & stat_susp) == 0) {
- snapshot[snaplines++] = dsref(line);
+ snapshot[0] = resizebuf(snapshot[0], snaplines[0], snaplines[0] + 1);
+ snapshot[0][snaplines[0]++] = dsref(line);
clrline();
drawline(line, hpos, columns);
- drawstatus(columns, stat, curcmd);
+ drawstatus(hist, columns, stat, curcmd);
}
}
line = 0;
@@ -783,9 +798,14 @@ int main(int argc, char **argv)
winch = 0;
if (ioctl(ttyfd, TIOCGWINSZ, &ws) == 0) {
if (maxed) {
+ hist = 0;
circbuf = resizebuf(circbuf, maxlines, ws.ws_row - 1);
- snapshot = resizebuf(snapshot, maxlines, ws.ws_row - 1);
- maxlines = ws.ws_row - 1;
+ snapshot[0] = resizebuf(snapshot[0], maxlines, ws.ws_row - 1);
+ for (int i = 1; i < snhistsize; i++) {
+ freebuf(snapshot[i], snaplines[i]);
+ free(snapshot[i]);
+ snapshot[i] = 0;
+ }
} else {
if (maxlines >= ws.ws_row) {
maxlines = ws.ws_row - 1;
@@ -795,8 +815,8 @@ int main(int argc, char **argv)
if (nlines > maxlines)
nlines = maxlines;
- if (snaplines > maxlines)
- snaplines = maxlines;
+ if (snaplines[0] > maxlines)
+ snaplines[0] = maxlines;
columns = ws.ws_col;
}
@@ -832,17 +852,17 @@ int main(int argc, char **argv)
}
if (force)
- stat = redraw(circbuf, nlines, hpos, columns, stat, curcmd);
+ stat = redraw(circbuf, nlines, hpos, hist, columns, stat, curcmd);
if (poll(pe, nfds, pollms) <= 0) {
if (pollms) {
if ((stat & stat_dirty) && nlines == maxlines)
- stat = redraw(circbuf, nlines, hpos, columns, stat, curcmd);
+ stat = redraw(circbuf, nlines, hpos, hist, columns, stat, curcmd);
if (kbd_state == kbd_esc || kbd_state == kbd_result) {
kbd_state = kbd_cmd;
curcmd = 0;
clrline();
- drawstatus(columns, stat, curcmd);
+ drawstatus(hist, columns, stat, curcmd);
}
}
work = workbout += workbout / 4;
@@ -859,7 +879,8 @@ int main(int argc, char **argv)
ttyset(ttyfd, &tty_new);
for (int i = 0; i < nlines; i++)
puts("");
- stat = redraw(circbuf, nlines, hpos, columns, stat | stat_force, curcmd);
+ stat = redraw(circbuf, nlines, hpos, hist, columns,
+ stat | stat_force, curcmd);
continue;
}
@@ -887,6 +908,18 @@ int main(int argc, char **argv)
stat |= stat_force;
}
break;
+ case 'j':
+ if (hist > 0) {
+ hist--;
+ stat |= stat_force;
+ }
+ break;
+ case 'k':
+ if (hist < snhistsize - 1 && snapshot[hist + 1]) {
+ hist++;
+ stat |= stat_force;
+ }
+ break;
case ' ':
if ((stat & stat_eof) == 0)
stat |= stat_susp;
@@ -941,7 +974,7 @@ int main(int argc, char **argv)
}
break;
case '+':
- if (ws.ws_row && maxlines >= ws.ws_row - 1) {
+ if (hist > 0 || (ws.ws_row && maxlines >= ws.ws_row - 1)) {
break;
} else {
unsigned count = (cmdcount == UINT_MAX) ? 1 : cmdcount;
@@ -954,7 +987,12 @@ int main(int argc, char **argv)
}
circbuf = resizebuf(circbuf, maxlines, maxlines + 1);
- snapshot = resizebuf(snapshot, maxlines, maxlines + 1);
+ snapshot[0] = resizebuf(snapshot[0], maxlines, maxlines + 1);
+ for (int i = 1; i < snhistsize; i++) {
+ freebuf(snapshot[i], snaplines[i]);
+ free(snapshot[i]);
+ snapshot[i] = 0;
+ }
}
break;
case '0':
@@ -994,6 +1032,12 @@ int main(int argc, char **argv)
case 'H':
ch = '0';
goto fakecmd;
+ case 'A':
+ ch = 'k';
+ goto fakecmd;
+ case 'B':
+ ch = 'j';
+ goto fakecmd;
}
switch (ch) {
case 'A':
@@ -1032,7 +1076,7 @@ int main(int argc, char **argv)
}
if (kbd_state == kbd_colon && cmdbuf[1]) {
- execute(cmdbuf, &stat);
+ execute(cmdbuf, &stat, hist);
if (cmdbuf[0] != 0) {
kbd_state = kbd_result;
break;
@@ -1176,11 +1220,11 @@ int main(int argc, char **argv)
}
if ((stat & (stat_dirty | stat_force))) {
- stat = redraw(circbuf, nlines, hpos, columns, stat, curcmd);
+ stat = redraw(circbuf, nlines, hpos, hist, columns, stat, curcmd);
} else switch (kbd_state) {
case kbd_colon: case kbd_trig: case kbd_result: case kbd_cmd:
clrline();
- drawstatus(columns, stat, curcmd);
+ drawstatus(hist, columns, stat, curcmd);
}
} else {
work = workbout += workbout / 4;