diff options
-rw-r--r-- | pw.c | 50 |
1 files changed, 37 insertions, 13 deletions
@@ -26,6 +26,9 @@ typedef struct dstr { #define dstr_of(str) ((dstr *) ((str) - sizeof (dstr))) +char **snapshot; +int snaplines; + static void panic(const char *fmt, ...) { va_list vl; @@ -189,13 +192,20 @@ static void drawstatus(unsigned stat, char *cmd) static void redraw(char **circbuf, int nlines, int hpos, int columns, unsigned stat, char *cmd) { + if (snapshot) { + for (int i = 0; i < snaplines; i++) + dsdrop(snapshot[i]); + } + snaplines = nlines; printf("\r\033[%dA\033[J", nlines); - for (int i = 0; i < nlines; i++) + for (int i = 0; i < nlines; i++) { drawline(circbuf[i], hpos, columns); + snapshot[i] = dsref(circbuf[i]); + } drawstatus(stat, cmd); } -static void execute(char *cmd, char **circbuf, int nlines) +static void execute(char *cmd) { char *arg = cmd + 1 + strspn(cmd + 1, " \t"); @@ -212,8 +222,8 @@ static void execute(char *cmd, char **circbuf, int nlines) break; } - for (int i = 0; ok && i < nlines; i++) - if (fprintf(f, "%s\n", circbuf[i]) < 0) { + for (int i = 0; ok && i < snaplines; i++) + if (fprintf(f, "%s\n", snapshot[i]) < 0) { sprintf(cmd, "write error!"); ok = 0; break; @@ -235,8 +245,8 @@ static void execute(char *cmd, char **circbuf, int nlines) break; } - for (int i = 0; i < nlines && ok; i++) - if (fprintf(p, "%s\n", circbuf[i]) < 0) { + for (int i = 0; i < snaplines && ok; i++) + if (fprintf(p, "%s\n", snapshot[i]) < 0) { sprintf(cmd, "write error!"); ok = 0; break; @@ -307,7 +317,9 @@ int main(int argc, char **argv) if (maxlines <= 0 || maxlines > 1000) error("%d is an unreasonable number of lines to display", maxlines); - if ((circbuf = malloc(sizeof *circbuf * maxlines)) == 0) + if ((circbuf = calloc(sizeof *circbuf, maxlines)) == 0) + panic("out of memory"); + if ((snapshot = calloc(sizeof *snapshot, maxlines)) == 0) panic("out of memory"); if (isatty(fd)) { @@ -388,10 +400,15 @@ int main(int argc, char **argv) stat |= stat_dirty; } } else { - circbuf[nlines++] = line; - clear_cur_line(); - drawline(line, hpos, columns); - drawstatus(stat, colcmd); + if ((stat & stat_susp)) { + dsdrop(line); + } else { + circbuf[nlines++] = line; + snapshot[snaplines++] = dsref(line); + clear_cur_line(); + drawline(line, hpos, columns); + drawstatus(stat, colcmd); + } } } else { if (auto_quit) @@ -438,8 +455,15 @@ int main(int argc, char **argv) stat |= stat_dirty; break; case ' ': - if ((stat & stat_eof) == 0) + if ((stat & stat_eof) == 0) { stat |= (stat_dirty | stat_susp); + for (int i = 0; i < nlines || i < snaplines; i++) { + if (i < nlines) + dsdrop(circbuf[i]); + circbuf[i] = (i < snaplines) ? dsref(snapshot[i]) : 0; + } + nlines = snaplines; + } break; case 13: stat &= ~stat_susp; @@ -480,7 +504,7 @@ int main(int argc, char **argv) kbd_state = kbd_cmd; stat |= stat_dirty; if (ch == 13 && cmdbuf[0]) { - execute(cmdbuf, circbuf, nlines); + execute(cmdbuf); stat &= ~stat_dirty; kbd_state = kbd_result; break; |