aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Fürmetz <fuermetz@mailbox.org>2018-12-11 14:21:03 +0100
committerLukas Fürmetz <fuermetz@mailbox.org>2018-12-11 14:21:03 +0100
commit42c7802db348b2601527a4a53cb1786f672e0848 (patch)
tree08245fca829593741ef871f60132b89af17afc31
parentd4e326a01ad1fd764ca5587f2e42b959034f35af (diff)
parentb3bb2997b8b91d77da5382b7a77c76c704024e60 (diff)
Merge remote-tracking branch 'jixiuf/fix-window-resize'
-rw-r--r--vterm-module.c75
-rw-r--r--vterm-module.h2
-rw-r--r--vterm.el2
3 files changed, 57 insertions, 22 deletions
diff --git a/vterm-module.c b/vterm-module.c
index 7c93fa7..d401eb0 100644
--- a/vterm-module.c
+++ b/vterm-module.c
@@ -120,10 +120,32 @@ static void fetch_cell(Term *term, int row, int col, VTermScreenCell *cell) {
}
}
+static bool is_eol(Term *term, int end_col, int row, int col) {
+ /* This cell is EOL if this and every cell to the right is black */
+ if (row >= 0) {
+ VTermPos pos = {.row = row, .col = col};
+ return vterm_screen_is_eol(term->vts, pos);
+ }
+
+ ScrollbackLine *sbrow = term->sb_buffer[-row - 1];
+ int c;
+ for (c = col; c < end_col && c < sbrow->cols;) {
+ if (sbrow->cells[c].chars[0]) {
+ return 0;
+ }
+ c += sbrow->cells[c].width;
+ }
+ return 1;
+}
+
static size_t get_col_offset(Term *term, int row, int end_col) {
int col = 0;
size_t offset = 0;
unsigned char buf[4];
+ int height;
+ int width;
+ vterm_get_size(term->vt, &height, &width);
+
while (col < end_col) {
VTermScreenCell cell;
@@ -132,6 +154,10 @@ static size_t get_col_offset(Term *term, int row, int end_col) {
if (cell.width > 1) {
offset += cell.width - 1;
}
+ } else {
+ if (is_eol(term, term->width, row, col)) {
+ offset += cell.width;
+ }
}
col += cell.width;
}
@@ -164,6 +190,10 @@ static void refresh_lines(Term *term, emacs_env *env, int start_row,
lastCell = cell;
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 */
+ break;
+ }
buffer[length] = ' ';
length++;
} else {
@@ -194,34 +224,39 @@ static void refresh_lines(Term *term, emacs_env *env, int start_row,
// Refresh the screen (visible part of the buffer when the terminal is
// focused) of a invalidated terminal
static void refresh_screen(Term *term, emacs_env *env) {
- int height;
- int width;
+ // Term height may have decreased before `invalid_end` reflects it.
+ term->invalid_end = MIN(term->invalid_end, term->height);
if (term->invalid_end >= term->invalid_start) {
- vterm_get_size(term->vt, &height, &width);
-
- // Term height may have decreased before `invalid_end` reflects it.
int line_start = row_to_linenr(term, term->invalid_start);
goto_line(env, line_start);
delete_lines(env, line_start, term->invalid_end - term->invalid_start,
true);
- refresh_lines(term, env, term->invalid_start, term->invalid_end, width);
+ refresh_lines(term, env, term->invalid_start, term->invalid_end,
+ term->width);
}
term->invalid_start = INT_MAX;
term->invalid_end = -1;
}
-static int term_resize(int rows, int cols, void *term) {
- invalidate_terminal(term, 0, rows);
+static int term_resize(int rows, int cols, void *user_data) {
+ /* can not use invalidate_terminal here */
+ /* when the window heigh decreased, */
+ /* the value of term->invalid_end can't bigger than window height */
+ Term *term = (Term *)user_data;
+ term->invalid_start = 0;
+ term->invalid_end = rows;
+ term->width = cols;
+ term->height = rows;
+ invalidate_terminal(term, -1, -1);
+
return 1;
}
// Refresh the scrollback of an invalidated terminal.
static void refresh_scrollback(Term *term, emacs_env *env) {
- int width, height;
int buffer_lnum;
- vterm_get_size(term->vt, &height, &width);
if (term->sb_pending > 0) {
// This means that either the window height has decreased or the screen
@@ -230,17 +265,18 @@ static void refresh_scrollback(Term *term, emacs_env *env) {
// section of the buffer
buffer_lnum = env->extract_integer(env, buffer_line_number(env));
- int del_cnt = buffer_lnum - height - (int)term->sb_size + term->sb_pending;
+ int del_cnt =
+ buffer_lnum - term->height - (int)term->sb_size + term->sb_pending;
if (del_cnt > 0) {
delete_lines(env, 1, del_cnt, true);
buffer_lnum = env->extract_integer(env, buffer_line_number(env));
}
- int buf_index = buffer_lnum - height + 1;
+ int buf_index = buffer_lnum - term->height + 1;
goto_line(env, buf_index);
- refresh_lines(term, env, -term->sb_pending, 0, width);
+ refresh_lines(term, env, -term->sb_pending, 0, term->width);
term->sb_pending = 0;
}
- int max_line_count = (int)term->sb_current + height;
+ int max_line_count = (int)term->sb_current + term->height;
buffer_lnum = env->extract_integer(env, buffer_line_number(env));
// Remove extra lines at the bottom
@@ -251,9 +287,6 @@ static void refresh_scrollback(Term *term, emacs_env *env) {
}
static void adjust_topline(Term *term, emacs_env *env, long added) {
- int height, width;
- vterm_get_size(term->vt, &height, &width);
-
int buffer_lnum = env->extract_integer(env, buffer_line_number(env));
VTermState *state = vterm_obtain_state(term->vt);
VTermPos pos;
@@ -594,6 +627,9 @@ static emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs,
term->sb_buffer = malloc(sizeof(ScrollbackLine *) * term->sb_size);
term->invalid_start = 0;
term->invalid_end = rows;
+ term->width = cols;
+ term->height = rows;
+
term->cursor.visible = true;
term->cursor.blinking = false;
term->title = NULL;
@@ -651,10 +687,7 @@ static emacs_value Fvterm_set_size(emacs_env *env, ptrdiff_t nargs,
int rows = env->extract_integer(env, args[1]);
int cols = env->extract_integer(env, args[2]);
- int old_rows, old_cols;
- vterm_get_size(term->vt, &old_rows, &old_cols);
-
- if (cols != old_cols || rows != old_rows) {
+ if (cols != term->width || rows != term->height) {
vterm_set_size(term->vt, rows, cols);
vterm_screen_flush_damage(term->vts);
diff --git a/vterm-module.h b/vterm-module.h
index 9f809b3..d985033 100644
--- a/vterm-module.h
+++ b/vterm-module.h
@@ -50,6 +50,8 @@ typedef struct Term {
Cursor cursor;
char *title;
bool is_title_changed;
+
+ int width, height;
} Term;
// Faces
diff --git a/vterm.el b/vterm.el
index 1978fe5..469a12c 100644
--- a/vterm.el
+++ b/vterm.el
@@ -305,7 +305,7 @@ Feeds the size change to the virtual terminal."
(defun vterm--buffer-line-num()
"Return the maximum line number."
- (line-number-at-pos (point-max)))
+ (count-lines (point-min) (point-max)))
(defun vterm--set-title (title)
"Run the `vterm--set-title-hook' with TITLE as argument."