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