tUse append buffer for drawing output - ve - a minimal text editor (work in pro… | |
git clone git://src.adamsgaard.dk/ve | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit be10ead5325b9450f1a985058b8740a088424e3f | |
parent 05eda5f08e9010499b4143860fd225dbf5393ff1 | |
Author: Anders Damsgaard <[email protected]> | |
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(-) | |
--- | |
diff --git a/input.h b/input.h | |
t@@ -1 +1,6 @@ | |
+#ifndef INPUT_H_ | |
+#define INPUT_H_ | |
+ | |
void editor_process_keypress(); | |
+ | |
+#endif | |
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); | |
} | |
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 | |
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 |