Skip to content

Commit

Permalink
Merge pull request #9883 from bfredl/termredraw
Browse files Browse the repository at this point in the history
make terminal state redraw like any other state
  • Loading branch information
bfredl committed May 14, 2019
2 parents 9e0982a + 5020daa commit 94f78cc
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 85 deletions.
97 changes: 31 additions & 66 deletions src/nvim/terminal.c
Expand Up @@ -401,7 +401,6 @@ void terminal_enter(void)
showmode(); showmode();
curwin->w_redr_status = true; // For mode() in statusline. #8323 curwin->w_redr_status = true; // For mode() in statusline. #8323
ui_busy_start(); ui_busy_start();
redraw(false);


s->state.execute = terminal_execute; s->state.execute = terminal_execute;
s->state.check = terminal_check; s->state.check = terminal_check;
Expand All @@ -417,8 +416,10 @@ void terminal_enter(void)


// draw the unfocused cursor // draw the unfocused cursor
invalidate_terminal(s->term, s->term->cursor.row, s->term->cursor.row + 1); invalidate_terminal(s->term, s->term->cursor.row, s->term->cursor.row + 1);
if (curbuf->terminal == s->term && !s->close) {
terminal_check_cursor();
}
unshowmode(true); unshowmode(true);
redraw(curbuf->handle != s->term->buf_handle);
ui_busy_stop(); ui_busy_stop();
if (s->close) { if (s->close) {
bool wipe = s->term->buf_handle != 0; bool wipe = s->term->buf_handle != 0;
Expand All @@ -429,6 +430,20 @@ void terminal_enter(void)
} }
} }


static void terminal_check_cursor(void)
{
Terminal *term = curbuf->terminal;
curwin->w_wrow = term->cursor.row;
curwin->w_wcol = term->cursor.col + win_col_off(curwin);
curwin->w_cursor.lnum = MIN(curbuf->b_ml.ml_line_count,
row_to_linenr(term, term->cursor.row));
// Nudge cursor when returning to normal-mode.
int off = is_focused(term) ? 0 : (curwin->w_p_rl ? 1 : -1);
curwin->w_cursor.col = MAX(0, term->cursor.col + win_col_off(curwin) + off);
curwin->w_cursor.coladd = 0;
mb_check_adjust_col(curwin);
}

// Function executed before each iteration of terminal mode. // Function executed before each iteration of terminal mode.
// Return: // Return:
// 1 if the iteration should continue normally // 1 if the iteration should continue normally
Expand All @@ -438,6 +453,19 @@ static int terminal_check(VimState *state)
if (stop_insert_mode) { if (stop_insert_mode) {
return 0; return 0;
} }

terminal_check_cursor();

if (must_redraw) {
update_screen(0);
}

if (need_maketitle) { // Update title in terminal-mode. #7248
maketitle();
}

setcursor();
ui_flush();
return 1; return 1;
} }


Expand Down Expand Up @@ -1151,11 +1179,7 @@ static void refresh_terminal(Terminal *term)
static void refresh_timer_cb(TimeWatcher *watcher, void *data) static void refresh_timer_cb(TimeWatcher *watcher, void *data)
{ {
refresh_pending = false; refresh_pending = false;
if (exiting // Cannot redraw (requires event loop) during teardown/exit. if (exiting) { // Cannot redraw (requires event loop) during teardown/exit.
|| (State & CMDPREVIEW)
// WM_LIST (^D) is not redrawn, unlike the normal wildmenu. So we must
// skip redraws to keep it visible.
|| wild_menu_showing == WM_LIST) {
return; return;
} }
Terminal *term; Terminal *term;
Expand All @@ -1165,12 +1189,8 @@ static void refresh_timer_cb(TimeWatcher *watcher, void *data)
map_foreach(invalidated_terminals, term, stub, { map_foreach(invalidated_terminals, term, stub, {
refresh_terminal(term); refresh_terminal(term);
}); });
bool any_visible = is_term_visible();
pmap_clear(ptr_t)(invalidated_terminals); pmap_clear(ptr_t)(invalidated_terminals);
unblock_autocmds(); unblock_autocmds();
if (any_visible) {
redraw(true);
}
} }


static void refresh_size(Terminal *term, buf_T *buf) static void refresh_size(Terminal *term, buf_T *buf)
Expand Down Expand Up @@ -1284,61 +1304,6 @@ static void refresh_screen(Terminal *term, buf_T *buf)
term->invalid_end = -1; term->invalid_end = -1;
} }


/// @return true if any invalidated terminal buffer is visible to the user
static bool is_term_visible(void)
{
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_buffer->terminal
&& pmap_has(ptr_t)(invalidated_terminals, wp->w_buffer->terminal)) {
return true;
}
}
return false;
}

static void redraw(bool restore_cursor)
{
Terminal *term = curbuf->terminal;
if (!term) {
restore_cursor = true;
}

int save_row = 0;
int save_col = 0;
if (restore_cursor) {
// save the current row/col to restore after updating screen when not
// focused
save_row = ui_current_row();
save_col = ui_current_col();
}
block_autocmds();

if (must_redraw) {
update_screen(0);
}

if (need_maketitle) { // Update title in terminal-mode. #7248
maketitle();
}

if (restore_cursor) {
ui_cursor_goto(save_row, save_col);
} else if (term) {
curwin->w_wrow = term->cursor.row;
curwin->w_wcol = term->cursor.col + win_col_off(curwin);
curwin->w_cursor.lnum = MIN(curbuf->b_ml.ml_line_count,
row_to_linenr(term, term->cursor.row));
// Nudge cursor when returning to normal-mode.
int off = is_focused(term) ? 0 : (curwin->w_p_rl ? 1 : -1);
curwin->w_cursor.col = MAX(0, term->cursor.col + win_col_off(curwin) + off);
curwin->w_cursor.coladd = 0;
mb_check_adjust_col(curwin);
}

unblock_autocmds();
ui_flush();
}

