From 4ec8fd43bfdf1924ee03e07afc8a46dfdd3c9b12 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 15 Apr 2024 17:55:57 +0800 Subject: [PATCH] fix(api): make width/height for split by nvim_open_win work (#28341) --- src/nvim/api/win_config.c | 13 +- test/functional/api/window_spec.lua | 216 ++++++++++++++++++---------- 2 files changed, 150 insertions(+), 79 deletions(-) diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 11b6b17516..3bc9cd816f 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -224,7 +224,7 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dict(win_config) *config, Err } WinConfig fconfig = WIN_CONFIG_INIT; - if (!parse_float_config(NULL, config, &fconfig, false, err)) { + if (!parse_win_config(NULL, config, &fconfig, false, err)) { return 0; } @@ -263,8 +263,9 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dict(win_config) *config, Err int flags = win_split_flags(fconfig.split, parent == NULL) | WSP_NOENTER; TRY_WRAP(err, { + int size = (flags & WSP_VERT) ? fconfig.width : fconfig.height; if (parent == NULL || parent == curwin) { - wp = win_split_ins(0, flags, NULL, 0, NULL); + wp = win_split_ins(size, flags, NULL, 0, NULL); } else { tp = win_find_tabpage(parent); switchwin_T switchwin; @@ -272,7 +273,7 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dict(win_config) *config, Err const int result = switch_win(&switchwin, parent, tp, true); assert(result == OK); (void)result; - wp = win_split_ins(0, flags, NULL, 0, NULL); + wp = win_split_ins(size, flags, NULL, 0, NULL); restore_win(&switchwin, true); } }); @@ -405,7 +406,7 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err) && !(HAS_KEY_X(config, external) ? config->external : fconfig.external) && (has_split || has_vertical || was_split); - if (!parse_float_config(win, config, &fconfig, !was_split || to_split, err)) { + if (!parse_win_config(win, config, &fconfig, !was_split || to_split, err)) { return; } if (was_split && !to_split) { @@ -1043,8 +1044,8 @@ static void generate_api_error(win_T *wp, const char *attribute, Error *err) } } -static bool parse_float_config(win_T *wp, Dict(win_config) *config, WinConfig *fconfig, bool reconf, - Error *err) +static bool parse_win_config(win_T *wp, Dict(win_config) *config, WinConfig *fconfig, bool reconf, + Error *err) { #define HAS_KEY_X(d, key) HAS_KEY(d, win_config, key) bool has_relative = false, relative_is_win = false, is_split = false; diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index d9d3772df2..4f0da7c0f4 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -1227,81 +1227,151 @@ describe('API/win', function() eq(wins_before, api.nvim_list_wins()) end) - it('creates a split window', function() - local win = api.nvim_open_win(0, true, { - vertical = false, - }) - eq('', api.nvim_win_get_config(win).relative) - end) - - it('creates split windows in the correct direction', function() - local initial_win = api.nvim_get_current_win() - local win = api.nvim_open_win(0, true, { - vertical = true, - }) - eq('', api.nvim_win_get_config(win).relative) - - local layout = fn.winlayout() - - eq({ - 'row', - { - { 'leaf', win }, - { 'leaf', initial_win }, - }, - }, layout) - end) - - it("respects the 'split' option", function() - local initial_win = api.nvim_get_current_win() - local win = api.nvim_open_win(0, true, { - split = 'below', - }) - eq('', api.nvim_win_get_config(win).relative) - - local layout = fn.winlayout() - - eq({ - 'col', - { - { 'leaf', initial_win }, - { 'leaf', win }, - }, - }, layout) - end) - - it( - "doesn't change tp_curwin when splitting window in non-current tab with enter=false", - function() - local tab1 = api.nvim_get_current_tabpage() - local tab1_win = api.nvim_get_current_win() - - t.command('tabnew') - local tab2 = api.nvim_get_current_tabpage() - local tab2_win = api.nvim_get_current_win() - - eq({ tab1_win, tab2_win }, api.nvim_list_wins()) - eq({ tab1, tab2 }, api.nvim_list_tabpages()) - - api.nvim_set_current_tabpage(tab1) - eq(tab1_win, api.nvim_get_current_win()) - - local tab2_prevwin = fn.tabpagewinnr(tab2, '#') - - -- split in tab2 whine in tab2, with enter = false - local tab2_win2 = api.nvim_open_win(api.nvim_create_buf(false, true), false, { - win = tab2_win, - split = 'right', + describe('creates a split window above', function() + local function test_open_win_split_above(key, val) + local initial_win = api.nvim_get_current_win() + local win = api.nvim_open_win(0, true, { + [key] = val, + height = 10, }) - eq(tab1_win, api.nvim_get_current_win()) -- we should still be in the first tp - eq(tab1_win, api.nvim_tabpage_get_win(tab1)) - - eq(tab2_win, api.nvim_tabpage_get_win(tab2)) -- tab2's tp_curwin should not have changed - eq(tab2_prevwin, fn.tabpagewinnr(tab2, '#')) -- tab2's tp_prevwin should not have changed - eq({ tab1_win, tab2_win, tab2_win2 }, api.nvim_list_wins()) - eq({ tab2_win, tab2_win2 }, api.nvim_tabpage_list_wins(tab2)) + eq('', api.nvim_win_get_config(win).relative) + eq(10, api.nvim_win_get_height(win)) + local layout = fn.winlayout() + eq({ + 'col', + { + { 'leaf', win }, + { 'leaf', initial_win }, + }, + }, layout) end - ) + + it("with split = 'above'", function() + test_open_win_split_above('split', 'above') + end) + + it("with vertical = false and 'nosplitbelow'", function() + api.nvim_set_option_value('splitbelow', false, {}) + test_open_win_split_above('vertical', false) + end) + end) + + describe('creates a split window below', function() + local function test_open_win_split_below(key, val) + local initial_win = api.nvim_get_current_win() + local win = api.nvim_open_win(0, true, { + [key] = val, + height = 15, + }) + eq('', api.nvim_win_get_config(win).relative) + eq(15, api.nvim_win_get_height(win)) + local layout = fn.winlayout() + eq({ + 'col', + { + { 'leaf', initial_win }, + { 'leaf', win }, + }, + }, layout) + end + + it("with split = 'below'", function() + test_open_win_split_below('split', 'below') + end) + + it("with vertical = false and 'splitbelow'", function() + api.nvim_set_option_value('splitbelow', true, {}) + test_open_win_split_below('vertical', false) + end) + end) + + describe('creates a split window to the left', function() + local function test_open_win_split_left(key, val) + local initial_win = api.nvim_get_current_win() + local win = api.nvim_open_win(0, true, { + [key] = val, + width = 25, + }) + eq('', api.nvim_win_get_config(win).relative) + eq(25, api.nvim_win_get_width(win)) + local layout = fn.winlayout() + eq({ + 'row', + { + { 'leaf', win }, + { 'leaf', initial_win }, + }, + }, layout) + end + + it("with split = 'left'", function() + test_open_win_split_left('split', 'left') + end) + + it("with vertical = true and 'nosplitright'", function() + api.nvim_set_option_value('splitright', false, {}) + test_open_win_split_left('vertical', true) + end) + end) + + describe('creates a split window to the right', function() + local function test_open_win_split_right(key, val) + local initial_win = api.nvim_get_current_win() + local win = api.nvim_open_win(0, true, { + [key] = val, + width = 30, + }) + eq('', api.nvim_win_get_config(win).relative) + eq(30, api.nvim_win_get_width(win)) + local layout = fn.winlayout() + eq({ + 'row', + { + { 'leaf', initial_win }, + { 'leaf', win }, + }, + }, layout) + end + + it("with split = 'right'", function() + test_open_win_split_right('split', 'right') + end) + + it("with vertical = true and 'splitright'", function() + api.nvim_set_option_value('splitright', true, {}) + test_open_win_split_right('vertical', true) + end) + end) + + it("doesn't change tp_curwin when splitting window in another tab with enter=false", function() + local tab1 = api.nvim_get_current_tabpage() + local tab1_win = api.nvim_get_current_win() + + t.command('tabnew') + local tab2 = api.nvim_get_current_tabpage() + local tab2_win = api.nvim_get_current_win() + + eq({ tab1_win, tab2_win }, api.nvim_list_wins()) + eq({ tab1, tab2 }, api.nvim_list_tabpages()) + + api.nvim_set_current_tabpage(tab1) + eq(tab1_win, api.nvim_get_current_win()) + + local tab2_prevwin = fn.tabpagewinnr(tab2, '#') + + -- split in tab2 whine in tab2, with enter = false + local tab2_win2 = api.nvim_open_win(api.nvim_create_buf(false, true), false, { + win = tab2_win, + split = 'right', + }) + eq(tab1_win, api.nvim_get_current_win()) -- we should still be in the first tp + eq(tab1_win, api.nvim_tabpage_get_win(tab1)) + + eq(tab2_win, api.nvim_tabpage_get_win(tab2)) -- tab2's tp_curwin should not have changed + eq(tab2_prevwin, fn.tabpagewinnr(tab2, '#')) -- tab2's tp_prevwin should not have changed + eq({ tab1_win, tab2_win, tab2_win2 }, api.nvim_list_wins()) + eq({ tab2_win, tab2_win2 }, api.nvim_tabpage_list_wins(tab2)) + end) it('creates splits in the correct location', function() local first_win = api.nvim_get_current_win()