sfeed_curses

[fork] sfeed (atom feed) reader
Log | Files | Refs | README | LICENSE

commit 6f297f4dce9b2269b052fab6a3bc00873bac65bb
parent adc464f7fb07bb99226761ff45aa4efee78bf076
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Fri,  3 Jul 2020 19:01:52 +0200

rework line reading for searching

This implements a small line-editor, similar to the previous getline() behaviour.

It will not output a newline or control-character anymore. Only the statusbar
is marked dirty and redrawn. This also fixes an issue where the screen flickers
and "scrolls" in xterm.

Diffstat:
Msfeed_curses.c | 71++++++++++++++++++++++++++++++++++++++++++++---------------------------
1 file changed, 44 insertions(+), 27 deletions(-)

diff --git a/sfeed_curses.c b/sfeed_curses.c @@ -835,14 +835,51 @@ scrollbar_draw(struct scrollbar *s) } char * +lineeditor(void) +{ + unsigned char ch; + char *input = NULL; + size_t cap = 0, nchars = 0; + ssize_t n; + + for (;;) { + if (nchars + 1 >= cap) { + cap = cap ? cap * 2 : 32; + input = erealloc(input, cap); + } + + n = read(0, &ch, 1); + if (n < 0) { + free(input); + input = NULL; + } else if (n == 0 || ch == '\r' || ch == '\n') { + input[nchars] = '\0'; + break; + } else if (ch == '\b' || ch == 0x7f) { + if (!nchars) + continue; + input[--nchars] = '\0'; + ch = '\b'; /* back */ + write(1, &ch, 1); + ch = ' '; /* blank */ + write(1, &ch, 1); + ch = '\b'; /* back */ + write(1, &ch, 1); + continue; + } else if (ch >= ' ') { + write(1, &ch, 1); + } + input[nchars++] = ch; + } + return input; +} + +char * uiprompt(int x, int y, char *fmt, ...) { va_list ap; - char *input = NULL; - size_t n; - ssize_t r; + char *input; char buf[32]; - struct termios tset; va_start(ap, fmt); if (vsnprintf(buf, sizeof(buf), fmt, ap) >= sizeof(buf)) @@ -858,25 +895,9 @@ uiprompt(int x, int y, char *fmt, ...) cursormove(x + colw(buf) + 1, y); fflush(stdout); - tcgetattr(ttyfd, &tset); - tset.c_lflag |= (ECHO|ICANON); - tcsetattr(ttyfd, TCSANOW, &tset); - - n = 0; - r = getline(&input, &n, stdin); + input = lineeditor(); cursormode(0); - tcsetattr(ttyfd, TCSANOW, &tcur); /* restore */ - - fflush(stdout); - - if (r < 0) { - clearerr(stdin); - free(input); - input = NULL; - } else if (input[r - 1] == '\n') { - input[--r] = '\0'; - } return input; } @@ -946,10 +967,7 @@ feed_getitems(struct feed *f, FILE *fp, struct item **items, size_t *nitems) offset = 0; for (i = 0; ; i++) { if (i + 1 >= cap) { - if (cap == 0) - cap = 16; - else - cap *= 2; + cap = cap ? cap * 2 : 16; *items = erealloc(*items, cap * sizeof(struct item)); } if ((linelen = getline(&line, &linesize, fp)) > 0) { @@ -1574,8 +1592,7 @@ nextpage: free(search); search = uiprompt(statusbar.x, statusbar.y, "Search (%s):", tmp); - alldirty(); - draw(); + statusbar.dirty = 1; } if (!search) break;