static void adjust_topline(Terminal *term, buf_T *buf, long added) static void adjust_topline(Terminal *term, buf_T *buf, long added)
{ {
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
Expand Down
12 changes: 6 additions & 6 deletions test/functional/terminal/scrollback_spec.lua
Expand Up @@ -142,15 +142,15 @@ describe(':terminal scrollback', function()
describe('and height decreased by 1', function() describe('and height decreased by 1', function()
if helpers.pending_win32(pending) then return end if helpers.pending_win32(pending) then return end
local function will_hide_top_line() local function will_hide_top_line()
feed([[<C-\><C-N>:]]) -- Go to cmdline-mode, so cursor is at bottom. feed([[<C-\><C-N>]])
screen:try_resize(screen._width - 2, screen._height - 1) screen:try_resize(screen._width - 2, screen._height - 1)
screen:expect([[ screen:expect([[
line2 | line2 |
line3 | line3 |
line4 | line4 |
rows: 5, cols: 28 | rows: 5, cols: 28 |
{2: } | {2:^ } |
:^ | |
]]) ]])
end end


Expand All @@ -166,11 +166,11 @@ describe(':terminal scrollback', function()
screen:expect([[ screen:expect([[
rows: 5, cols: 28 | rows: 5, cols: 28 |
rows: 3, cols: 26 | rows: 3, cols: 26 |
{2: } | {2:^ } |
:^ | |
]]) ]])
eq(8, curbuf('line_count')) eq(8, curbuf('line_count'))
feed([[<C-\><C-N>3k]]) feed([[3k]])
screen:expect([[ screen:expect([[
^line4 | ^line4 |
rows: 5, cols: 28 | rows: 5, cols: 28 |
Expand Down
8 changes: 4 additions & 4 deletions test/functional/terminal/window_split_tab_spec.lua
Expand Up @@ -69,7 +69,7 @@ describe(':terminal', function()
end) end)


it('forwards resize request to the program', function() it('forwards resize request to the program', function()
feed([[<C-\><C-N>G:]]) -- Go to cmdline-mode, so cursor is at bottom. feed([[<C-\><C-N>G]])
local w1, h1 = screen._width - 3, screen._height - 2 local w1, h1 = screen._width - 3, screen._height - 2
local w2, h2 = w1 - 6, h1 - 3 local w2, h2 = w1 - 6, h1 - 3


Expand All @@ -92,16 +92,16 @@ describe(':terminal', function()
| |
| |
| |
^ |
| |
:^ |
]]) ]])
screen:try_resize(w2, h2) screen:try_resize(w2, h2)
screen:expect([[ screen:expect([[
tty ready | tty ready |
rows: 7, cols: 47 | rows: 7, cols: 47 |
rows: 4, cols: 41 | rows: 4, cols: 41 |
{2: } | {2:^ } |
:^ | |
]]) ]])
end) end)
end) end)
14 changes: 8 additions & 6 deletions test/functional/ui/searchhl_spec.lua
Expand Up @@ -163,12 +163,14 @@ describe('search highlighting', function()
]]) ]])
feed('/foo') feed('/foo')
sleep(50) -- Allow some terminal activity. sleep(50) -- Allow some terminal activity.
screen:expect([[ -- NB: in earlier versions terminal output was redrawn during cmdline mode.
{3:foo} bar baz {3:│}xxx | -- For now just assert that the screens remain unchanged.
bar baz {2:foo} {3:│}xxx | screen:expect([[
bar {2:foo} baz {3:│}xxx | {3:foo} bar baz {3:│} |
{3:│}xxx | bar baz {2:foo} {3:│} |
{1:~ }{3:│}xxx | bar {2:foo} baz {3:│} |
{3:│} |
{1:~ }{3:│} |
{5:[No Name] [+] }{3:term }| {5:[No Name] [+] }{3:term }|
/foo^ | /foo^ |
]], { [1] = {bold = true, foreground = Screen.colors.Blue1}, ]], { [1] = {bold = true, foreground = Screen.colors.Blue1},
Expand Down
8 changes: 5 additions & 3 deletions test/functional/ui/wildmode_spec.lua
Expand Up @@ -95,10 +95,12 @@ describe("'wildmenu'", function()


feed([[<C-\><C-N>gg]]) feed([[<C-\><C-N>gg]])
feed([[:sign <Tab>]]) -- Invoke wildmenu. feed([[:sign <Tab>]]) -- Invoke wildmenu.
-- NB: in earlier versions terminal output was redrawn during cmdline mode.
-- For now just assert that the screen remains unchanged.
expect_stay_unchanged{grid=[[ expect_stay_unchanged{grid=[[
foo | |
foo | |
foo | |
define jump list > | define jump list > |
:sign define^ | :sign define^ |
]]} ]]}
Expand Down

0 comments on commit 94f78cc

Please sign in to comment.