Commit fe71aa1

mo khan <mo@mokhan.ca>
2021-07-23 02:40:25
refactor: use an append buffer to flush multiple writes at once
1 parent 2eeb871
Changed files (1)
kilo.c
@@ -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 ***/