diff options
| author | mo khan <mo@mokhan.ca> | 2021-07-22 20:40:25 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2021-07-22 20:40:25 -0600 |
| commit | fe71aa1ba2c34ff054a51a19ec7d2e58ecaf10b0 (patch) | |
| tree | 5acbc4e2c6529b86490cf1a8eb2b90af1036d7ff | |
| parent | 2eeb871807ae461dac8f0d74431850e2ae65e871 (diff) | |
refactor: use an append buffer to flush multiple writes at once
| -rw-r--r-- | kilo.c | 44 |
1 files changed, 37 insertions, 7 deletions
@@ -4,6 +4,7 @@ #include <errno.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <sys/ioctl.h> #include <termios.h> #include <unistd.h> @@ -93,27 +94,56 @@ int get_window_size(int *rows, int *cols) { } } +/*** append buffer ***/ + +struct abuf { + char *b; + int len; +}; + +#define ABUF_INIT {NULL, 0} + +void ab_append(struct abuf *ab, const char *s, int len) { + char *new = realloc(ab->b, ab->len + len); + + if (new == NULL) return; + memcpy(&new[ab->len], s, len); + ab->b = new; + ab->len += len; +} + +void ab_free(struct abuf *ab) { + free(ab->b); +} + /*** output ***/ -void editor_draw_rows() { +void editor_draw_rows(struct abuf *ab) { for (int i = 0; i < E.screenrows; i++) { - write(STDOUT_FILENO, "~", 1); + ab_append(ab, "~", 1); if (i < E.screenrows - 1) { - write(STDOUT_FILENO, "\r\n", 2); + ab_append(ab, "\r\n", 2); } } } void editor_refresh_screen() { + struct abuf ab = ABUF_INIT; + // <esc>[0J clear screen from cursor up // <esc>[1J clear screen up to cursor // <esc>[2J clear entire screen - write(STDOUT_FILENO, "\x1b[2J", 4); + ab_append(&ab, "\x1b[2J", 4); // reposition cursor at the top-left corner - write(STDOUT_FILENO, "\x1b[H", 3); // https://vt100.net/docs/vt100-ug/chapter3.html#CUP - editor_draw_rows(); - write(STDOUT_FILENO, "\x1b[H", 3); + ab_append(&ab, "\x1b[H", 3); // https://vt100.net/docs/vt100-ug/chapter3.html#CUP + + editor_draw_rows(&ab); + + ab_append(&ab, "\x1b[H", 3); + + write(STDOUT_FILENO, ab.b, ab.len); + ab_free(&ab); } /*** input ***/ |
