aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vterm-module.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/vterm-module.c b/vterm-module.c
index 7bdd635..0418b69 100644
--- a/vterm-module.c
+++ b/vterm-module.c
@@ -264,8 +264,18 @@ static void refresh_lines(Term *term, emacs_env *env, int start_row,
}
int i, j;
- char buffer[((end_row - start_row + 1) * end_col) * 4];
+#define PUSH_BUFFER(c) do { \
+ if (length == capacity) { \
+ capacity += end_col * 4; \
+ buffer = realloc(buffer, capacity * sizeof(char)); \
+ } \
+ buffer[length] = (c); \
+ length++; \
+ } while (0)
+
+ int capacity = ((end_row - start_row + 1) * end_col) * 4;
int length = 0;
+ char* buffer = malloc(capacity * sizeof(char));
VTermScreenCell cell;
VTermScreenCell lastCell;
fetch_cell(term, start_row, 0, &lastCell);
@@ -298,19 +308,18 @@ static void refresh_lines(Term *term, emacs_env *env, int start_row,
if (cell.chars[0] == 0) {
if (is_eol(term, end_col, i, j)) {
/* This cell is EOL if this and every cell to the right is black */
- buffer[length] = '\n';
- length++;
+ PUSH_BUFFER('\n');
newline = 1;
break;
}
- buffer[length] = ' ';
- length++;
+ PUSH_BUFFER(' ');
} else {
- unsigned char bytes[4];
- size_t count = codepoint_to_utf8(cell.chars[0], bytes);
- for (int k = 0; k < count; k++) {
- buffer[length] = bytes[k];
- length++;
+ for (int k = 0; k < VTERM_MAX_CHARS_PER_CELL && cell.chars[k]; ++k) {
+ unsigned char bytes[4];
+ size_t count = codepoint_to_utf8(cell.chars[k], bytes);
+ for (int l = 0; l < count; l++) {
+ PUSH_BUFFER(bytes[l]);
+ }
}
}
@@ -337,6 +346,9 @@ static void refresh_lines(Term *term, emacs_env *env, int start_row,
emacs_value text = render_text(env, term, buffer, length, &lastCell);
insert(env, text);
+#undef PUSH_BUFFER
+ free(buffer);
+
return;
}
// Refresh the screen (visible part of the buffer when the terminal is