From 8df6736ca14d09f87cf0a8486758ac5708819434 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Wed, 24 May 2023 10:04:49 +0200 Subject: [PATCH] feat(term): enable reflow by default (#21124) Problem: Contents of terminal buffer are not reflown when Nvim is resized. Solution: Enable reflow in libvterm by default. Now that libvterm is vendored, also fix "TUI rapid resize" test failures there. Note: Neovim's scrollback buffer does not support reflow (yet), so lines vanishing into the buffer due to a too small window will be restored without reflow. --- runtime/doc/news.txt | 3 +++ runtime/doc/options.txt | 3 +++ runtime/lua/vim/_meta/options.lua | 3 +++ src/nvim/options.lua | 3 +++ src/nvim/terminal.c | 3 +-- src/vterm/screen.c | 4 ++-- test/functional/terminal/window_spec.lua | 8 ++++---- 7 files changed, 19 insertions(+), 8 deletions(-) diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 4df7d6442a..68a05a99a4 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -163,6 +163,9 @@ TERMINAL system clipboard (copy). Querying with OSC 52 (paste) is not supported. • |hl-StatusLineTerm| and |hl-StatusLineTermNC| define highlights for the status line in |terminal| windows. +• The terminal buffer now supports reflow (wrapped lines adapt when the buffer + is resized horizontally). Note: Lines that are not visible and kept in + 'scrollback' are not reflown. TREESITTER diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index bc2a8ae263..f44e0954a5 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -5031,6 +5031,9 @@ A jump table for the options with a short description can be found at |Q_op|. Minimum is 1, maximum is 100000. Only in |terminal| buffers. + Note: Lines that are not visible and kept in scrollback are not + reflown when the terminal buffer is resized horizontally. + *'scrollbind'* *'scb'* *'noscrollbind'* *'noscb'* 'scrollbind' 'scb' boolean (default off) local to window diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index 10c888548c..b4ac478b61 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -5253,6 +5253,9 @@ vim.wo.scr = vim.wo.scroll --- Minimum is 1, maximum is 100000. --- Only in `terminal` buffers. --- +--- Note: Lines that are not visible and kept in scrollback are not +--- reflown when the terminal buffer is resized horizontally. +--- --- @type integer vim.o.scrollback = -1 vim.o.scbk = vim.o.scrollback diff --git a/src/nvim/options.lua b/src/nvim/options.lua index ef7cc2fb89..3612a80fb8 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -6627,6 +6627,9 @@ return { top are deleted if new lines exceed this limit. Minimum is 1, maximum is 100000. Only in |terminal| buffers. + + Note: Lines that are not visible and kept in scrollback are not + reflown when the terminal buffer is resized horizontally. ]=], full_name = 'scrollback', redraw = { 'current_buffer' }, diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index abc9b3534b..54a0de9c22 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -319,8 +319,7 @@ void terminal_open(Terminal **termpp, buf_T *buf, TerminalOptions opts) // Set up screen term->vts = vterm_obtain_screen(term->vt); vterm_screen_enable_altscreen(term->vts, true); - // TODO(clason): reenable when https://github.com/neovim/neovim/issues/23762 is fixed - // vterm_screen_enable_reflow(term->vts, true); + vterm_screen_enable_reflow(term->vts, true); // delete empty lines at the end of the buffer vterm_screen_set_callbacks(term->vts, &vterm_screen_callbacks, term); vterm_screen_set_unrecognised_fallbacks(term->vts, &vterm_fallbacks, term); diff --git a/src/vterm/screen.c b/src/vterm/screen.c index 97a8d50b93..720d1bb939 100644 --- a/src/vterm/screen.c +++ b/src/vterm/screen.c @@ -534,7 +534,7 @@ static void resize_buffer(VTermScreen *screen, int bufidx, int new_rows, int new while(old_row >= 0) { int old_row_end = old_row; /* TODO: Stop if dwl or dhl */ - while(REFLOW && old_lineinfo && old_row >= 0 && old_lineinfo[old_row].continuation) + while(REFLOW && old_lineinfo && old_row > 0 && old_lineinfo[old_row].continuation) old_row--; int old_row_start = old_row; @@ -596,7 +596,7 @@ static void resize_buffer(VTermScreen *screen, int bufidx, int new_rows, int new #endif if(new_row_start < 0) { - if(old_row_start <= old_cursor.row && old_cursor.row < old_row_end) { + if(old_row_start <= old_cursor.row && old_cursor.row <= old_row_end) { new_cursor.row = 0; new_cursor.col = old_cursor.col; if(new_cursor.col >= new_cols) diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua index 64534ca8dc..18477fdf2d 100644 --- a/test/functional/terminal/window_spec.lua +++ b/test/functional/terminal/window_spec.lua @@ -87,7 +87,7 @@ describe(':terminal window', function() {7: 1 }tty ready | {7: 2 }rows: 6, cols: 48 | {7: 3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO| - {7: 4 }WXYZrows: 6, cols: 41 | + {7: 4 }PQRSTUVWXYZrows: 6, cols: 41 | {7: 5 }{1: } | {7: 6 } | {3:-- TERMINAL --} | @@ -97,7 +97,7 @@ describe(':terminal window', function() {7: 1 }tty ready | {7: 2 }rows: 6, cols: 48 | {7: 3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO| - {7: 4 }WXYZrows: 6, cols: 41 | + {7: 4 }PQRSTUVWXYZrows: 6, cols: 41 | {7: 5 } abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN| {7: 6 }OPQRSTUVWXYZ{1: } | {3:-- TERMINAL --} | @@ -132,9 +132,9 @@ describe(':terminal window', function() screen:expect([[ {7:++ 7 } | {7:++ 8 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR| - {7:++ 9 }TUVWXYZ | + {7:++ 9 }STUVWXYZ | {7:++10 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR| - {7:++11 }TUVWXYZrows: 6, cols: 44 | + {7:++11 }STUVWXYZrows: 6, cols: 44 | {7:++12 }{1: } | {3:-- TERMINAL --} | ]])