aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Hopkins <willothyh@gmail.com>2024-01-28 23:18:33 -0800
committerGitHub <noreply@github.com>2024-01-29 15:18:33 +0800
commitca9f6f56949d66f0f6467fa64b215f861fe0a3bf (patch)
treec65f6084044279f65617c6e7345304edc015b767
parent5e5b004da44c7075ed1e20ae9d05ab09c6f2ac58 (diff)
downloadrneovim-ca9f6f56949d66f0f6467fa64b215f861fe0a3bf.tar.gz
rneovim-ca9f6f56949d66f0f6467fa64b215f861fe0a3bf.tar.bz2
rneovim-ca9f6f56949d66f0f6467fa64b215f861fe0a3bf.zip
feat(api): add nvim_tabpage_set_win (#27222)
Allows setting the current window of a non-current tabpage without switching tabpages.
-rw-r--r--runtime/doc/api.txt7
-rw-r--r--runtime/doc/news.txt2
-rw-r--r--runtime/lua/vim/_meta/api.lua6
-rw-r--r--src/nvim/api/tabpage.c31
-rw-r--r--src/nvim/window.c2
-rw-r--r--test/functional/api/tabpage_spec.lua56
6 files changed, 103 insertions, 1 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index 90c9d0ccbb..1831b78e9e 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -3336,6 +3336,13 @@ nvim_tabpage_set_var({tabpage}, {name}, {value})
• {name} Variable name
• {value} Variable value
+nvim_tabpage_set_win({tabpage}, {win}) *nvim_tabpage_set_win()*
+ Sets the current window in a tabpage
+
+ Parameters: ~
+ • {tabpage} Tabpage handle, or 0 for current tabpage
+ • {win} Window handle, must already belong to {tabpage}
+
==============================================================================
Autocmd Functions *api-autocmd*
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index 40717f8ecf..3051b81189 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -304,6 +304,8 @@ The following new APIs and features were added.
highlight attribute. The TUI will display URLs using the OSC 8 control
sequence, enabling clickable text in supporting terminals.
+• Added |nvim_tabpage_set_win()| to set the current window of a tabpage.
+
==============================================================================
CHANGED FEATURES *news-changed*
diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua
index f9fa364158..bedc218626 100644
--- a/runtime/lua/vim/_meta/api.lua
+++ b/runtime/lua/vim/_meta/api.lua
@@ -1952,6 +1952,12 @@ function vim.api.nvim_tabpage_list_wins(tabpage) end
--- @param value any Variable value
function vim.api.nvim_tabpage_set_var(tabpage, name, value) end
+--- Sets the current window in a tabpage
+---
+--- @param tabpage integer Tabpage handle, or 0 for current tabpage
+--- @param win integer Window handle, must already belong to {tabpage}
+function vim.api.nvim_tabpage_set_win(tabpage, win) end
+
--- Calls a function with window as temporary current window.
---
--- @param window integer Window handle, or 0 for current window
diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c
index 303f2ca817..fadc03b3e5 100644
--- a/src/nvim/api/tabpage.c
+++ b/src/nvim/api/tabpage.c
@@ -122,6 +122,37 @@ Window nvim_tabpage_get_win(Tabpage tabpage, Error *err)
abort();
}
+/// Sets the current window in a tabpage
+///
+/// @param tabpage Tabpage handle, or 0 for current tabpage
+/// @param win Window handle, must already belong to {tabpage}
+/// @param[out] err Error details, if any
+void nvim_tabpage_set_win(Tabpage tabpage, Window win, Error *err)
+ FUNC_API_SINCE(12)
+{
+ tabpage_T *tp = find_tab_by_handle(tabpage, err);
+ if (!tp) {
+ return;
+ }
+
+ win_T *wp = find_window_by_handle(win, err);
+ if (!wp) {
+ return;
+ }
+
+ if (!tabpage_win_valid(tp, wp)) {
+ api_set_error(err, kErrorTypeException, "Window does not belong to tabpage %d", tp->handle);
+ return;
+ }
+
+ if (tp == curtab) {
+ win_enter(wp, true);
+ } else if (tp->tp_curwin != wp) {
+ tp->tp_prevwin = tp->tp_curwin;
+ tp->tp_curwin = wp;
+ }
+}
+
/// Gets the tabpage number
///
/// @param tabpage Tabpage handle, or 0 for current tabpage
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 65db25bc13..66169bcb74 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -1557,7 +1557,7 @@ bool win_valid(const win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
/// Check if "win" is a pointer to an existing window in tabpage "tp".
///
/// @param win window to check
-static bool tabpage_win_valid(const tabpage_T *tp, const win_T *win)
+bool tabpage_win_valid(const tabpage_T *tp, const win_T *win)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (win == NULL) {
diff --git a/test/functional/api/tabpage_spec.lua b/test/functional/api/tabpage_spec.lua
index f801c55de9..36955c4ace 100644
--- a/test/functional/api/tabpage_spec.lua
+++ b/test/functional/api/tabpage_spec.lua
@@ -32,6 +32,62 @@ describe('api/tabpage', function()
end)
end)
+ describe('set_win', function()
+ it('works', function()
+ command('tabnew')
+ command('vsplit')
+ local tab1, tab2 = unpack(api.nvim_list_tabpages())
+ local win1, win2, win3 = unpack(api.nvim_list_wins())
+ eq({ win1 }, api.nvim_tabpage_list_wins(tab1))
+ eq({ win2, win3 }, api.nvim_tabpage_list_wins(tab2))
+ eq(win2, api.nvim_tabpage_get_win(tab2))
+ api.nvim_tabpage_set_win(tab2, win3)
+ eq(win3, api.nvim_tabpage_get_win(tab2))
+ end)
+
+ it('works in non-current tabpages', function()
+ command('tabnew')
+ command('vsplit')
+ local tab1, tab2 = unpack(api.nvim_list_tabpages())
+ local win1, win2, win3 = unpack(api.nvim_list_wins())
+ eq({ win1 }, api.nvim_tabpage_list_wins(tab1))
+ eq({ win2, win3 }, api.nvim_tabpage_list_wins(tab2))
+ eq(win2, api.nvim_tabpage_get_win(tab2))
+ eq(win2, api.nvim_get_current_win())
+
+ command('tabprev')
+
+ eq(tab1, api.nvim_get_current_tabpage())
+
+ eq(win2, api.nvim_tabpage_get_win(tab2))
+ api.nvim_tabpage_set_win(tab2, win3)
+ eq(win3, api.nvim_tabpage_get_win(tab2))
+
+ command('tabnext')
+ eq(win3, api.nvim_get_current_win())
+ end)
+
+ it('throws an error when the window does not belong to the tabpage', function()
+ command('tabnew')
+ command('vsplit')
+ local tab1, tab2 = unpack(api.nvim_list_tabpages())
+ local win1, win2, win3 = unpack(api.nvim_list_wins())
+ eq({ win1 }, api.nvim_tabpage_list_wins(tab1))
+ eq({ win2, win3 }, api.nvim_tabpage_list_wins(tab2))
+ eq(win2, api.nvim_get_current_win())
+
+ eq(
+ string.format('Window does not belong to tabpage %d', tab2),
+ pcall_err(api.nvim_tabpage_set_win, tab2, win1)
+ )
+
+ eq(
+ string.format('Window does not belong to tabpage %d', tab1),
+ pcall_err(api.nvim_tabpage_set_win, tab1, win3)
+ )
+ end)
+ end)
+
describe('{get,set,del}_var', function()
it('works', function()
api.nvim_tabpage_set_var(0, 'lua', { 1, 2, { ['3'] = 1 } })