Patch 8.0.1797
Problem: Terminal window is redrawn too often and scrolling is repeated.
Solution: Don't scroll immediately but only when redrawing. Avoid redrawing
the whole terminal window on every change.
Files: src/terminal.c, src/screen.c, src/proto/terminal.pro
*** ../vim-8.0.1796/src/terminal.c 2018-05-06 13:53:46.374938177 +0200
--- src/terminal.c 2018-05-06 16:38:36.516316098 +0200
***************
*** 42,50 ****
* redirection. Probably in call to channel_set_pipes().
* - Win32: Redirecting output does not work, Test_terminal_redir_file()
* is disabled.
- * - handle_moverect() scrolls one line at a time. Postpone scrolling, count
- * the number of lines, until a redraw happens. Then if scrolling many
lines
- * a redraw is faster.
* - Copy text in the vterm to the Vim buffer once in a while, so that
* completion works.
* - When the job only outputs lines, we could handle resizing the terminal
--- 42,47 ----
***************
*** 137,142 ****
--- 134,141 ----
int tl_dirty_row_start; /* MAX_ROW if nothing dirty */
int tl_dirty_row_end; /* row below last one to update */
+ int tl_postponed_scroll; /* to be scrolled up */
+
garray_T tl_scrollback;
int tl_scrollback_scrolled;
cellattr_T tl_default_color;
***************
*** 2373,2416 ****
term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, rect.start_row);
term->tl_dirty_row_end = MAX(term->tl_dirty_row_end, rect.end_row);
! redraw_buf_later(term->tl_buffer, NOT_VALID);
return 1;
}
static int
handle_moverect(VTermRect dest, VTermRect src, void *user)
{
term_T *term = (term_T *)user;
/* Scrolling up is done much more efficiently by deleting lines instead of
! * redrawing the text. */
if (dest.start_col == src.start_col
&& dest.end_col == src.end_col
&& dest.start_row < src.start_row)
{
! win_T *wp;
! VTermColor fg, bg;
! VTermScreenCellAttrs attr;
! int clear_attr;
!
! /* Set the color to clear lines with. */
! vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
! &fg, &bg);
! vim_memset(&attr, 0, sizeof(attr));
! clear_attr = cell2attr(attr, fg, bg);
!
! FOR_ALL_WINDOWS(wp)
! {
! if (wp->w_buffer == term->tl_buffer)
! win_del_lines(wp, dest.start_row,
! src.start_row - dest.start_row, FALSE, FALSE,
! clear_attr);
! }
}
term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, dest.start_row);
term->tl_dirty_row_end = MIN(term->tl_dirty_row_end, dest.end_row);
redraw_buf_later(term->tl_buffer, NOT_VALID);
return 1;
}
--- 2372,2426 ----
term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, rect.start_row);
term->tl_dirty_row_end = MAX(term->tl_dirty_row_end, rect.end_row);
! redraw_buf_later(term->tl_buffer, SOME_VALID);
return 1;
}
+ static void
+ term_scroll_up(term_T *term, int start_row, int count)
+ {
+ win_T *wp;
+ VTermColor fg, bg;
+ VTermScreenCellAttrs attr;
+ int clear_attr;
+
+ /* Set the color to clear lines with. */
+ vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
+ &fg, &bg);
+ vim_memset(&attr, 0, sizeof(attr));
+ clear_attr = cell2attr(attr, fg, bg);
+
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp->w_buffer == term->tl_buffer)
+ win_del_lines(wp, start_row, count, FALSE, FALSE, clear_attr);
+ }
+ }
+
static int
handle_moverect(VTermRect dest, VTermRect src, void *user)
{
term_T *term = (term_T *)user;
+ int count = src.start_row - dest.start_row;
/* Scrolling up is done much more efficiently by deleting lines instead of
! * redrawing the text. But avoid doing this multiple times, postpone until
! * the redraw happens. */
if (dest.start_col == src.start_col
&& dest.end_col == src.end_col
&& dest.start_row < src.start_row)
{
! if (dest.start_row == 0)
! term->tl_postponed_scroll += count;
! else
! term_scroll_up(term, dest.start_row, count);
}
term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, dest.start_row);
term->tl_dirty_row_end = MIN(term->tl_dirty_row_end, dest.end_row);
+ /* Note sure if the scrolling will work correctly, let's do a complete
+ * redraw later. */
redraw_buf_later(term->tl_buffer, NOT_VALID);
return 1;
}
***************
*** 2857,2867 ****
#endif
/*
! * Called to update a window that contains an active terminal.
! * Returns FAIL when there is no terminal running in this window or in
* Terminal-Normal mode.
*/
int
term_update_window(win_T *wp)
{
term_T *term = wp->w_buffer->b_term;
--- 2867,2888 ----
#endif
/*
! * Return TRUE if window "wp" is to be redrawn with term_update_window().
! * Returns FALSE when there is no terminal running in this window or it is in
* Terminal-Normal mode.
*/
int
+ term_do_update_window(win_T *wp)
+ {
+ term_T *term = wp->w_buffer->b_term;
+
+ return term != NULL && term->tl_vterm != NULL && !term->tl_normal_mode;
+ }
+
+ /*
+ * Called to update a window that contains an active terminal.
+ */
+ void
term_update_window(win_T *wp)
{
term_T *term = wp->w_buffer->b_term;
***************
*** 2874,2890 ****
int minsize;
win_T *twp;
- if (term == NULL || term->tl_vterm == NULL || term->tl_normal_mode)
- return FAIL;
-
vterm = term->tl_vterm;
screen = vterm_obtain_screen(vterm);
state = vterm_obtain_state(vterm);
! if (wp->w_redr_type >= SOME_VALID)
{
term->tl_dirty_row_start = 0;
term->tl_dirty_row_end = MAX_ROW;
}
/*
--- 2895,2917 ----
int minsize;
win_T *twp;
vterm = term->tl_vterm;
screen = vterm_obtain_screen(vterm);
state = vterm_obtain_state(vterm);
! /* We use NOT_VALID on a resize or scroll, redraw everything then. With
! * SOME_VALID only redraw what was marked dirty. */
! if (wp->w_redr_type > SOME_VALID)
{
term->tl_dirty_row_start = 0;
term->tl_dirty_row_end = MAX_ROW;
+
+ if (term->tl_postponed_scroll > 0
+ && term->tl_postponed_scroll < term->tl_rows / 3)
+ /* Scrolling is usually faster than redrawing, when there are only
+ * a few lines to scroll. */
+ term_scroll_up(term, 0, term->tl_postponed_scroll);
+ term->tl_postponed_scroll = 0;
}
/*
***************
*** 2943,2950 ****
}
term->tl_dirty_row_start = MAX_ROW;
term->tl_dirty_row_end = 0;
-
- return OK;
}
/*
--- 2970,2975 ----
*** ../vim-8.0.1796/src/screen.c 2018-04-27 22:53:03.930590711 +0200
--- src/screen.c 2018-05-06 16:30:59.487900163 +0200
***************
*** 567,574 ****
must_redraw = 0;
}
! /* Need to update w_lines[]. */
! if (curwin->w_lines_valid == 0 && type < NOT_VALID)
type = NOT_VALID;
/* Postpone the redrawing when it's not needed and when being called
--- 567,578 ----
must_redraw = 0;
}
! /* May need to update w_lines[]. */
! if (curwin->w_lines_valid == 0 && type < NOT_VALID
! #ifdef FEAT_TERMINAL
! && !term_do_update_window(curwin)
! #endif
! )
type = NOT_VALID;
/* Postpone the redrawing when it's not needed and when being called
***************
*** 1172,1181 ****
}
#ifdef FEAT_TERMINAL
! /* If this window contains a terminal, redraw works completely
differently.
! */
! if (term_update_window(wp) == OK)
{
# ifdef FEAT_MENU
/* Draw the window toolbar, if there is one. */
if (winbar_height(wp) > 0)
--- 1176,1185 ----
}
#ifdef FEAT_TERMINAL
! // If this window contains a terminal, redraw works completely
differently.
! if (term_do_update_window(wp))
{
+ term_update_window(wp);
# ifdef FEAT_MENU
/* Draw the window toolbar, if there is one. */
if (winbar_height(wp) > 0)
*** ../vim-8.0.1796/src/proto/terminal.pro 2018-04-14 17:05:29.787581114
+0200
--- src/proto/terminal.pro 2018-05-06 16:30:55.115937396 +0200
***************
*** 14,25 ****
int send_keys_to_term(term_T *term, int c, int typed);
int terminal_is_active(void);
cursorentry_T *term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg);
- void term_win_entered(void);
int term_use_loop(void);
int terminal_loop(int blocking);
void term_job_ended(job_T *job);
void term_channel_closed(channel_T *ch);
! int term_update_window(win_T *wp);
int term_is_finished(buf_T *buf);
int term_show_buffer(buf_T *buf);
void term_change_in_curbuf(void);
--- 14,26 ----
int send_keys_to_term(term_T *term, int c, int typed);
int terminal_is_active(void);
cursorentry_T *term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg);
int term_use_loop(void);
+ void term_win_entered(void);
int terminal_loop(int blocking);
void term_job_ended(job_T *job);
void term_channel_closed(channel_T *ch);
! int term_do_update_window(win_T *wp);
! void term_update_window(win_T *wp);
int term_is_finished(buf_T *buf);
int term_show_buffer(buf_T *buf);
void term_change_in_curbuf(void);
*** ../vim-8.0.1796/src/version.c 2018-05-06 13:53:46.378938152 +0200
--- src/version.c 2018-05-06 16:39:05.092106787 +0200
***************
*** 763,764 ****
--- 763,766 ----
{ /* Add new patch number below this line */
+ /**/
+ 1797,
/**/
--
I'm sure that I asked CBuilder to do a "full" install. Looks like I got
a "fool" install, instead. Charles E Campbell, Jr, PhD
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.