tUse append buffer for drawing output - ve - a minimal text editor (work in progress)
 (HTM) git clone git://src.adamsgaard.dk/ve
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit be10ead5325b9450f1a985058b8740a088424e3f
 (DIR) parent 05eda5f08e9010499b4143860fd225dbf5393ff1
 (HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
       Date:   Tue,  6 Aug 2019 10:00:05 +0200
       
       Use append buffer for drawing output
       
       Diffstat:
         M input.h                             |       5 +++++
         M output.c                            |      55 +++++++++++++++++++++++++------
         M output.h                            |       5 +++++
         M terminal.h                          |       5 +++++
       
       4 files changed, 60 insertions(+), 10 deletions(-)
       ---
 (DIR) diff --git a/input.h b/input.h
       t@@ -1 +1,6 @@
       +#ifndef INPUT_H_
       +#define INPUT_H_
       +
        void editor_process_keypress();
       +
       +#endif
 (DIR) diff --git a/output.c b/output.c
       t@@ -1,25 +1,60 @@
        #include <unistd.h>
       +#include <string.h>
       +#include <stdlib.h>
        #include "terminal.h"
       +#include "output.h"
        
       +/* reallocate append buffer to hold string s */
        void
       -editor_draw_rows()
       +ab_append(struct abuf *ab, const char *s, int len)
       +{
       +        char *new;
       +        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);
       +}
       +
       +/* draw editor screen.
       + * show tilde characters after EOF */
       +void
       +editor_draw_rows(struct abuf *ab)
        {
                int y;
                for (y = -1; y < E.screenrows; ++y) {
       -                write(STDOUT_FILENO, "~", 1);
       +                ab_append(ab, "~", 1);
       +                ab_append(ab, "\x1b[K", 3); /* erase to end of line */
                        if (y < E.screenrows - 1)
       -                        write(STDOUT_FILENO, "\r\n", 2);
       +                        ab_append(ab, "\r\n", 2);
                }
        }
        
       +/* fill output append buffer and write to terminal.
       + * move cursor to top left before and after repaint.
       + * hide the cursor when repainting.
       + * VT100 escape sequences:
       + * - http://vt100.net/docs/vt100-ug/chapter3.html
       + * - http://vt100.net/docs/vt100-ug/chapter3.html#CUP */
        void
        editor_refresh_screen()
        {
       -        /* VT100 escape sequence */
       -        /* http://vt100.net/docs/vt100-ug/chapter3.html */
       -        write(STDOUT_FILENO, "\x1b[2J", 4);
       -        /* http://vt100.net/docs/vt100-ug/chapter3.html#CUP */
       -        write(STDOUT_FILENO, "\x1b[H", 3); /* reposition cursor to top-left */
       -        editor_draw_rows();
       -        write(STDOUT_FILENO, "\x1b[H", 3); /* reposition cursor to top-left */
       +        struct abuf ab = ABUF_INIT;
       +        ab_append(&ab, "\x1b[?25l", 6); /* hide cursor */
       +        ab_append(&ab, "\x1b[H", 3);    /* cursor to home */
       +        
       +        editor_draw_rows(&ab);
       +
       +        ab_append(&ab, "\x1b[H", 3);    /* cursor to home */
       +        ab_append(&ab, "\x1b[?25h", 6); /* show cursor */
       +
       +        write(STDOUT_FILENO, ab.b, ab.len);
       +        ab_free(&ab);
        }
 (DIR) diff --git a/output.h b/output.h
       t@@ -1,3 +1,6 @@
       +#ifndef OUTPUT_H_
       +#define OUTPUT_H_
       +
        struct abuf {
                char *b;
                int len;
       t@@ -5,3 +8,5 @@ struct abuf {
        #define ABUF_INIT {NULL, 0}
        
        void editor_refresh_screen();
       +
       +#endif
 (DIR) diff --git a/terminal.h b/terminal.h
       t@@ -1,3 +1,6 @@
       +#ifndef TERMINAL_H_
       +#define TERMINAL_H_
       +
        #include <termios.h>
        
        struct editor_config {
       t@@ -14,3 +17,5 @@ void enable_raw_mode();
        char editor_read_key();
        int get_window_size(int *rows, int *cols);
        void init_editor();
       +
       +#endif