commit 47706e9bc61a337498f43c7053048932ce617b75
parent 34be376a9445ac7283268a5cdd7c07dee65e576d
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun, 12 Oct 2014 22:05:12 +0000
optimize line_draw, reduces flicker in some terminals
Diffstat:
M | sob.c | | | 32 | ++++++++++++++++++++++++++++---- |
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/sob.c b/sob.c
@@ -29,6 +29,7 @@ struct line {
size_t utfpos; /* pos in characters */
size_t colpos; /* cursor position (in columns) */
size_t collen; /* total length (in columns) */
+ size_t dirtylen; /* dirty length (in columns) */
};
static void cb_pipe_insert(const char *, size_t);
@@ -66,6 +67,7 @@ static int pipe_readline(int, int, char *, void (*)(const char *, size_t));
static int pipe_cmd(char *[], char *, void (*)(const char *, size_t));
static void cleanup(void);
+static void clear(void);
static void gettermsize(void);
static void handleinput(const unsigned char *, size_t);
static void resize(void);
@@ -245,11 +247,22 @@ line_prompt(void)
static void
line_draw(void)
{
- fprintf(outfp, "\x1b[2J\x1b[H"); /* clear */
- fflush(outfp);
+ size_t i;
+
+ fprintf(outfp, "\x1b[H"); /* move cursor to (0, 0) */
+ fprintf(outfp, "\x1b[?25l"); /* hide cursor */
+
line_prompt();
fwrite(line.line, 1, line.bytesiz, outfp);
+
+ /* replace dirty chars with ' ' */
+ if(line.dirtylen > line.collen) {
+ for(i = line.collen; i < line.dirtylen; i++)
+ fputc(' ', outfp);
+ }
line_cursor_move(line.colpos);
+ fprintf(outfp, "\x1b[?25h"); /* show cursor */
+ fflush(outfp);
}
static void
@@ -394,7 +407,6 @@ line_delcharprev(void)
line.utfpos--;
line.colpos -= col;
line.collen -= col;
-
line_draw();
}
@@ -691,6 +703,7 @@ sighandler(int signum)
isrunning = 0;
cleanup();
} else if(signum == SIGWINCH) {
+ clear();
gettermsize();
resize();
line_draw();
@@ -710,10 +723,12 @@ setup(void)
/* set the terminal attributes */
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
-
/* get terminal window size */
gettermsize();
+ /* clear screen */
+ clear();
+
/* signal handling */
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_RESTART;
@@ -754,6 +769,7 @@ handleinput(const unsigned char *input, size_t len)
int ismatch = 0;
char buf[BUFSIZ];
+ line.dirtylen = line.collen;
while(p < len && input[p] != '\0') {
if(input[p] <= 0x1b) {
ismatch = 0;
@@ -838,6 +854,14 @@ usage(void)
exit(EXIT_FAILURE);
}
+static void
+clear(void)
+{
+ /* clear screen, move cursor to (0, 0) */
+ fprintf(outfp, "\x1b[2J\x1b[H");
+ fflush(outfp);
+}
+
int
main(int argc, char **argv)
{