From 49a9fb2d9848ab06727bf966ae9c0d1a901216d5 Mon Sep 17 00:00:00 2001 From: Javier Lopez Date: Mon, 4 Jul 2022 15:09:47 -0500 Subject: [PATCH 1/2] fix(tui): resize at startup #17795 * fix(test): screen.lua nil index When actual_rows and expected_rows are different avoid a nil index. * fix(tui): resize at startup The deleted code is not needed after 402b4e8. It caused the condition to false positive when the function was called more than once before startup (first normal mode). Being itself what set the dimension and not the user, locking the size of the screen to an incorrect size. Make got_winch an int to mitigate: tui_grid_resize changing the size of the host terminal between the signal handler and the call to sigwinch_cb. Since the actual signal handler uv__signal_handle doesn't directly call the callback, the event loop does. Fixes #17285 Fixes #15044 Fixes #11330 --- src/nvim/tui/tui.c | 25 +++++++------------------ test/functional/terminal/tui_spec.lua | 18 ++++++++++++++++++ test/functional/ui/screen.lua | 2 +- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 13a67dafa6..725eb2e316 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -137,8 +137,7 @@ struct TUIData { char *space_buf; }; -static bool volatile got_winch = false; -static bool did_user_set_dimensions = false; +static int got_winch = 0; static bool cursor_style_enabled = false; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -536,7 +535,7 @@ static void sigcont_cb(SignalWatcher *watcher, int signum, void *data) static void sigwinch_cb(SignalWatcher *watcher, int signum, void *data) { - got_winch = true; + got_winch++; UI *ui = data; if (tui_is_stopped(ui)) { return; @@ -989,7 +988,7 @@ static void tui_grid_resize(UI *ui, Integer g, Integer width, Integer height) r->right = MIN(r->right, grid->width); } - if (!got_winch && (!data->is_starting || did_user_set_dimensions)) { + if (!got_winch && !data->is_starting) { // Resize the _host_ terminal. UNIBI_SET_NUM_VAR(data->params[0], (int)height); UNIBI_SET_NUM_VAR(data->params[1], (int)width); @@ -999,7 +998,7 @@ static void tui_grid_resize(UI *ui, Integer g, Integer width, Integer height) reset_scroll_region(ui, ui->width == grid->width); } } else { // Already handled the SIGWINCH signal; avoid double-resize. - got_winch = false; + got_winch = got_winch > 0 ? got_winch - 1 : 0; grid->row = -1; } } @@ -1507,23 +1506,13 @@ static void tui_guess_size(UI *ui) TUIData *data = ui->data; int width = 0, height = 0; - // 1 - look for non-default 'columns' and 'lines' options during startup - if (data->is_starting && (Columns != DFLT_COLS || Rows != DFLT_ROWS)) { - did_user_set_dimensions = true; - assert(Columns >= 0); - assert(Rows >= 0); - width = Columns; - height = Rows; - goto end; - } - - // 2 - try from a system call(ioctl/TIOCGWINSZ on unix) + // 1 - try from a system call(ioctl/TIOCGWINSZ on unix) if (data->out_isatty && !uv_tty_get_winsize(&data->output_handle.tty, &width, &height)) { goto end; } - // 3 - use $LINES/$COLUMNS if available + // 2 - use $LINES/$COLUMNS if available const char *val; int advance; if ((val = os_getenv("LINES")) @@ -1533,7 +1522,7 @@ static void tui_guess_size(UI *ui) goto end; } - // 4 - read from terminfo if available + // 3 - read from terminfo if available height = unibi_get_num(data->ut, unibi_lines); width = unibi_get_num(data->ut, unibi_columns); diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 1a11f6fc60..20bd4d8ef7 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -86,6 +86,24 @@ describe('TUI', function() assert_alive() end) + it('resize at startup', function() + -- Issues: #17285 #15044 #11330 + screen:try_resize(50, 10) + feed_command([[call termopen([v:progpath, '--clean', '--cmd', 'let start = reltime() | while v:true | if reltimefloat(reltime(start)) > 2 | break | endif | endwhile']) | sleep 500m | vs new]]) + screen:expect([[ + {1: } {1:│} | + {4:~ }{1:│}{4:~ }| + {4:~ }{1:│}{4:~ }| + {4:~ }{1:│}{4:~ }| + {4:~ }{1:│}{4:~ }| + {4:~ }{1:│}{5:[No Name] 0,0-1 All}| + {4:~ }{1:│} | + {5:new }{MATCH:<.*[/\]nvim }| + | + {3:-- TERMINAL --} | + ]]) + end) + it('accepts resize while pager is active', function() child_session:request("nvim_command", [[ set more diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index 80dba70b33..6bd1a5d3f1 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -380,7 +380,7 @@ function Screen:expect(expected, attr_ids, ...) for i, row in ipairs(expected_rows) do msg_expected_rows[i] = row local m = (row ~= actual_rows[i] and row:match('{MATCH:(.*)}') or nil) - if row ~= actual_rows[i] and (not m or not actual_rows[i]:match(m)) then + if row ~= actual_rows[i] and (not m or not (actual_rows[i] and actual_rows[i]:match(m))) then msg_expected_rows[i] = '*' .. msg_expected_rows[i] if i <= #actual_rows then actual_rows[i] = '*' .. actual_rows[i] From d9521c71d17b6e1ee2fd8eae1547e217380480ca Mon Sep 17 00:00:00 2001 From: Enan Ajmain <3nan.ajmain@gmail.com> Date: Mon, 18 Jul 2022 06:00:08 +0600 Subject: [PATCH 2/2] fix(windows):exepath, stdpath return wrong slashes #19111 exepath and stdpath should respect shellslash and return path with proper file separator. Closes #13787 --- src/nvim/eval/funcs.c | 6 ++++++ src/nvim/os/stdpaths.c | 4 ++++ test/functional/core/startup_spec.lua | 11 +++++++---- test/functional/vimscript/executable_spec.lua | 15 +++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 61eee29627..c9ba98dfbc 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -2056,6 +2056,12 @@ static void f_exepath(typval_T *argvars, typval_T *rettv, FunPtr fptr) (void)os_can_exe(tv_get_string(&argvars[0]), &path, true); +#ifdef BACKSLASH_IN_FILENAME + if (path != NULL) { + slash_adjust((char_u *)path); + } +#endif + rettv->v_type = VAR_STRING; rettv->vval.v_string = (char_u *)path; } diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 5b824d23f4..e0115e5f1a 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -104,6 +104,10 @@ char *get_xdg_home(const XDGVarType idx) #else dir = concat_fnames_realloc(dir, "nvim", true); #endif + +#ifdef BACKSLASH_IN_FILENAME + slash_adjust((char_u *)dir); +#endif } return dir; } diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index 20ea3621f0..acb492e0ee 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -23,6 +23,7 @@ local iswin = helpers.iswin local startswith = helpers.startswith local write_file = helpers.write_file local meths = helpers.meths +local alter_slashes = helpers.alter_slashes describe('startup', function() before_each(function() @@ -521,10 +522,12 @@ describe('sysinit', function() end) describe('clean', function() - clear() - ok(string.find(meths.get_option('runtimepath'), funcs.stdpath('config'), 1, true) ~= nil) - clear('--clean') - ok(string.find(meths.get_option('runtimepath'), funcs.stdpath('config'), 1, true) == nil) + it('--clean', function() + clear() + ok(string.find(alter_slashes(meths.get_option('runtimepath')), funcs.stdpath('config'), 1, true) ~= nil) + clear('--clean') + ok(string.find(alter_slashes(meths.get_option('runtimepath')), funcs.stdpath('config'), 1, true) == nil) + end) end) describe('user config init', function() diff --git a/test/functional/vimscript/executable_spec.lua b/test/functional/vimscript/executable_spec.lua index 048a65188d..b4162b2336 100644 --- a/test/functional/vimscript/executable_spec.lua +++ b/test/functional/vimscript/executable_spec.lua @@ -17,6 +17,21 @@ describe('executable()', function() eq(1, call('executable', 'false')) end) + if iswin() then + it('exepath respects shellslash', function() + command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")') + eq([[test\functional\fixtures\bin\null.CMD]], call('fnamemodify', call('exepath', 'null'), ':.')) + command('set shellslash') + eq('test/functional/fixtures/bin/null.CMD', call('fnamemodify', call('exepath', 'null'), ':.')) + end) + + it('stdpath respects shellslash', function() + eq([[build\Xtest_xdg\share\nvim-data]], call('fnamemodify', call('stdpath', 'data'), ':.')) + command('set shellslash') + eq('build/Xtest_xdg/share/nvim-data', call('fnamemodify', call('stdpath', 'data'), ':.')) + end) + end + it('fails for invalid values', function() for _, input in ipairs({'v:null', 'v:true', 'v:false', '{}', '[]'}) do eq('Vim(call):E928: String required', exc_exec('call executable('..input..')'))