1// This is an open source non-commercial project. Dear PVS-Studio, please check
2// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
3
4#include <stdbool.h>
5#include <stdint.h>
6#include <stdlib.h>
7
8#include "nvim/api/tabpage.h"
9#include "nvim/api/vim.h"
10#include "nvim/api/private/defs.h"
11#include "nvim/api/private/helpers.h"
12#include "nvim/memory.h"
13#include "nvim/window.h"
14
15/// Gets the windows in a tabpage
16///
17/// @param tabpage Tabpage handle, or 0 for current tabpage
18/// @param[out] err Error details, if any
19/// @return List of windows in `tabpage`
20ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err)
21 FUNC_API_SINCE(1)
22{
23 Array rv = ARRAY_DICT_INIT;
24 tabpage_T *tab = find_tab_by_handle(tabpage, err);
25
26 if (!tab || !valid_tabpage(tab)) {
27 return rv;
28 }
29
30 FOR_ALL_WINDOWS_IN_TAB(wp, tab) {
31 rv.size++;
32 }
33
34 rv.items = xmalloc(sizeof(Object) * rv.size);
35 size_t i = 0;
36
37 FOR_ALL_WINDOWS_IN_TAB(wp, tab) {
38 rv.items[i++] = WINDOW_OBJ(wp->handle);
39 }
40
41 return rv;
42}
43
44/// Gets a tab-scoped (t:) variable
45///
46/// @param tabpage Tabpage handle, or 0 for current tabpage
47/// @param name Variable name
48/// @param[out] err Error details, if any
49/// @return Variable value
50Object nvim_tabpage_get_var(Tabpage tabpage, String name, Error *err)
51 FUNC_API_SINCE(1)
52{
53 tabpage_T *tab = find_tab_by_handle(tabpage, err);
54
55 if (!tab) {
56 return (Object) OBJECT_INIT;
57 }
58
59 return dict_get_value(tab->tp_vars, name, err);
60}
61
62/// Sets a tab-scoped (t:) variable
63///
64/// @param tabpage Tabpage handle, or 0 for current tabpage
65/// @param name Variable name
66/// @param value Variable value
67/// @param[out] err Error details, if any
68void nvim_tabpage_set_var(Tabpage tabpage,
69 String name,
70 Object value,
71 Error *err)
72 FUNC_API_SINCE(1)
73{
74 tabpage_T *tab = find_tab_by_handle(tabpage, err);
75
76 if (!tab) {
77 return;
78 }
79
80 dict_set_var(tab->tp_vars, name, value, false, false, err);
81}
82
83/// Removes a tab-scoped (t:) variable
84///
85/// @param tabpage Tabpage handle, or 0 for current tabpage
86/// @param name Variable name
87/// @param[out] err Error details, if any
88void nvim_tabpage_del_var(Tabpage tabpage, String name, Error *err)
89 FUNC_API_SINCE(1)
90{
91 tabpage_T *tab = find_tab_by_handle(tabpage, err);
92
93 if (!tab) {
94 return;
95 }
96
97 dict_set_var(tab->tp_vars, name, NIL, true, false, err);
98}
99
100/// Sets a tab-scoped (t:) variable
101///
102/// @deprecated
103///
104/// @param tabpage Tabpage handle, or 0 for current tabpage
105/// @param name Variable name
106/// @param value Variable value
107/// @param[out] err Error details, if any
108/// @return Old value or nil if there was no previous value.
109///
110/// @warning It may return nil if there was no previous value
111/// or if previous value was `v:null`.
112Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err)
113{
114 tabpage_T *tab = find_tab_by_handle(tabpage, err);
115
116 if (!tab) {
117 return (Object) OBJECT_INIT;
118 }
119
120 return dict_set_var(tab->tp_vars, name, value, false, true, err);
121}
122
123/// Removes a tab-scoped (t:) variable
124///
125/// @deprecated
126///
127/// @param tabpage Tabpage handle, or 0 for current tabpage
128/// @param name Variable name
129/// @param[out] err Error details, if any
130/// @return Old value
131Object tabpage_del_var(Tabpage tabpage, String name, Error *err)
132{
133 tabpage_T *tab = find_tab_by_handle(tabpage, err);
134
135 if (!tab) {
136 return (Object) OBJECT_INIT;
137 }
138
139 return dict_set_var(tab->tp_vars, name, NIL, true, true, err);
140}
141
142/// Gets the current window in a tabpage
143///
144/// @param tabpage Tabpage handle, or 0 for current tabpage
145/// @param[out] err Error details, if any
146/// @return Window handle
147Window nvim_tabpage_get_win(Tabpage tabpage, Error *err)
148 FUNC_API_SINCE(1)
149{
150 Window rv = 0;
151 tabpage_T *tab = find_tab_by_handle(tabpage, err);
152
153 if (!tab || !valid_tabpage(tab)) {
154 return rv;
155 }
156
157 if (tab == curtab) {
158 return nvim_get_current_win();
159 } else {
160 FOR_ALL_WINDOWS_IN_TAB(wp, tab) {
161 if (wp == tab->tp_curwin) {
162 return wp->handle;
163 }
164 }
165 // There should always be a current window for a tabpage
166 abort();
167 }
168}
169
170/// Gets the tabpage number
171///
172/// @param tabpage Tabpage handle, or 0 for current tabpage
173/// @param[out] err Error details, if any
174/// @return Tabpage number
175Integer nvim_tabpage_get_number(Tabpage tabpage, Error *err)
176 FUNC_API_SINCE(1)
177{
178 Integer rv = 0;
179 tabpage_T *tab = find_tab_by_handle(tabpage, err);
180
181 if (!tab) {
182 return rv;
183 }
184
185 return tabpage_index(tab);
186}
187
188/// Checks if a tabpage is valid
189///
190/// @param tabpage Tabpage handle, or 0 for current tabpage
191/// @return true if the tabpage is valid, false otherwise
192Boolean nvim_tabpage_is_valid(Tabpage tabpage)
193 FUNC_API_SINCE(1)
194{
195 Error stub = ERROR_INIT;
196 Boolean ret = find_tab_by_handle(tabpage, &stub) != NULL;
197 api_clear_error(&stub);
198 return ret;
199}
200
201