From 1999c4cdc11c530be272d192c5b435a95cb6ba3b Mon Sep 17 00:00:00 2001 From: fredizzimo Date: Sat, 26 Apr 2025 23:39:12 +0300 Subject: [PATCH] fix: screenchar()/screenstring() with multigrid #32494 Problem: - When multigrid is enabled, screenchar()/screenstring() functions return wrong results. See https://github.com/neovide/neovide/issues/2569 - `screenstring()` executed via RPC in child Nvim process, doesn't recognize floating windows. Solution: In ui_comp_get_grid_at_coord(), also iterate window grids. --- src/nvim/ui_compositor.c | 8 ++ test/functional/vimscript/screenchar_spec.lua | 77 +++++++++++-------- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index e18e2a711d..afe64c15ae 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -333,6 +333,14 @@ ScreenGrid *ui_comp_get_grid_at_coord(int row, int col) return grid; } } + + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + ScreenGrid *grid = &wp->w_grid_alloc; + if (row >= grid->comp_row && row < grid->comp_row + grid->rows + && col >= grid->comp_col && col < grid->comp_col + grid->cols) { + return grid; + } + } return &default_grid; } diff --git a/test/functional/vimscript/screenchar_spec.lua b/test/functional/vimscript/screenchar_spec.lua index b6137d7741..706e3221c0 100644 --- a/test/functional/vimscript/screenchar_spec.lua +++ b/test/functional/vimscript/screenchar_spec.lua @@ -1,5 +1,6 @@ local t = require('test.testutil') local n = require('test.functional.testnvim')() +local Screen = require('test.functional.ui.screen') local clear, eq, neq = n.clear, t.eq, t.neq local command, api, fn = n.command, n.api, n.fn @@ -30,42 +31,52 @@ local setup_floating_windows = function() end describe('screenchar() and family respect floating windows', function() - before_each(function() - clear() - -- These commands result into visible text `aabc`. - -- `aab` - from floating windows, `c` - from text in regular window. - api.nvim_buf_set_lines(0, 0, -1, true, { 'cccc' }) - setup_floating_windows() - end) + local function with_ext_multigrid(multigrid) + before_each(function() + clear() + Screen.new(40, 7, { ext_multigrid = multigrid }) + -- These commands result into visible text `aabc`. + -- `aab` - from floating windows, `c` - from text in regular window. + api.nvim_buf_set_lines(0, 0, -1, true, { 'cccc' }) + setup_floating_windows() + end) - it('screenattr()', function() - local attr_1 = fn.screenattr(1, 1) - local attr_2 = fn.screenattr(1, 2) - local attr_3 = fn.screenattr(1, 3) - local attr_4 = fn.screenattr(1, 4) - eq(attr_1, attr_2) - eq(attr_1, attr_3) - neq(attr_1, attr_4) - end) + it('screenattr()', function() + local attr_1 = fn.screenattr(1, 1) + local attr_2 = fn.screenattr(1, 2) + local attr_3 = fn.screenattr(1, 3) + local attr_4 = fn.screenattr(1, 4) + eq(attr_1, attr_2) + eq(attr_1, attr_3) + neq(attr_1, attr_4) + end) - it('screenchar()', function() - eq(97, fn.screenchar(1, 1)) - eq(97, fn.screenchar(1, 2)) - eq(98, fn.screenchar(1, 3)) - eq(99, fn.screenchar(1, 4)) - end) + it('screenchar()', function() + eq(97, fn.screenchar(1, 1)) + eq(97, fn.screenchar(1, 2)) + eq(98, fn.screenchar(1, 3)) + eq(99, fn.screenchar(1, 4)) + end) - it('screenchars()', function() - eq({ 97 }, fn.screenchars(1, 1)) - eq({ 97 }, fn.screenchars(1, 2)) - eq({ 98 }, fn.screenchars(1, 3)) - eq({ 99 }, fn.screenchars(1, 4)) - end) + it('screenchars()', function() + eq({ 97 }, fn.screenchars(1, 1)) + eq({ 97 }, fn.screenchars(1, 2)) + eq({ 98 }, fn.screenchars(1, 3)) + eq({ 99 }, fn.screenchars(1, 4)) + end) - it('screenstring()', function() - eq('a', fn.screenstring(1, 1)) - eq('a', fn.screenstring(1, 2)) - eq('b', fn.screenstring(1, 3)) - eq('c', fn.screenstring(1, 4)) + it('screenstring()', function() + eq('a', fn.screenstring(1, 1)) + eq('a', fn.screenstring(1, 2)) + eq('b', fn.screenstring(1, 3)) + eq('c', fn.screenstring(1, 4)) + end) + end + + describe('with ext_multigrid', function() + with_ext_multigrid(true) + end) + describe('without ext_multigrid', function() + with_ext_multigrid(false) end) end)