xref: /vim-8.2.3635/src/evalwindow.c (revision cdf5fdb2)
1261f346fSBram Moolenaar /* vi:set ts=8 sts=4 sw=4 noet:
2261f346fSBram Moolenaar  *
3261f346fSBram Moolenaar  * VIM - Vi IMproved	by Bram Moolenaar
4261f346fSBram Moolenaar  *
5261f346fSBram Moolenaar  * Do ":help uganda"  in Vim to read copying and usage conditions.
6261f346fSBram Moolenaar  * Do ":help credits" in Vim to see a list of people who contributed.
7261f346fSBram Moolenaar  * See README.txt for an overview of the Vim source code.
8261f346fSBram Moolenaar  */
9261f346fSBram Moolenaar 
10261f346fSBram Moolenaar /*
11261f346fSBram Moolenaar  * evalwindow.c: Window related builtin functions
12261f346fSBram Moolenaar  */
13261f346fSBram Moolenaar 
14261f346fSBram Moolenaar #include "vim.h"
15261f346fSBram Moolenaar 
16261f346fSBram Moolenaar #if defined(FEAT_EVAL) || defined(PROTO)
17261f346fSBram Moolenaar 
18261f346fSBram Moolenaar     static int
win_getid(typval_T * argvars)19261f346fSBram Moolenaar win_getid(typval_T *argvars)
20261f346fSBram Moolenaar {
21261f346fSBram Moolenaar     int	    winnr;
22261f346fSBram Moolenaar     win_T   *wp;
23261f346fSBram Moolenaar 
24261f346fSBram Moolenaar     if (argvars[0].v_type == VAR_UNKNOWN)
25261f346fSBram Moolenaar 	return curwin->w_id;
26261f346fSBram Moolenaar     winnr = tv_get_number(&argvars[0]);
27261f346fSBram Moolenaar     if (winnr > 0)
28261f346fSBram Moolenaar     {
29261f346fSBram Moolenaar 	if (argvars[1].v_type == VAR_UNKNOWN)
30261f346fSBram Moolenaar 	    wp = firstwin;
31261f346fSBram Moolenaar 	else
32261f346fSBram Moolenaar 	{
33261f346fSBram Moolenaar 	    tabpage_T	*tp;
34261f346fSBram Moolenaar 	    int		tabnr = tv_get_number(&argvars[1]);
35261f346fSBram Moolenaar 
36261f346fSBram Moolenaar 	    FOR_ALL_TABPAGES(tp)
37261f346fSBram Moolenaar 		if (--tabnr == 0)
38261f346fSBram Moolenaar 		    break;
39261f346fSBram Moolenaar 	    if (tp == NULL)
40261f346fSBram Moolenaar 		return -1;
41261f346fSBram Moolenaar 	    if (tp == curtab)
42261f346fSBram Moolenaar 		wp = firstwin;
43261f346fSBram Moolenaar 	    else
44261f346fSBram Moolenaar 		wp = tp->tp_firstwin;
45261f346fSBram Moolenaar 	}
46261f346fSBram Moolenaar 	for ( ; wp != NULL; wp = wp->w_next)
47261f346fSBram Moolenaar 	    if (--winnr == 0)
48261f346fSBram Moolenaar 		return wp->w_id;
49261f346fSBram Moolenaar     }
50261f346fSBram Moolenaar     return 0;
51261f346fSBram Moolenaar }
52261f346fSBram Moolenaar 
53261f346fSBram Moolenaar     static void
win_id2tabwin(typval_T * argvars,list_T * list)54261f346fSBram Moolenaar win_id2tabwin(typval_T *argvars, list_T *list)
55261f346fSBram Moolenaar {
56261f346fSBram Moolenaar     win_T	*wp;
57261f346fSBram Moolenaar     tabpage_T   *tp;
58261f346fSBram Moolenaar     int		winnr = 1;
59261f346fSBram Moolenaar     int		tabnr = 1;
60261f346fSBram Moolenaar     int		id = tv_get_number(&argvars[0]);
61261f346fSBram Moolenaar 
62261f346fSBram Moolenaar     FOR_ALL_TABPAGES(tp)
63261f346fSBram Moolenaar     {
64261f346fSBram Moolenaar 	FOR_ALL_WINDOWS_IN_TAB(tp, wp)
65261f346fSBram Moolenaar 	{
66261f346fSBram Moolenaar 	    if (wp->w_id == id)
67261f346fSBram Moolenaar 	    {
68261f346fSBram Moolenaar 		list_append_number(list, tabnr);
69261f346fSBram Moolenaar 		list_append_number(list, winnr);
70261f346fSBram Moolenaar 		return;
71261f346fSBram Moolenaar 	    }
72261f346fSBram Moolenaar 	    ++winnr;
73261f346fSBram Moolenaar 	}
74261f346fSBram Moolenaar 	++tabnr;
75261f346fSBram Moolenaar 	winnr = 1;
76261f346fSBram Moolenaar     }
77261f346fSBram Moolenaar     list_append_number(list, 0);
78261f346fSBram Moolenaar     list_append_number(list, 0);
79261f346fSBram Moolenaar }
80261f346fSBram Moolenaar 
81261f346fSBram Moolenaar /*
82261f346fSBram Moolenaar  * Return the window pointer of window "id".
83261f346fSBram Moolenaar  */
84261f346fSBram Moolenaar     win_T *
win_id2wp(int id)85261f346fSBram Moolenaar win_id2wp(int id)
86261f346fSBram Moolenaar {
87261f346fSBram Moolenaar     return win_id2wp_tp(id, NULL);
88261f346fSBram Moolenaar }
89261f346fSBram Moolenaar 
90261f346fSBram Moolenaar /*
91261f346fSBram Moolenaar  * Return the window and tab pointer of window "id".
92261f346fSBram Moolenaar  */
93261f346fSBram Moolenaar     win_T *
win_id2wp_tp(int id,tabpage_T ** tpp)94261f346fSBram Moolenaar win_id2wp_tp(int id, tabpage_T **tpp)
95261f346fSBram Moolenaar {
96261f346fSBram Moolenaar     win_T	*wp;
97261f346fSBram Moolenaar     tabpage_T   *tp;
98261f346fSBram Moolenaar 
99261f346fSBram Moolenaar     FOR_ALL_TAB_WINDOWS(tp, wp)
100261f346fSBram Moolenaar 	if (wp->w_id == id)
101261f346fSBram Moolenaar 	{
102261f346fSBram Moolenaar 	    if (tpp != NULL)
103261f346fSBram Moolenaar 		*tpp = tp;
104261f346fSBram Moolenaar 	    return wp;
105261f346fSBram Moolenaar 	}
10605ad5ff0SBram Moolenaar #ifdef FEAT_PROP_POPUP
107261f346fSBram Moolenaar     // popup windows are in separate lists
108261f346fSBram Moolenaar      FOR_ALL_TABPAGES(tp)
109aeea7215SBram Moolenaar 	 FOR_ALL_POPUPWINS_IN_TAB(tp, wp)
110261f346fSBram Moolenaar 	     if (wp->w_id == id)
111261f346fSBram Moolenaar 	     {
112261f346fSBram Moolenaar 		 if (tpp != NULL)
113261f346fSBram Moolenaar 		     *tpp = tp;
114261f346fSBram Moolenaar 		 return wp;
115261f346fSBram Moolenaar 	     }
116aeea7215SBram Moolenaar     FOR_ALL_POPUPWINS(wp)
117261f346fSBram Moolenaar 	if (wp->w_id == id)
118261f346fSBram Moolenaar 	{
119261f346fSBram Moolenaar 	    if (tpp != NULL)
1201f42f5a6SBram Moolenaar 		*tpp = curtab;  // any tabpage would do
121261f346fSBram Moolenaar 	    return wp;
122261f346fSBram Moolenaar 	}
123261f346fSBram Moolenaar #endif
124261f346fSBram Moolenaar 
125261f346fSBram Moolenaar     return NULL;
126261f346fSBram Moolenaar }
127261f346fSBram Moolenaar 
128261f346fSBram Moolenaar     static int
win_id2win(typval_T * argvars)129261f346fSBram Moolenaar win_id2win(typval_T *argvars)
130261f346fSBram Moolenaar {
131261f346fSBram Moolenaar     win_T   *wp;
132261f346fSBram Moolenaar     int	    nr = 1;
133261f346fSBram Moolenaar     int	    id = tv_get_number(&argvars[0]);
134261f346fSBram Moolenaar 
135261f346fSBram Moolenaar     FOR_ALL_WINDOWS(wp)
136261f346fSBram Moolenaar     {
137261f346fSBram Moolenaar 	if (wp->w_id == id)
138261f346fSBram Moolenaar 	    return nr;
139261f346fSBram Moolenaar 	++nr;
140261f346fSBram Moolenaar     }
141261f346fSBram Moolenaar     return 0;
142261f346fSBram Moolenaar }
143261f346fSBram Moolenaar 
144261f346fSBram Moolenaar     void
win_findbuf(typval_T * argvars,list_T * list)145261f346fSBram Moolenaar win_findbuf(typval_T *argvars, list_T *list)
146261f346fSBram Moolenaar {
147261f346fSBram Moolenaar     win_T	*wp;
148261f346fSBram Moolenaar     tabpage_T   *tp;
149261f346fSBram Moolenaar     int		bufnr = tv_get_number(&argvars[0]);
150261f346fSBram Moolenaar 
151261f346fSBram Moolenaar     FOR_ALL_TAB_WINDOWS(tp, wp)
152261f346fSBram Moolenaar 	    if (wp->w_buffer->b_fnum == bufnr)
153261f346fSBram Moolenaar 		list_append_number(list, wp->w_id);
154261f346fSBram Moolenaar }
155261f346fSBram Moolenaar 
156261f346fSBram Moolenaar /*
157261f346fSBram Moolenaar  * Find window specified by "vp" in tabpage "tp".
158261f346fSBram Moolenaar  */
159261f346fSBram Moolenaar     win_T *
find_win_by_nr(typval_T * vp,tabpage_T * tp)160261f346fSBram Moolenaar find_win_by_nr(
161261f346fSBram Moolenaar     typval_T	*vp,
162261f346fSBram Moolenaar     tabpage_T	*tp)	// NULL for current tab page
163261f346fSBram Moolenaar {
164261f346fSBram Moolenaar     win_T	*wp;
165261f346fSBram Moolenaar     int		nr = (int)tv_get_number_chk(vp, NULL);
166261f346fSBram Moolenaar 
167261f346fSBram Moolenaar     if (nr < 0)
168261f346fSBram Moolenaar 	return NULL;
169261f346fSBram Moolenaar     if (nr == 0)
170261f346fSBram Moolenaar 	return curwin;
171261f346fSBram Moolenaar 
172261f346fSBram Moolenaar     FOR_ALL_WINDOWS_IN_TAB(tp, wp)
173261f346fSBram Moolenaar     {
174261f346fSBram Moolenaar 	if (nr >= LOWEST_WIN_ID)
175261f346fSBram Moolenaar 	{
176261f346fSBram Moolenaar 	    if (wp->w_id == nr)
177261f346fSBram Moolenaar 		return wp;
178261f346fSBram Moolenaar 	}
179261f346fSBram Moolenaar 	else if (--nr <= 0)
180261f346fSBram Moolenaar 	    break;
181261f346fSBram Moolenaar     }
182261f346fSBram Moolenaar     if (nr >= LOWEST_WIN_ID)
183261f346fSBram Moolenaar     {
18405ad5ff0SBram Moolenaar #ifdef FEAT_PROP_POPUP
185261f346fSBram Moolenaar 	// check tab-local popup windows
186ee93b737SBram Moolenaar 	for (wp = (tp == NULL ? curtab : tp)->tp_first_popupwin;
187ee93b737SBram Moolenaar 						   wp != NULL; wp = wp->w_next)
188261f346fSBram Moolenaar 	    if (wp->w_id == nr)
189261f346fSBram Moolenaar 		return wp;
190261f346fSBram Moolenaar 	// check global popup windows
191aeea7215SBram Moolenaar 	FOR_ALL_POPUPWINS(wp)
192261f346fSBram Moolenaar 	    if (wp->w_id == nr)
193261f346fSBram Moolenaar 		return wp;
194261f346fSBram Moolenaar #endif
195261f346fSBram Moolenaar 	return NULL;
196261f346fSBram Moolenaar     }
197261f346fSBram Moolenaar     return wp;
198261f346fSBram Moolenaar }
199261f346fSBram Moolenaar 
200261f346fSBram Moolenaar /*
201261f346fSBram Moolenaar  * Find a window: When using a Window ID in any tab page, when using a number
202261f346fSBram Moolenaar  * in the current tab page.
20305ad5ff0SBram Moolenaar  * Returns NULL when not found.
204261f346fSBram Moolenaar  */
205261f346fSBram Moolenaar     win_T *
find_win_by_nr_or_id(typval_T * vp)206261f346fSBram Moolenaar find_win_by_nr_or_id(typval_T *vp)
207261f346fSBram Moolenaar {
208261f346fSBram Moolenaar     int	nr = (int)tv_get_number_chk(vp, NULL);
209261f346fSBram Moolenaar 
210261f346fSBram Moolenaar     if (nr >= LOWEST_WIN_ID)
211261f346fSBram Moolenaar 	return win_id2wp(tv_get_number(vp));
212261f346fSBram Moolenaar     return find_win_by_nr(vp, NULL);
213261f346fSBram Moolenaar }
214261f346fSBram Moolenaar 
215261f346fSBram Moolenaar /*
216261f346fSBram Moolenaar  * Find window specified by "wvp" in tabpage "tvp".
217261f346fSBram Moolenaar  * Returns the tab page in 'ptp'
218261f346fSBram Moolenaar  */
219261f346fSBram Moolenaar     win_T *
find_tabwin(typval_T * wvp,typval_T * tvp,tabpage_T ** ptp)220261f346fSBram Moolenaar find_tabwin(
221261f346fSBram Moolenaar     typval_T	*wvp,	// VAR_UNKNOWN for current window
222261f346fSBram Moolenaar     typval_T	*tvp,	// VAR_UNKNOWN for current tab page
223261f346fSBram Moolenaar     tabpage_T	**ptp)
224261f346fSBram Moolenaar {
225261f346fSBram Moolenaar     win_T	*wp = NULL;
226261f346fSBram Moolenaar     tabpage_T	*tp = NULL;
227261f346fSBram Moolenaar     long	n;
228261f346fSBram Moolenaar 
229261f346fSBram Moolenaar     if (wvp->v_type != VAR_UNKNOWN)
230261f346fSBram Moolenaar     {
231261f346fSBram Moolenaar 	if (tvp->v_type != VAR_UNKNOWN)
232261f346fSBram Moolenaar 	{
233261f346fSBram Moolenaar 	    n = (long)tv_get_number(tvp);
234261f346fSBram Moolenaar 	    if (n >= 0)
235261f346fSBram Moolenaar 		tp = find_tabpage(n);
236261f346fSBram Moolenaar 	}
237261f346fSBram Moolenaar 	else
238261f346fSBram Moolenaar 	    tp = curtab;
239261f346fSBram Moolenaar 
240261f346fSBram Moolenaar 	if (tp != NULL)
241261f346fSBram Moolenaar 	{
242261f346fSBram Moolenaar 	    wp = find_win_by_nr(wvp, tp);
243261f346fSBram Moolenaar 	    if (wp == NULL && wvp->v_type == VAR_NUMBER
244261f346fSBram Moolenaar 						&& wvp->vval.v_number != -1)
245261f346fSBram Moolenaar 		// A window with the specified number is not found
246261f346fSBram Moolenaar 		tp = NULL;
247261f346fSBram Moolenaar 	}
248261f346fSBram Moolenaar     }
249261f346fSBram Moolenaar     else
250261f346fSBram Moolenaar     {
251261f346fSBram Moolenaar 	wp = curwin;
252261f346fSBram Moolenaar 	tp = curtab;
253261f346fSBram Moolenaar     }
254261f346fSBram Moolenaar 
255261f346fSBram Moolenaar     if (ptp != NULL)
256261f346fSBram Moolenaar 	*ptp = tp;
257261f346fSBram Moolenaar 
258261f346fSBram Moolenaar     return wp;
259261f346fSBram Moolenaar }
260261f346fSBram Moolenaar 
261261f346fSBram Moolenaar /*
262261f346fSBram Moolenaar  * Get the layout of the given tab page for winlayout().
263261f346fSBram Moolenaar  */
264261f346fSBram Moolenaar     static void
get_framelayout(frame_T * fr,list_T * l,int outer)265261f346fSBram Moolenaar get_framelayout(frame_T *fr, list_T *l, int outer)
266261f346fSBram Moolenaar {
267261f346fSBram Moolenaar     frame_T	*child;
268261f346fSBram Moolenaar     list_T	*fr_list;
269261f346fSBram Moolenaar     list_T	*win_list;
270261f346fSBram Moolenaar 
271261f346fSBram Moolenaar     if (fr == NULL)
272261f346fSBram Moolenaar 	return;
273261f346fSBram Moolenaar 
274261f346fSBram Moolenaar     if (outer)
275261f346fSBram Moolenaar 	// outermost call from f_winlayout()
276261f346fSBram Moolenaar 	fr_list = l;
277261f346fSBram Moolenaar     else
278261f346fSBram Moolenaar     {
279261f346fSBram Moolenaar 	fr_list = list_alloc();
280261f346fSBram Moolenaar 	if (fr_list == NULL)
281261f346fSBram Moolenaar 	    return;
282261f346fSBram Moolenaar 	list_append_list(l, fr_list);
283261f346fSBram Moolenaar     }
284261f346fSBram Moolenaar 
285261f346fSBram Moolenaar     if (fr->fr_layout == FR_LEAF)
286261f346fSBram Moolenaar     {
287261f346fSBram Moolenaar 	if (fr->fr_win != NULL)
288261f346fSBram Moolenaar 	{
289261f346fSBram Moolenaar 	    list_append_string(fr_list, (char_u *)"leaf", -1);
290261f346fSBram Moolenaar 	    list_append_number(fr_list, fr->fr_win->w_id);
291261f346fSBram Moolenaar 	}
292261f346fSBram Moolenaar     }
293261f346fSBram Moolenaar     else
294261f346fSBram Moolenaar     {
295261f346fSBram Moolenaar 	list_append_string(fr_list,
296261f346fSBram Moolenaar 	     fr->fr_layout == FR_ROW ?  (char_u *)"row" : (char_u *)"col", -1);
297261f346fSBram Moolenaar 
298261f346fSBram Moolenaar 	win_list = list_alloc();
299261f346fSBram Moolenaar 	if (win_list == NULL)
300261f346fSBram Moolenaar 	    return;
301261f346fSBram Moolenaar 	list_append_list(fr_list, win_list);
302261f346fSBram Moolenaar 	child = fr->fr_child;
303261f346fSBram Moolenaar 	while (child != NULL)
304261f346fSBram Moolenaar 	{
305261f346fSBram Moolenaar 	    get_framelayout(child, win_list, FALSE);
306261f346fSBram Moolenaar 	    child = child->fr_next;
307261f346fSBram Moolenaar 	}
308261f346fSBram Moolenaar     }
309261f346fSBram Moolenaar }
310261f346fSBram Moolenaar 
311261f346fSBram Moolenaar /*
312261f346fSBram Moolenaar  * Common code for tabpagewinnr() and winnr().
313261f346fSBram Moolenaar  */
314261f346fSBram Moolenaar     static int
get_winnr(tabpage_T * tp,typval_T * argvar)315261f346fSBram Moolenaar get_winnr(tabpage_T *tp, typval_T *argvar)
316261f346fSBram Moolenaar {
317261f346fSBram Moolenaar     win_T	*twin;
318261f346fSBram Moolenaar     int		nr = 1;
319261f346fSBram Moolenaar     win_T	*wp;
320261f346fSBram Moolenaar     char_u	*arg;
321261f346fSBram Moolenaar 
322261f346fSBram Moolenaar     twin = (tp == curtab) ? curwin : tp->tp_curwin;
323261f346fSBram Moolenaar     if (argvar->v_type != VAR_UNKNOWN)
324261f346fSBram Moolenaar     {
325261f346fSBram Moolenaar 	int	invalid_arg = FALSE;
326261f346fSBram Moolenaar 
327261f346fSBram Moolenaar 	arg = tv_get_string_chk(argvar);
328261f346fSBram Moolenaar 	if (arg == NULL)
329261f346fSBram Moolenaar 	    nr = 0;		// type error; errmsg already given
330261f346fSBram Moolenaar 	else if (STRCMP(arg, "$") == 0)
331261f346fSBram Moolenaar 	    twin = (tp == curtab) ? lastwin : tp->tp_lastwin;
332261f346fSBram Moolenaar 	else if (STRCMP(arg, "#") == 0)
333261f346fSBram Moolenaar 	{
334261f346fSBram Moolenaar 	    twin = (tp == curtab) ? prevwin : tp->tp_prevwin;
335261f346fSBram Moolenaar 	}
336261f346fSBram Moolenaar 	else
337261f346fSBram Moolenaar 	{
338261f346fSBram Moolenaar 	    long	count;
339261f346fSBram Moolenaar 	    char_u	*endp;
340261f346fSBram Moolenaar 
341261f346fSBram Moolenaar 	    // Extract the window count (if specified). e.g. winnr('3j')
342261f346fSBram Moolenaar 	    count = strtol((char *)arg, (char **)&endp, 10);
343261f346fSBram Moolenaar 	    if (count <= 0)
344261f346fSBram Moolenaar 		count = 1;	// if count is not specified, default to 1
345261f346fSBram Moolenaar 	    if (endp != NULL && *endp != '\0')
346261f346fSBram Moolenaar 	    {
347261f346fSBram Moolenaar 		if (STRCMP(endp, "j") == 0)
348261f346fSBram Moolenaar 		    twin = win_vert_neighbor(tp, twin, FALSE, count);
349261f346fSBram Moolenaar 		else if (STRCMP(endp, "k") == 0)
350261f346fSBram Moolenaar 		    twin = win_vert_neighbor(tp, twin, TRUE, count);
351261f346fSBram Moolenaar 		else if (STRCMP(endp, "h") == 0)
352261f346fSBram Moolenaar 		    twin = win_horz_neighbor(tp, twin, TRUE, count);
353261f346fSBram Moolenaar 		else if (STRCMP(endp, "l") == 0)
354261f346fSBram Moolenaar 		    twin = win_horz_neighbor(tp, twin, FALSE, count);
355261f346fSBram Moolenaar 		else
356261f346fSBram Moolenaar 		    invalid_arg = TRUE;
357261f346fSBram Moolenaar 	    }
358261f346fSBram Moolenaar 	    else
359261f346fSBram Moolenaar 		invalid_arg = TRUE;
360261f346fSBram Moolenaar 	}
361631ebc48SBram Moolenaar 	if (twin == NULL)
362631ebc48SBram Moolenaar 	    nr = 0;
363261f346fSBram Moolenaar 
364261f346fSBram Moolenaar 	if (invalid_arg)
365261f346fSBram Moolenaar 	{
366108010aaSBram Moolenaar 	    semsg(_(e_invalid_expression_str), arg);
367261f346fSBram Moolenaar 	    nr = 0;
368261f346fSBram Moolenaar 	}
369261f346fSBram Moolenaar     }
370261f346fSBram Moolenaar 
371261f346fSBram Moolenaar     if (nr > 0)
372261f346fSBram Moolenaar 	for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
373261f346fSBram Moolenaar 					      wp != twin; wp = wp->w_next)
374261f346fSBram Moolenaar 	{
375261f346fSBram Moolenaar 	    if (wp == NULL)
376261f346fSBram Moolenaar 	    {
377261f346fSBram Moolenaar 		// didn't find it in this tabpage
378261f346fSBram Moolenaar 		nr = 0;
379261f346fSBram Moolenaar 		break;
380261f346fSBram Moolenaar 	    }
381261f346fSBram Moolenaar 	    ++nr;
382261f346fSBram Moolenaar 	}
383261f346fSBram Moolenaar     return nr;
384261f346fSBram Moolenaar }
385261f346fSBram Moolenaar 
386261f346fSBram Moolenaar /*
387261f346fSBram Moolenaar  * Returns information about a window as a dictionary.
388261f346fSBram Moolenaar  */
389261f346fSBram Moolenaar     static dict_T *
get_win_info(win_T * wp,short tpnr,short winnr)390261f346fSBram Moolenaar get_win_info(win_T *wp, short tpnr, short winnr)
391261f346fSBram Moolenaar {
392261f346fSBram Moolenaar     dict_T	*dict;
393261f346fSBram Moolenaar 
394261f346fSBram Moolenaar     dict = dict_alloc();
395261f346fSBram Moolenaar     if (dict == NULL)
396261f346fSBram Moolenaar 	return NULL;
397261f346fSBram Moolenaar 
398261f346fSBram Moolenaar     dict_add_number(dict, "tabnr", tpnr);
399261f346fSBram Moolenaar     dict_add_number(dict, "winnr", winnr);
400261f346fSBram Moolenaar     dict_add_number(dict, "winid", wp->w_id);
401261f346fSBram Moolenaar     dict_add_number(dict, "height", wp->w_height);
402261f346fSBram Moolenaar     dict_add_number(dict, "winrow", wp->w_winrow + 1);
403261f346fSBram Moolenaar     dict_add_number(dict, "topline", wp->w_topline);
404261f346fSBram Moolenaar     dict_add_number(dict, "botline", wp->w_botline - 1);
405261f346fSBram Moolenaar #ifdef FEAT_MENU
406261f346fSBram Moolenaar     dict_add_number(dict, "winbar", wp->w_winbar_height);
407261f346fSBram Moolenaar #endif
408261f346fSBram Moolenaar     dict_add_number(dict, "width", wp->w_width);
409261f346fSBram Moolenaar     dict_add_number(dict, "wincol", wp->w_wincol + 1);
410*cdf5fdb2SBram Moolenaar     dict_add_number(dict, "textoff", win_col_off(wp));
411261f346fSBram Moolenaar     dict_add_number(dict, "bufnr", wp->w_buffer->b_fnum);
412261f346fSBram Moolenaar 
413261f346fSBram Moolenaar #ifdef FEAT_TERMINAL
414261f346fSBram Moolenaar     dict_add_number(dict, "terminal", bt_terminal(wp->w_buffer));
415261f346fSBram Moolenaar #endif
416261f346fSBram Moolenaar #ifdef FEAT_QUICKFIX
417261f346fSBram Moolenaar     dict_add_number(dict, "quickfix", bt_quickfix(wp->w_buffer));
418261f346fSBram Moolenaar     dict_add_number(dict, "loclist",
419261f346fSBram Moolenaar 		      (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL));
420261f346fSBram Moolenaar #endif
421261f346fSBram Moolenaar 
422261f346fSBram Moolenaar     // Add a reference to window variables
423261f346fSBram Moolenaar     dict_add_dict(dict, "variables", wp->w_vars);
424261f346fSBram Moolenaar 
425261f346fSBram Moolenaar     return dict;
426261f346fSBram Moolenaar }
427261f346fSBram Moolenaar 
428261f346fSBram Moolenaar /*
429261f346fSBram Moolenaar  * Returns information (variables, options, etc.) about a tab page
430261f346fSBram Moolenaar  * as a dictionary.
431261f346fSBram Moolenaar  */
432261f346fSBram Moolenaar     static dict_T *
get_tabpage_info(tabpage_T * tp,int tp_idx)433261f346fSBram Moolenaar get_tabpage_info(tabpage_T *tp, int tp_idx)
434261f346fSBram Moolenaar {
435261f346fSBram Moolenaar     win_T	*wp;
436261f346fSBram Moolenaar     dict_T	*dict;
437261f346fSBram Moolenaar     list_T	*l;
438261f346fSBram Moolenaar 
439261f346fSBram Moolenaar     dict = dict_alloc();
440261f346fSBram Moolenaar     if (dict == NULL)
441261f346fSBram Moolenaar 	return NULL;
442261f346fSBram Moolenaar 
443261f346fSBram Moolenaar     dict_add_number(dict, "tabnr", tp_idx);
444261f346fSBram Moolenaar 
445261f346fSBram Moolenaar     l = list_alloc();
446261f346fSBram Moolenaar     if (l != NULL)
447261f346fSBram Moolenaar     {
44800d253e2SBram Moolenaar 	FOR_ALL_WINDOWS_IN_TAB(tp, wp)
449261f346fSBram Moolenaar 	    list_append_number(l, (varnumber_T)wp->w_id);
450261f346fSBram Moolenaar 	dict_add_list(dict, "windows", l);
451261f346fSBram Moolenaar     }
452261f346fSBram Moolenaar 
453261f346fSBram Moolenaar     // Make a reference to tabpage variables
454261f346fSBram Moolenaar     dict_add_dict(dict, "variables", tp->tp_vars);
455261f346fSBram Moolenaar 
456261f346fSBram Moolenaar     return dict;
457261f346fSBram Moolenaar }
458261f346fSBram Moolenaar 
459261f346fSBram Moolenaar /*
460261f346fSBram Moolenaar  * "gettabinfo()" function
461261f346fSBram Moolenaar  */
462261f346fSBram Moolenaar     void
f_gettabinfo(typval_T * argvars,typval_T * rettv)463261f346fSBram Moolenaar f_gettabinfo(typval_T *argvars, typval_T *rettv)
464261f346fSBram Moolenaar {
465261f346fSBram Moolenaar     tabpage_T	*tp, *tparg = NULL;
466261f346fSBram Moolenaar     dict_T	*d;
467261f346fSBram Moolenaar     int		tpnr = 0;
468261f346fSBram Moolenaar 
469261f346fSBram Moolenaar     if (rettv_list_alloc(rettv) != OK)
470261f346fSBram Moolenaar 	return;
471261f346fSBram Moolenaar 
4724490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL)
4734490ec4eSYegappan Lakshmanan 	return;
4744490ec4eSYegappan Lakshmanan 
475261f346fSBram Moolenaar     if (argvars[0].v_type != VAR_UNKNOWN)
476261f346fSBram Moolenaar     {
477261f346fSBram Moolenaar 	// Information about one tab page
478261f346fSBram Moolenaar 	tparg = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
479261f346fSBram Moolenaar 	if (tparg == NULL)
480261f346fSBram Moolenaar 	    return;
481261f346fSBram Moolenaar     }
482261f346fSBram Moolenaar 
483261f346fSBram Moolenaar     // Get information about a specific tab page or all tab pages
484261f346fSBram Moolenaar     FOR_ALL_TABPAGES(tp)
485261f346fSBram Moolenaar     {
486261f346fSBram Moolenaar 	tpnr++;
487261f346fSBram Moolenaar 	if (tparg != NULL && tp != tparg)
488261f346fSBram Moolenaar 	    continue;
489261f346fSBram Moolenaar 	d = get_tabpage_info(tp, tpnr);
490261f346fSBram Moolenaar 	if (d != NULL)
491261f346fSBram Moolenaar 	    list_append_dict(rettv->vval.v_list, d);
492261f346fSBram Moolenaar 	if (tparg != NULL)
493261f346fSBram Moolenaar 	    return;
494261f346fSBram Moolenaar     }
495261f346fSBram Moolenaar }
496261f346fSBram Moolenaar 
497261f346fSBram Moolenaar /*
498261f346fSBram Moolenaar  * "getwininfo()" function
499261f346fSBram Moolenaar  */
500261f346fSBram Moolenaar     void
f_getwininfo(typval_T * argvars,typval_T * rettv)501261f346fSBram Moolenaar f_getwininfo(typval_T *argvars, typval_T *rettv)
502261f346fSBram Moolenaar {
503261f346fSBram Moolenaar     tabpage_T	*tp;
504261f346fSBram Moolenaar     win_T	*wp = NULL, *wparg = NULL;
505261f346fSBram Moolenaar     dict_T	*d;
506261f346fSBram Moolenaar     short	tabnr = 0, winnr;
507261f346fSBram Moolenaar 
508261f346fSBram Moolenaar     if (rettv_list_alloc(rettv) != OK)
509261f346fSBram Moolenaar 	return;
510261f346fSBram Moolenaar 
5114490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL)
5124490ec4eSYegappan Lakshmanan 	return;
5134490ec4eSYegappan Lakshmanan 
514261f346fSBram Moolenaar     if (argvars[0].v_type != VAR_UNKNOWN)
515261f346fSBram Moolenaar     {
516261f346fSBram Moolenaar 	wparg = win_id2wp(tv_get_number(&argvars[0]));
517261f346fSBram Moolenaar 	if (wparg == NULL)
518261f346fSBram Moolenaar 	    return;
519261f346fSBram Moolenaar     }
520261f346fSBram Moolenaar 
521261f346fSBram Moolenaar     // Collect information about either all the windows across all the tab
522261f346fSBram Moolenaar     // pages or one particular window.
523261f346fSBram Moolenaar     FOR_ALL_TABPAGES(tp)
524261f346fSBram Moolenaar     {
525261f346fSBram Moolenaar 	tabnr++;
526261f346fSBram Moolenaar 	winnr = 0;
527261f346fSBram Moolenaar 	FOR_ALL_WINDOWS_IN_TAB(tp, wp)
528261f346fSBram Moolenaar 	{
529261f346fSBram Moolenaar 	    winnr++;
530261f346fSBram Moolenaar 	    if (wparg != NULL && wp != wparg)
531261f346fSBram Moolenaar 		continue;
532261f346fSBram Moolenaar 	    d = get_win_info(wp, tabnr, winnr);
533261f346fSBram Moolenaar 	    if (d != NULL)
534261f346fSBram Moolenaar 		list_append_dict(rettv->vval.v_list, d);
535261f346fSBram Moolenaar 	    if (wparg != NULL)
536261f346fSBram Moolenaar 		// found information about a specific window
537261f346fSBram Moolenaar 		return;
538261f346fSBram Moolenaar 	}
539261f346fSBram Moolenaar     }
54099ca9c48SBram Moolenaar #ifdef FEAT_PROP_POPUP
54199ca9c48SBram Moolenaar     if (wparg != NULL)
54299ca9c48SBram Moolenaar     {
54399ca9c48SBram Moolenaar 	tabnr = 0;
54499ca9c48SBram Moolenaar 	FOR_ALL_TABPAGES(tp)
54599ca9c48SBram Moolenaar 	{
54699ca9c48SBram Moolenaar 	    tabnr++;
54799ca9c48SBram Moolenaar 	    FOR_ALL_POPUPWINS_IN_TAB(tp, wp)
54899ca9c48SBram Moolenaar 	    if (wp == wparg)
54999ca9c48SBram Moolenaar 		break;
55099ca9c48SBram Moolenaar 	}
55199ca9c48SBram Moolenaar 	d = get_win_info(wparg, tp == NULL ? 0 : tabnr, 0);
55299ca9c48SBram Moolenaar 	if (d != NULL)
55399ca9c48SBram Moolenaar 	    list_append_dict(rettv->vval.v_list, d);
55499ca9c48SBram Moolenaar     }
55599ca9c48SBram Moolenaar #endif
556261f346fSBram Moolenaar }
557261f346fSBram Moolenaar 
558261f346fSBram Moolenaar /*
559261f346fSBram Moolenaar  * "getwinpos({timeout})" function
560261f346fSBram Moolenaar  */
561261f346fSBram Moolenaar     void
f_getwinpos(typval_T * argvars UNUSED,typval_T * rettv)562261f346fSBram Moolenaar f_getwinpos(typval_T *argvars UNUSED, typval_T *rettv)
563261f346fSBram Moolenaar {
564261f346fSBram Moolenaar     int x = -1;
565261f346fSBram Moolenaar     int y = -1;
566261f346fSBram Moolenaar 
567261f346fSBram Moolenaar     if (rettv_list_alloc(rettv) == FAIL)
568261f346fSBram Moolenaar 	return;
5694490ec4eSYegappan Lakshmanan 
5704490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL)
5714490ec4eSYegappan Lakshmanan 	return;
5724490ec4eSYegappan Lakshmanan 
573261f346fSBram Moolenaar #if defined(FEAT_GUI) \
574261f346fSBram Moolenaar 	|| (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \
575261f346fSBram Moolenaar 	|| defined(MSWIN)
576261f346fSBram Moolenaar     {
577261f346fSBram Moolenaar 	varnumber_T timeout = 100;
578261f346fSBram Moolenaar 
579261f346fSBram Moolenaar 	if (argvars[0].v_type != VAR_UNKNOWN)
580261f346fSBram Moolenaar 	    timeout = tv_get_number(&argvars[0]);
581261f346fSBram Moolenaar 
582261f346fSBram Moolenaar 	(void)ui_get_winpos(&x, &y, timeout);
583261f346fSBram Moolenaar     }
584261f346fSBram Moolenaar #endif
585261f346fSBram Moolenaar     list_append_number(rettv->vval.v_list, (varnumber_T)x);
586261f346fSBram Moolenaar     list_append_number(rettv->vval.v_list, (varnumber_T)y);
587261f346fSBram Moolenaar }
588261f346fSBram Moolenaar 
589261f346fSBram Moolenaar 
590261f346fSBram Moolenaar /*
591261f346fSBram Moolenaar  * "getwinposx()" function
592261f346fSBram Moolenaar  */
593261f346fSBram Moolenaar     void
f_getwinposx(typval_T * argvars UNUSED,typval_T * rettv)594261f346fSBram Moolenaar f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
595261f346fSBram Moolenaar {
596261f346fSBram Moolenaar     rettv->vval.v_number = -1;
597261f346fSBram Moolenaar #if defined(FEAT_GUI) \
598261f346fSBram Moolenaar 	|| (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \
599261f346fSBram Moolenaar 	|| defined(MSWIN)
600261f346fSBram Moolenaar 
601261f346fSBram Moolenaar     {
602261f346fSBram Moolenaar 	int	    x, y;
603261f346fSBram Moolenaar 
604261f346fSBram Moolenaar 	if (ui_get_winpos(&x, &y, 100) == OK)
605261f346fSBram Moolenaar 	    rettv->vval.v_number = x;
606261f346fSBram Moolenaar     }
607261f346fSBram Moolenaar #endif
608261f346fSBram Moolenaar }
609261f346fSBram Moolenaar 
610261f346fSBram Moolenaar /*
611261f346fSBram Moolenaar  * "getwinposy()" function
612261f346fSBram Moolenaar  */
613261f346fSBram Moolenaar     void
f_getwinposy(typval_T * argvars UNUSED,typval_T * rettv)614261f346fSBram Moolenaar f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv)
615261f346fSBram Moolenaar {
616261f346fSBram Moolenaar     rettv->vval.v_number = -1;
617261f346fSBram Moolenaar #if defined(FEAT_GUI) \
618261f346fSBram Moolenaar 	|| (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \
619261f346fSBram Moolenaar 	|| defined(MSWIN)
620261f346fSBram Moolenaar     {
621261f346fSBram Moolenaar 	int	    x, y;
622261f346fSBram Moolenaar 
623261f346fSBram Moolenaar 	if (ui_get_winpos(&x, &y, 100) == OK)
624261f346fSBram Moolenaar 	    rettv->vval.v_number = y;
625261f346fSBram Moolenaar     }
626261f346fSBram Moolenaar #endif
627261f346fSBram Moolenaar }
628261f346fSBram Moolenaar 
629261f346fSBram Moolenaar /*
630261f346fSBram Moolenaar  * "tabpagenr()" function
631261f346fSBram Moolenaar  */
632261f346fSBram Moolenaar     void
f_tabpagenr(typval_T * argvars UNUSED,typval_T * rettv)633261f346fSBram Moolenaar f_tabpagenr(typval_T *argvars UNUSED, typval_T *rettv)
634261f346fSBram Moolenaar {
635261f346fSBram Moolenaar     int		nr = 1;
636261f346fSBram Moolenaar     char_u	*arg;
637261f346fSBram Moolenaar 
6384490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL)
6394490ec4eSYegappan Lakshmanan 	return;
6404490ec4eSYegappan Lakshmanan 
641261f346fSBram Moolenaar     if (argvars[0].v_type != VAR_UNKNOWN)
642261f346fSBram Moolenaar     {
643261f346fSBram Moolenaar 	arg = tv_get_string_chk(&argvars[0]);
644261f346fSBram Moolenaar 	nr = 0;
645261f346fSBram Moolenaar 	if (arg != NULL)
646261f346fSBram Moolenaar 	{
647261f346fSBram Moolenaar 	    if (STRCMP(arg, "$") == 0)
648261f346fSBram Moolenaar 		nr = tabpage_index(NULL) - 1;
64962a23250SBram Moolenaar 	    else if (STRCMP(arg, "#") == 0)
65062a23250SBram Moolenaar 		nr = valid_tabpage(lastused_tabpage) ?
65162a23250SBram Moolenaar 					tabpage_index(lastused_tabpage) : 0;
652261f346fSBram Moolenaar 	    else
653108010aaSBram Moolenaar 		semsg(_(e_invalid_expression_str), arg);
654261f346fSBram Moolenaar 	}
655261f346fSBram Moolenaar     }
656261f346fSBram Moolenaar     else
657261f346fSBram Moolenaar 	nr = tabpage_index(curtab);
658261f346fSBram Moolenaar     rettv->vval.v_number = nr;
659261f346fSBram Moolenaar }
660261f346fSBram Moolenaar 
661261f346fSBram Moolenaar /*
662261f346fSBram Moolenaar  * "tabpagewinnr()" function
663261f346fSBram Moolenaar  */
664261f346fSBram Moolenaar     void
f_tabpagewinnr(typval_T * argvars UNUSED,typval_T * rettv)665261f346fSBram Moolenaar f_tabpagewinnr(typval_T *argvars UNUSED, typval_T *rettv)
666261f346fSBram Moolenaar {
667261f346fSBram Moolenaar     int		nr = 1;
668261f346fSBram Moolenaar     tabpage_T	*tp;
669261f346fSBram Moolenaar 
6701a71d31bSYegappan Lakshmanan     if (in_vim9script()
6711a71d31bSYegappan Lakshmanan 	    && (check_for_number_arg(argvars, 0) == FAIL
67283494b4aSYegappan Lakshmanan 		|| check_for_opt_string_arg(argvars, 1) == FAIL))
6731a71d31bSYegappan Lakshmanan 	return;
6741a71d31bSYegappan Lakshmanan 
675261f346fSBram Moolenaar     tp = find_tabpage((int)tv_get_number(&argvars[0]));
676261f346fSBram Moolenaar     if (tp == NULL)
677261f346fSBram Moolenaar 	nr = 0;
678261f346fSBram Moolenaar     else
679261f346fSBram Moolenaar 	nr = get_winnr(tp, &argvars[1]);
680261f346fSBram Moolenaar     rettv->vval.v_number = nr;
681261f346fSBram Moolenaar }
682261f346fSBram Moolenaar 
683261f346fSBram Moolenaar /*
684261f346fSBram Moolenaar  * "win_execute()" function
685261f346fSBram Moolenaar  */
686261f346fSBram Moolenaar     void
f_win_execute(typval_T * argvars,typval_T * rettv)687261f346fSBram Moolenaar f_win_execute(typval_T *argvars, typval_T *rettv)
688261f346fSBram Moolenaar {
6894490ec4eSYegappan Lakshmanan     int		id;
690261f346fSBram Moolenaar     tabpage_T	*tp;
6914490ec4eSYegappan Lakshmanan     win_T	*wp;
692261f346fSBram Moolenaar     win_T	*save_curwin;
693261f346fSBram Moolenaar     tabpage_T	*save_curtab;
694261f346fSBram Moolenaar 
69537487e16SBram Moolenaar     // Return an empty string if something fails.
69637487e16SBram Moolenaar     rettv->v_type = VAR_STRING;
69737487e16SBram Moolenaar     rettv->vval.v_string = NULL;
69837487e16SBram Moolenaar 
6994490ec4eSYegappan Lakshmanan     if (in_vim9script()
7004490ec4eSYegappan Lakshmanan 	    && (check_for_number_arg(argvars, 0) == FAIL
7014490ec4eSYegappan Lakshmanan 		|| check_for_string_or_list_arg(argvars, 1) == FAIL
7024490ec4eSYegappan Lakshmanan 		|| check_for_opt_string_arg(argvars, 2) == FAIL))
7034490ec4eSYegappan Lakshmanan 	return;
7044490ec4eSYegappan Lakshmanan 
7054490ec4eSYegappan Lakshmanan     id = (int)tv_get_number(argvars);
7064490ec4eSYegappan Lakshmanan     wp = win_id2wp_tp(id, &tp);
707261f346fSBram Moolenaar     if (wp != NULL && tp != NULL)
708261f346fSBram Moolenaar     {
709345f28dfSBram Moolenaar 	pos_T	curpos = wp->w_cursor;
710345f28dfSBram Moolenaar 
711261f346fSBram Moolenaar 	if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, TRUE) == OK)
712261f346fSBram Moolenaar 	{
713261f346fSBram Moolenaar 	    check_cursor();
714261f346fSBram Moolenaar 	    execute_common(argvars, rettv, 1);
715261f346fSBram Moolenaar 	}
716261f346fSBram Moolenaar 	restore_win_noblock(save_curwin, save_curtab, TRUE);
717345f28dfSBram Moolenaar 
718345f28dfSBram Moolenaar 	// Update the status line if the cursor moved.
719345f28dfSBram Moolenaar 	if (win_valid(wp) && !EQUAL_POS(curpos, wp->w_cursor))
720345f28dfSBram Moolenaar 	    wp->w_redr_status = TRUE;
721261f346fSBram Moolenaar     }
722261f346fSBram Moolenaar }
723261f346fSBram Moolenaar 
724261f346fSBram Moolenaar /*
725261f346fSBram Moolenaar  * "win_findbuf()" function
726261f346fSBram Moolenaar  */
727261f346fSBram Moolenaar     void
f_win_findbuf(typval_T * argvars,typval_T * rettv)728261f346fSBram Moolenaar f_win_findbuf(typval_T *argvars, typval_T *rettv)
729261f346fSBram Moolenaar {
7304490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
7314490ec4eSYegappan Lakshmanan 	return;
7324490ec4eSYegappan Lakshmanan 
733261f346fSBram Moolenaar     if (rettv_list_alloc(rettv) != FAIL)
734261f346fSBram Moolenaar 	win_findbuf(argvars, rettv->vval.v_list);
735261f346fSBram Moolenaar }
736261f346fSBram Moolenaar 
737261f346fSBram Moolenaar /*
738261f346fSBram Moolenaar  * "win_getid()" function
739261f346fSBram Moolenaar  */
740261f346fSBram Moolenaar     void
f_win_getid(typval_T * argvars,typval_T * rettv)741261f346fSBram Moolenaar f_win_getid(typval_T *argvars, typval_T *rettv)
742261f346fSBram Moolenaar {
7434490ec4eSYegappan Lakshmanan     if (in_vim9script()
7444490ec4eSYegappan Lakshmanan 	    && (check_for_opt_number_arg(argvars, 0) == FAIL
7454490ec4eSYegappan Lakshmanan 		|| (argvars[0].v_type != VAR_UNKNOWN
7464490ec4eSYegappan Lakshmanan 		    && check_for_opt_number_arg(argvars, 1) == FAIL)))
7474490ec4eSYegappan Lakshmanan 	return;
7484490ec4eSYegappan Lakshmanan 
749261f346fSBram Moolenaar     rettv->vval.v_number = win_getid(argvars);
750261f346fSBram Moolenaar }
751261f346fSBram Moolenaar 
752261f346fSBram Moolenaar /*
753261f346fSBram Moolenaar  * "win_gotoid()" function
754261f346fSBram Moolenaar  */
755261f346fSBram Moolenaar     void
f_win_gotoid(typval_T * argvars,typval_T * rettv)756261f346fSBram Moolenaar f_win_gotoid(typval_T *argvars, typval_T *rettv)
757261f346fSBram Moolenaar {
758a046b37cSBram Moolenaar     win_T	*wp;
759a046b37cSBram Moolenaar     tabpage_T   *tp;
7604490ec4eSYegappan Lakshmanan     int		id;
761a046b37cSBram Moolenaar 
7624490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
7634490ec4eSYegappan Lakshmanan 	return;
7644490ec4eSYegappan Lakshmanan 
7654490ec4eSYegappan Lakshmanan     id = tv_get_number(&argvars[0]);
766a046b37cSBram Moolenaar #ifdef FEAT_CMDWIN
767a046b37cSBram Moolenaar     if (cmdwin_type != 0)
768a046b37cSBram Moolenaar     {
769108010aaSBram Moolenaar 	emsg(_(e_invalid_in_cmdline_window));
770a046b37cSBram Moolenaar 	return;
771a046b37cSBram Moolenaar     }
772a046b37cSBram Moolenaar #endif
773a046b37cSBram Moolenaar     FOR_ALL_TAB_WINDOWS(tp, wp)
774a046b37cSBram Moolenaar 	if (wp->w_id == id)
775a046b37cSBram Moolenaar 	{
776a046b37cSBram Moolenaar 	    goto_tabpage_win(tp, wp);
777a046b37cSBram Moolenaar 	    rettv->vval.v_number = 1;
778a046b37cSBram Moolenaar 	    return;
779a046b37cSBram Moolenaar 	}
780261f346fSBram Moolenaar }
781261f346fSBram Moolenaar 
782261f346fSBram Moolenaar /*
783261f346fSBram Moolenaar  * "win_id2tabwin()" function
784261f346fSBram Moolenaar  */
785261f346fSBram Moolenaar     void
f_win_id2tabwin(typval_T * argvars,typval_T * rettv)786261f346fSBram Moolenaar f_win_id2tabwin(typval_T *argvars, typval_T *rettv)
787261f346fSBram Moolenaar {
7884490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
7894490ec4eSYegappan Lakshmanan 	return;
7904490ec4eSYegappan Lakshmanan 
791261f346fSBram Moolenaar     if (rettv_list_alloc(rettv) != FAIL)
792261f346fSBram Moolenaar 	win_id2tabwin(argvars, rettv->vval.v_list);
793261f346fSBram Moolenaar }
794261f346fSBram Moolenaar 
795261f346fSBram Moolenaar /*
796261f346fSBram Moolenaar  * "win_id2win()" function
797261f346fSBram Moolenaar  */
798261f346fSBram Moolenaar     void
f_win_id2win(typval_T * argvars,typval_T * rettv)799261f346fSBram Moolenaar f_win_id2win(typval_T *argvars, typval_T *rettv)
800261f346fSBram Moolenaar {
8014490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
8024490ec4eSYegappan Lakshmanan 	return;
8034490ec4eSYegappan Lakshmanan 
804261f346fSBram Moolenaar     rettv->vval.v_number = win_id2win(argvars);
805261f346fSBram Moolenaar }
806261f346fSBram Moolenaar 
807261f346fSBram Moolenaar /*
808261f346fSBram Moolenaar  * "win_screenpos()" function
809261f346fSBram Moolenaar  */
810261f346fSBram Moolenaar     void
f_win_screenpos(typval_T * argvars,typval_T * rettv)811261f346fSBram Moolenaar f_win_screenpos(typval_T *argvars, typval_T *rettv)
812261f346fSBram Moolenaar {
813261f346fSBram Moolenaar     win_T	*wp;
814261f346fSBram Moolenaar 
815261f346fSBram Moolenaar     if (rettv_list_alloc(rettv) == FAIL)
816261f346fSBram Moolenaar 	return;
817261f346fSBram Moolenaar 
8184490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
8194490ec4eSYegappan Lakshmanan 	return;
8204490ec4eSYegappan Lakshmanan 
821261f346fSBram Moolenaar     wp = find_win_by_nr_or_id(&argvars[0]);
822261f346fSBram Moolenaar     list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_winrow + 1);
823261f346fSBram Moolenaar     list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_wincol + 1);
824261f346fSBram Moolenaar }
825261f346fSBram Moolenaar 
826261f346fSBram Moolenaar /*
827d20dcb3dSBram Moolenaar  * Move the window wp into a new split of targetwin in a given direction
828d20dcb3dSBram Moolenaar  */
829d20dcb3dSBram Moolenaar     static void
win_move_into_split(win_T * wp,win_T * targetwin,int size,int flags)830d20dcb3dSBram Moolenaar win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags)
831d20dcb3dSBram Moolenaar {
832d20dcb3dSBram Moolenaar     int	    dir;
833d20dcb3dSBram Moolenaar     int	    height = wp->w_height;
834d20dcb3dSBram Moolenaar     win_T   *oldwin = curwin;
835d20dcb3dSBram Moolenaar 
836d20dcb3dSBram Moolenaar     if (wp == targetwin)
837d20dcb3dSBram Moolenaar 	return;
838d20dcb3dSBram Moolenaar 
839d20dcb3dSBram Moolenaar     // Jump to the target window
840d20dcb3dSBram Moolenaar     if (curwin != targetwin)
841d20dcb3dSBram Moolenaar 	win_goto(targetwin);
842d20dcb3dSBram Moolenaar 
843d20dcb3dSBram Moolenaar     // Remove the old window and frame from the tree of frames
844d20dcb3dSBram Moolenaar     (void)winframe_remove(wp, &dir, NULL);
845d20dcb3dSBram Moolenaar     win_remove(wp, NULL);
846d20dcb3dSBram Moolenaar     last_status(FALSE);	    // may need to remove last status line
847d20dcb3dSBram Moolenaar     (void)win_comp_pos();   // recompute window positions
848d20dcb3dSBram Moolenaar 
849d20dcb3dSBram Moolenaar     // Split a window on the desired side and put the old window there
850d20dcb3dSBram Moolenaar     (void)win_split_ins(size, flags, wp, dir);
851d20dcb3dSBram Moolenaar 
852d20dcb3dSBram Moolenaar     // If splitting horizontally, try to preserve height
853d20dcb3dSBram Moolenaar     if (size == 0 && !(flags & WSP_VERT))
854d20dcb3dSBram Moolenaar     {
855d20dcb3dSBram Moolenaar 	win_setheight_win(height, wp);
856d20dcb3dSBram Moolenaar 	if (p_ea)
857d20dcb3dSBram Moolenaar 	    win_equal(wp, TRUE, 'v');
858d20dcb3dSBram Moolenaar     }
859d20dcb3dSBram Moolenaar 
860d20dcb3dSBram Moolenaar #if defined(FEAT_GUI)
861d20dcb3dSBram Moolenaar     // When 'guioptions' includes 'L' or 'R' may have to remove or add
862d20dcb3dSBram Moolenaar     // scrollbars.  Have to update them anyway.
863d20dcb3dSBram Moolenaar     gui_may_update_scrollbars();
864d20dcb3dSBram Moolenaar #endif
865d20dcb3dSBram Moolenaar 
866d20dcb3dSBram Moolenaar     if (oldwin != curwin)
867d20dcb3dSBram Moolenaar 	win_goto(oldwin);
868d20dcb3dSBram Moolenaar }
869d20dcb3dSBram Moolenaar 
870d20dcb3dSBram Moolenaar /*
871d20dcb3dSBram Moolenaar  * "win_splitmove()" function
872d20dcb3dSBram Moolenaar  */
873d20dcb3dSBram Moolenaar     void
f_win_splitmove(typval_T * argvars,typval_T * rettv)874d20dcb3dSBram Moolenaar f_win_splitmove(typval_T *argvars, typval_T *rettv)
875d20dcb3dSBram Moolenaar {
876d20dcb3dSBram Moolenaar     win_T   *wp;
877d20dcb3dSBram Moolenaar     win_T   *targetwin;
878d20dcb3dSBram Moolenaar     int     flags = 0, size = 0;
879d20dcb3dSBram Moolenaar 
88083494b4aSYegappan Lakshmanan     if (in_vim9script()
88183494b4aSYegappan Lakshmanan 	    && (check_for_number_arg(argvars, 0) == FAIL
88283494b4aSYegappan Lakshmanan 		|| check_for_number_arg(argvars, 1) == FAIL
88383494b4aSYegappan Lakshmanan 		|| check_for_opt_dict_arg(argvars, 2) == FAIL))
88483494b4aSYegappan Lakshmanan 	return;
88583494b4aSYegappan Lakshmanan 
886d20dcb3dSBram Moolenaar     wp = find_win_by_nr_or_id(&argvars[0]);
887d20dcb3dSBram Moolenaar     targetwin = find_win_by_nr_or_id(&argvars[1]);
888d20dcb3dSBram Moolenaar 
8897b94e771SBram Moolenaar     if (wp == NULL || targetwin == NULL || wp == targetwin
8900f1563ffSBram Moolenaar 	    || !win_valid(wp) || !win_valid(targetwin)
8910f1563ffSBram Moolenaar 	    || win_valid_popup(wp) || win_valid_popup(targetwin))
892d20dcb3dSBram Moolenaar     {
893d20dcb3dSBram Moolenaar         emsg(_(e_invalwindow));
894d20dcb3dSBram Moolenaar 	rettv->vval.v_number = -1;
895d20dcb3dSBram Moolenaar 	return;
896d20dcb3dSBram Moolenaar     }
897d20dcb3dSBram Moolenaar 
898d20dcb3dSBram Moolenaar     if (argvars[2].v_type != VAR_UNKNOWN)
899d20dcb3dSBram Moolenaar     {
900d20dcb3dSBram Moolenaar         dict_T      *d;
901d20dcb3dSBram Moolenaar         dictitem_T  *di;
902d20dcb3dSBram Moolenaar 
903d20dcb3dSBram Moolenaar         if (argvars[2].v_type != VAR_DICT || argvars[2].vval.v_dict == NULL)
904d20dcb3dSBram Moolenaar         {
905d20dcb3dSBram Moolenaar             emsg(_(e_invarg));
906d20dcb3dSBram Moolenaar             return;
907d20dcb3dSBram Moolenaar         }
908d20dcb3dSBram Moolenaar 
909d20dcb3dSBram Moolenaar         d = argvars[2].vval.v_dict;
9104b9bd692SBram Moolenaar         if (dict_get_bool(d, (char_u *)"vertical", FALSE))
911d20dcb3dSBram Moolenaar             flags |= WSP_VERT;
912d20dcb3dSBram Moolenaar         if ((di = dict_find(d, (char_u *)"rightbelow", -1)) != NULL)
9134b9bd692SBram Moolenaar             flags |= tv_get_bool(&di->di_tv) ? WSP_BELOW : WSP_ABOVE;
914d20dcb3dSBram Moolenaar         size = (int)dict_get_number(d, (char_u *)"size");
915d20dcb3dSBram Moolenaar     }
916d20dcb3dSBram Moolenaar 
917d20dcb3dSBram Moolenaar     win_move_into_split(wp, targetwin, size, flags);
918d20dcb3dSBram Moolenaar }
919d20dcb3dSBram Moolenaar 
920d20dcb3dSBram Moolenaar /*
92100f3b4e0SBram Moolenaar  * "win_gettype(nr)" function
92200f3b4e0SBram Moolenaar  */
92300f3b4e0SBram Moolenaar     void
f_win_gettype(typval_T * argvars,typval_T * rettv)92400f3b4e0SBram Moolenaar f_win_gettype(typval_T *argvars, typval_T *rettv)
92500f3b4e0SBram Moolenaar {
92600f3b4e0SBram Moolenaar     win_T	*wp = curwin;
92700f3b4e0SBram Moolenaar 
92800f3b4e0SBram Moolenaar     rettv->v_type = VAR_STRING;
92900f3b4e0SBram Moolenaar     rettv->vval.v_string = NULL;
9304490ec4eSYegappan Lakshmanan 
9314490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL)
9324490ec4eSYegappan Lakshmanan 	return;
9334490ec4eSYegappan Lakshmanan 
93400f3b4e0SBram Moolenaar     if (argvars[0].v_type != VAR_UNKNOWN)
93500f3b4e0SBram Moolenaar     {
93600f3b4e0SBram Moolenaar 	wp = find_win_by_nr_or_id(&argvars[0]);
93700f3b4e0SBram Moolenaar 	if (wp == NULL)
93800f3b4e0SBram Moolenaar 	{
93900f3b4e0SBram Moolenaar 	    rettv->vval.v_string = vim_strsave((char_u *)"unknown");
94000f3b4e0SBram Moolenaar 	    return;
94100f3b4e0SBram Moolenaar 	}
94200f3b4e0SBram Moolenaar     }
9430fe937fdSBram Moolenaar     if (wp == aucmd_win)
94440a019f1SBram Moolenaar 	rettv->vval.v_string = vim_strsave((char_u *)"autocmd");
9450fe937fdSBram Moolenaar #if defined(FEAT_QUICKFIX)
9460fe937fdSBram Moolenaar     else if (wp->w_p_pvw)
9470fe937fdSBram Moolenaar 	rettv->vval.v_string = vim_strsave((char_u *)"preview");
9480fe937fdSBram Moolenaar #endif
94900f3b4e0SBram Moolenaar #ifdef FEAT_PROP_POPUP
9500fe937fdSBram Moolenaar     else if (WIN_IS_POPUP(wp))
95100f3b4e0SBram Moolenaar 	rettv->vval.v_string = vim_strsave((char_u *)"popup");
95200f3b4e0SBram Moolenaar #endif
95300f3b4e0SBram Moolenaar #ifdef FEAT_CMDWIN
9540fe937fdSBram Moolenaar     else if (wp == curwin && cmdwin_type != 0)
95500f3b4e0SBram Moolenaar 	rettv->vval.v_string = vim_strsave((char_u *)"command");
95600f3b4e0SBram Moolenaar #endif
95728d8421bSYegappan Lakshmanan #ifdef FEAT_QUICKFIX
95828d8421bSYegappan Lakshmanan     else if (bt_quickfix(wp->w_buffer))
95928d8421bSYegappan Lakshmanan 	rettv->vval.v_string = vim_strsave((char_u *)
96028d8421bSYegappan Lakshmanan 		(wp->w_llist_ref != NULL ? "loclist" : "quickfix"));
96128d8421bSYegappan Lakshmanan #endif
96228d8421bSYegappan Lakshmanan 
96300f3b4e0SBram Moolenaar }
96400f3b4e0SBram Moolenaar 
96500f3b4e0SBram Moolenaar /*
96600f3b4e0SBram Moolenaar  * "getcmdwintype()" function
96700f3b4e0SBram Moolenaar  */
96800f3b4e0SBram Moolenaar     void
f_getcmdwintype(typval_T * argvars UNUSED,typval_T * rettv)96900f3b4e0SBram Moolenaar f_getcmdwintype(typval_T *argvars UNUSED, typval_T *rettv)
97000f3b4e0SBram Moolenaar {
97100f3b4e0SBram Moolenaar     rettv->v_type = VAR_STRING;
97200f3b4e0SBram Moolenaar     rettv->vval.v_string = NULL;
97300f3b4e0SBram Moolenaar #ifdef FEAT_CMDWIN
97400f3b4e0SBram Moolenaar     rettv->vval.v_string = alloc(2);
97500f3b4e0SBram Moolenaar     if (rettv->vval.v_string != NULL)
97600f3b4e0SBram Moolenaar     {
97700f3b4e0SBram Moolenaar 	rettv->vval.v_string[0] = cmdwin_type;
97800f3b4e0SBram Moolenaar 	rettv->vval.v_string[1] = NUL;
97900f3b4e0SBram Moolenaar     }
98000f3b4e0SBram Moolenaar #endif
98100f3b4e0SBram Moolenaar }
98200f3b4e0SBram Moolenaar 
98300f3b4e0SBram Moolenaar /*
984261f346fSBram Moolenaar  * "winbufnr(nr)" function
985261f346fSBram Moolenaar  */
986261f346fSBram Moolenaar     void
f_winbufnr(typval_T * argvars,typval_T * rettv)987261f346fSBram Moolenaar f_winbufnr(typval_T *argvars, typval_T *rettv)
988261f346fSBram Moolenaar {
989261f346fSBram Moolenaar     win_T	*wp;
990261f346fSBram Moolenaar 
9914490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
9924490ec4eSYegappan Lakshmanan 	return;
9934490ec4eSYegappan Lakshmanan 
994261f346fSBram Moolenaar     wp = find_win_by_nr_or_id(&argvars[0]);
995261f346fSBram Moolenaar     if (wp == NULL)
996261f346fSBram Moolenaar 	rettv->vval.v_number = -1;
997261f346fSBram Moolenaar     else
998261f346fSBram Moolenaar 	rettv->vval.v_number = wp->w_buffer->b_fnum;
999261f346fSBram Moolenaar }
1000261f346fSBram Moolenaar 
1001261f346fSBram Moolenaar /*
1002261f346fSBram Moolenaar  * "wincol()" function
1003261f346fSBram Moolenaar  */
1004261f346fSBram Moolenaar     void
f_wincol(typval_T * argvars UNUSED,typval_T * rettv)1005261f346fSBram Moolenaar f_wincol(typval_T *argvars UNUSED, typval_T *rettv)
1006261f346fSBram Moolenaar {
1007261f346fSBram Moolenaar     validate_cursor();
1008261f346fSBram Moolenaar     rettv->vval.v_number = curwin->w_wcol + 1;
1009261f346fSBram Moolenaar }
1010261f346fSBram Moolenaar 
1011261f346fSBram Moolenaar /*
1012261f346fSBram Moolenaar  * "winheight(nr)" function
1013261f346fSBram Moolenaar  */
1014261f346fSBram Moolenaar     void
f_winheight(typval_T * argvars,typval_T * rettv)1015261f346fSBram Moolenaar f_winheight(typval_T *argvars, typval_T *rettv)
1016261f346fSBram Moolenaar {
1017261f346fSBram Moolenaar     win_T	*wp;
1018261f346fSBram Moolenaar 
10194490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
10204490ec4eSYegappan Lakshmanan 	return;
10214490ec4eSYegappan Lakshmanan 
1022261f346fSBram Moolenaar     wp = find_win_by_nr_or_id(&argvars[0]);
1023261f346fSBram Moolenaar     if (wp == NULL)
1024261f346fSBram Moolenaar 	rettv->vval.v_number = -1;
1025261f346fSBram Moolenaar     else
1026261f346fSBram Moolenaar 	rettv->vval.v_number = wp->w_height;
1027261f346fSBram Moolenaar }
1028261f346fSBram Moolenaar 
1029261f346fSBram Moolenaar /*
1030261f346fSBram Moolenaar  * "winlayout()" function
1031261f346fSBram Moolenaar  */
1032261f346fSBram Moolenaar     void
f_winlayout(typval_T * argvars,typval_T * rettv)1033261f346fSBram Moolenaar f_winlayout(typval_T *argvars, typval_T *rettv)
1034261f346fSBram Moolenaar {
1035261f346fSBram Moolenaar     tabpage_T	*tp;
1036261f346fSBram Moolenaar 
1037261f346fSBram Moolenaar     if (rettv_list_alloc(rettv) != OK)
1038261f346fSBram Moolenaar 	return;
1039261f346fSBram Moolenaar 
10404490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL)
10414490ec4eSYegappan Lakshmanan 	return;
10424490ec4eSYegappan Lakshmanan 
1043261f346fSBram Moolenaar     if (argvars[0].v_type == VAR_UNKNOWN)
1044261f346fSBram Moolenaar 	tp = curtab;
1045261f346fSBram Moolenaar     else
1046261f346fSBram Moolenaar     {
1047261f346fSBram Moolenaar 	tp = find_tabpage((int)tv_get_number(&argvars[0]));
1048261f346fSBram Moolenaar 	if (tp == NULL)
1049261f346fSBram Moolenaar 	    return;
1050261f346fSBram Moolenaar     }
1051261f346fSBram Moolenaar 
1052261f346fSBram Moolenaar     get_framelayout(tp->tp_topframe, rettv->vval.v_list, TRUE);
1053261f346fSBram Moolenaar }
1054261f346fSBram Moolenaar 
1055261f346fSBram Moolenaar /*
1056261f346fSBram Moolenaar  * "winline()" function
1057261f346fSBram Moolenaar  */
1058261f346fSBram Moolenaar     void
f_winline(typval_T * argvars UNUSED,typval_T * rettv)1059261f346fSBram Moolenaar f_winline(typval_T *argvars UNUSED, typval_T *rettv)
1060261f346fSBram Moolenaar {
1061261f346fSBram Moolenaar     validate_cursor();
1062261f346fSBram Moolenaar     rettv->vval.v_number = curwin->w_wrow + 1;
1063261f346fSBram Moolenaar }
1064261f346fSBram Moolenaar 
1065261f346fSBram Moolenaar /*
1066261f346fSBram Moolenaar  * "winnr()" function
1067261f346fSBram Moolenaar  */
1068261f346fSBram Moolenaar     void
f_winnr(typval_T * argvars UNUSED,typval_T * rettv)1069261f346fSBram Moolenaar f_winnr(typval_T *argvars UNUSED, typval_T *rettv)
1070261f346fSBram Moolenaar {
1071261f346fSBram Moolenaar     int		nr = 1;
1072261f346fSBram Moolenaar 
10734490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL)
10744490ec4eSYegappan Lakshmanan 	return;
10754490ec4eSYegappan Lakshmanan 
1076261f346fSBram Moolenaar     nr = get_winnr(curtab, &argvars[0]);
1077261f346fSBram Moolenaar     rettv->vval.v_number = nr;
1078261f346fSBram Moolenaar }
1079261f346fSBram Moolenaar 
1080261f346fSBram Moolenaar /*
1081261f346fSBram Moolenaar  * "winrestcmd()" function
1082261f346fSBram Moolenaar  */
1083261f346fSBram Moolenaar     void
f_winrestcmd(typval_T * argvars UNUSED,typval_T * rettv)1084261f346fSBram Moolenaar f_winrestcmd(typval_T *argvars UNUSED, typval_T *rettv)
1085261f346fSBram Moolenaar {
1086261f346fSBram Moolenaar     win_T	*wp;
1087a0c8aea4SBram Moolenaar     int		i;
1088a0c8aea4SBram Moolenaar     int		winnr;
1089261f346fSBram Moolenaar     garray_T	ga;
1090261f346fSBram Moolenaar     char_u	buf[50];
1091261f346fSBram Moolenaar 
1092261f346fSBram Moolenaar     ga_init2(&ga, (int)sizeof(char), 70);
1093a0c8aea4SBram Moolenaar 
1094a0c8aea4SBram Moolenaar     // Do this twice to handle some window layouts properly.
1095a0c8aea4SBram Moolenaar     for (i = 0; i < 2; ++i)
1096a0c8aea4SBram Moolenaar     {
1097a0c8aea4SBram Moolenaar 	winnr = 1;
1098261f346fSBram Moolenaar 	FOR_ALL_WINDOWS(wp)
1099261f346fSBram Moolenaar 	{
1100285b15fcSBram Moolenaar 	    sprintf((char *)buf, ":%dresize %d|", winnr, wp->w_height);
1101261f346fSBram Moolenaar 	    ga_concat(&ga, buf);
1102285b15fcSBram Moolenaar 	    sprintf((char *)buf, "vert :%dresize %d|", winnr, wp->w_width);
1103261f346fSBram Moolenaar 	    ga_concat(&ga, buf);
1104261f346fSBram Moolenaar 	    ++winnr;
1105261f346fSBram Moolenaar 	}
1106a0c8aea4SBram Moolenaar     }
1107261f346fSBram Moolenaar     ga_append(&ga, NUL);
1108261f346fSBram Moolenaar 
1109261f346fSBram Moolenaar     rettv->vval.v_string = ga.ga_data;
1110261f346fSBram Moolenaar     rettv->v_type = VAR_STRING;
1111261f346fSBram Moolenaar }
1112261f346fSBram Moolenaar 
1113261f346fSBram Moolenaar /*
1114261f346fSBram Moolenaar  * "winrestview()" function
1115261f346fSBram Moolenaar  */
1116261f346fSBram Moolenaar     void
f_winrestview(typval_T * argvars,typval_T * rettv UNUSED)1117261f346fSBram Moolenaar f_winrestview(typval_T *argvars, typval_T *rettv UNUSED)
1118261f346fSBram Moolenaar {
1119261f346fSBram Moolenaar     dict_T	*dict;
1120261f346fSBram Moolenaar 
11214490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_dict_arg(argvars, 0) == FAIL)
11224490ec4eSYegappan Lakshmanan 	return;
11234490ec4eSYegappan Lakshmanan 
1124261f346fSBram Moolenaar     if (argvars[0].v_type != VAR_DICT
1125261f346fSBram Moolenaar 	    || (dict = argvars[0].vval.v_dict) == NULL)
1126261f346fSBram Moolenaar 	emsg(_(e_invarg));
1127261f346fSBram Moolenaar     else
1128261f346fSBram Moolenaar     {
1129261f346fSBram Moolenaar 	if (dict_find(dict, (char_u *)"lnum", -1) != NULL)
1130261f346fSBram Moolenaar 	    curwin->w_cursor.lnum = (linenr_T)dict_get_number(dict, (char_u *)"lnum");
1131261f346fSBram Moolenaar 	if (dict_find(dict, (char_u *)"col", -1) != NULL)
1132261f346fSBram Moolenaar 	    curwin->w_cursor.col = (colnr_T)dict_get_number(dict, (char_u *)"col");
1133261f346fSBram Moolenaar 	if (dict_find(dict, (char_u *)"coladd", -1) != NULL)
1134261f346fSBram Moolenaar 	    curwin->w_cursor.coladd = (colnr_T)dict_get_number(dict, (char_u *)"coladd");
1135261f346fSBram Moolenaar 	if (dict_find(dict, (char_u *)"curswant", -1) != NULL)
1136261f346fSBram Moolenaar 	{
1137261f346fSBram Moolenaar 	    curwin->w_curswant = (colnr_T)dict_get_number(dict, (char_u *)"curswant");
1138261f346fSBram Moolenaar 	    curwin->w_set_curswant = FALSE;
1139261f346fSBram Moolenaar 	}
1140261f346fSBram Moolenaar 
1141261f346fSBram Moolenaar 	if (dict_find(dict, (char_u *)"topline", -1) != NULL)
1142261f346fSBram Moolenaar 	    set_topline(curwin, (linenr_T)dict_get_number(dict, (char_u *)"topline"));
1143261f346fSBram Moolenaar #ifdef FEAT_DIFF
1144261f346fSBram Moolenaar 	if (dict_find(dict, (char_u *)"topfill", -1) != NULL)
1145261f346fSBram Moolenaar 	    curwin->w_topfill = (int)dict_get_number(dict, (char_u *)"topfill");
1146261f346fSBram Moolenaar #endif
1147261f346fSBram Moolenaar 	if (dict_find(dict, (char_u *)"leftcol", -1) != NULL)
1148261f346fSBram Moolenaar 	    curwin->w_leftcol = (colnr_T)dict_get_number(dict, (char_u *)"leftcol");
1149261f346fSBram Moolenaar 	if (dict_find(dict, (char_u *)"skipcol", -1) != NULL)
1150261f346fSBram Moolenaar 	    curwin->w_skipcol = (colnr_T)dict_get_number(dict, (char_u *)"skipcol");
1151261f346fSBram Moolenaar 
1152261f346fSBram Moolenaar 	check_cursor();
1153261f346fSBram Moolenaar 	win_new_height(curwin, curwin->w_height);
1154261f346fSBram Moolenaar 	win_new_width(curwin, curwin->w_width);
1155261f346fSBram Moolenaar 	changed_window_setting();
1156261f346fSBram Moolenaar 
1157261f346fSBram Moolenaar 	if (curwin->w_topline <= 0)
1158261f346fSBram Moolenaar 	    curwin->w_topline = 1;
1159261f346fSBram Moolenaar 	if (curwin->w_topline > curbuf->b_ml.ml_line_count)
1160261f346fSBram Moolenaar 	    curwin->w_topline = curbuf->b_ml.ml_line_count;
1161261f346fSBram Moolenaar #ifdef FEAT_DIFF
1162261f346fSBram Moolenaar 	check_topfill(curwin, TRUE);
1163261f346fSBram Moolenaar #endif
1164261f346fSBram Moolenaar     }
1165261f346fSBram Moolenaar }
1166261f346fSBram Moolenaar 
1167261f346fSBram Moolenaar /*
1168261f346fSBram Moolenaar  * "winsaveview()" function
1169261f346fSBram Moolenaar  */
1170261f346fSBram Moolenaar     void
f_winsaveview(typval_T * argvars UNUSED,typval_T * rettv)1171261f346fSBram Moolenaar f_winsaveview(typval_T *argvars UNUSED, typval_T *rettv)
1172261f346fSBram Moolenaar {
1173261f346fSBram Moolenaar     dict_T	*dict;
1174261f346fSBram Moolenaar 
1175261f346fSBram Moolenaar     if (rettv_dict_alloc(rettv) == FAIL)
1176261f346fSBram Moolenaar 	return;
1177261f346fSBram Moolenaar     dict = rettv->vval.v_dict;
1178261f346fSBram Moolenaar 
1179261f346fSBram Moolenaar     dict_add_number(dict, "lnum", (long)curwin->w_cursor.lnum);
1180261f346fSBram Moolenaar     dict_add_number(dict, "col", (long)curwin->w_cursor.col);
1181261f346fSBram Moolenaar     dict_add_number(dict, "coladd", (long)curwin->w_cursor.coladd);
1182261f346fSBram Moolenaar     update_curswant();
1183261f346fSBram Moolenaar     dict_add_number(dict, "curswant", (long)curwin->w_curswant);
1184261f346fSBram Moolenaar 
1185261f346fSBram Moolenaar     dict_add_number(dict, "topline", (long)curwin->w_topline);
1186261f346fSBram Moolenaar #ifdef FEAT_DIFF
1187261f346fSBram Moolenaar     dict_add_number(dict, "topfill", (long)curwin->w_topfill);
1188261f346fSBram Moolenaar #endif
1189261f346fSBram Moolenaar     dict_add_number(dict, "leftcol", (long)curwin->w_leftcol);
1190261f346fSBram Moolenaar     dict_add_number(dict, "skipcol", (long)curwin->w_skipcol);
1191261f346fSBram Moolenaar }
1192261f346fSBram Moolenaar 
1193261f346fSBram Moolenaar /*
1194261f346fSBram Moolenaar  * "winwidth(nr)" function
1195261f346fSBram Moolenaar  */
1196261f346fSBram Moolenaar     void
f_winwidth(typval_T * argvars,typval_T * rettv)1197261f346fSBram Moolenaar f_winwidth(typval_T *argvars, typval_T *rettv)
1198261f346fSBram Moolenaar {
1199261f346fSBram Moolenaar     win_T	*wp;
1200261f346fSBram Moolenaar 
12014490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
12024490ec4eSYegappan Lakshmanan 	return;
12034490ec4eSYegappan Lakshmanan 
1204261f346fSBram Moolenaar     wp = find_win_by_nr_or_id(&argvars[0]);
1205261f346fSBram Moolenaar     if (wp == NULL)
1206261f346fSBram Moolenaar 	rettv->vval.v_number = -1;
1207261f346fSBram Moolenaar     else
1208261f346fSBram Moolenaar 	rettv->vval.v_number = wp->w_width;
1209261f346fSBram Moolenaar }
1210261f346fSBram Moolenaar #endif // FEAT_EVAL
1211261f346fSBram Moolenaar 
1212261f346fSBram Moolenaar #if defined(FEAT_EVAL) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \
1213261f346fSBram Moolenaar 	|| defined(PROTO)
1214261f346fSBram Moolenaar /*
1215261f346fSBram Moolenaar  * Set "win" to be the curwin and "tp" to be the current tab page.
1216261f346fSBram Moolenaar  * restore_win() MUST be called to undo, also when FAIL is returned.
1217261f346fSBram Moolenaar  * No autocommands will be executed until restore_win() is called.
1218261f346fSBram Moolenaar  * When "no_display" is TRUE the display won't be affected, no redraw is
1219261f346fSBram Moolenaar  * triggered, another tabpage access is limited.
1220261f346fSBram Moolenaar  * Returns FAIL if switching to "win" failed.
1221261f346fSBram Moolenaar  */
1222261f346fSBram Moolenaar     int
switch_win(win_T ** save_curwin,tabpage_T ** save_curtab,win_T * win,tabpage_T * tp,int no_display)1223261f346fSBram Moolenaar switch_win(
1224261f346fSBram Moolenaar     win_T	**save_curwin,
1225261f346fSBram Moolenaar     tabpage_T	**save_curtab,
1226261f346fSBram Moolenaar     win_T	*win,
1227261f346fSBram Moolenaar     tabpage_T	*tp,
1228261f346fSBram Moolenaar     int		no_display)
1229261f346fSBram Moolenaar {
1230261f346fSBram Moolenaar     block_autocmds();
1231261f346fSBram Moolenaar     return switch_win_noblock(save_curwin, save_curtab, win, tp, no_display);
1232261f346fSBram Moolenaar }
1233261f346fSBram Moolenaar 
1234261f346fSBram Moolenaar /*
1235261f346fSBram Moolenaar  * As switch_win() but without blocking autocommands.
1236261f346fSBram Moolenaar  */
1237261f346fSBram Moolenaar     int
switch_win_noblock(win_T ** save_curwin,tabpage_T ** save_curtab,win_T * win,tabpage_T * tp,int no_display)1238261f346fSBram Moolenaar switch_win_noblock(
1239261f346fSBram Moolenaar     win_T	**save_curwin,
1240261f346fSBram Moolenaar     tabpage_T	**save_curtab,
1241261f346fSBram Moolenaar     win_T	*win,
1242261f346fSBram Moolenaar     tabpage_T	*tp,
1243261f346fSBram Moolenaar     int		no_display)
1244261f346fSBram Moolenaar {
1245261f346fSBram Moolenaar     *save_curwin = curwin;
1246261f346fSBram Moolenaar     if (tp != NULL)
1247261f346fSBram Moolenaar     {
1248261f346fSBram Moolenaar 	*save_curtab = curtab;
1249261f346fSBram Moolenaar 	if (no_display)
1250261f346fSBram Moolenaar 	{
1251261f346fSBram Moolenaar 	    curtab->tp_firstwin = firstwin;
1252261f346fSBram Moolenaar 	    curtab->tp_lastwin = lastwin;
1253261f346fSBram Moolenaar 	    curtab = tp;
1254261f346fSBram Moolenaar 	    firstwin = curtab->tp_firstwin;
1255261f346fSBram Moolenaar 	    lastwin = curtab->tp_lastwin;
1256261f346fSBram Moolenaar 	}
1257261f346fSBram Moolenaar 	else
1258261f346fSBram Moolenaar 	    goto_tabpage_tp(tp, FALSE, FALSE);
1259261f346fSBram Moolenaar     }
1260261f346fSBram Moolenaar     if (!win_valid(win))
1261261f346fSBram Moolenaar 	return FAIL;
1262261f346fSBram Moolenaar     curwin = win;
1263261f346fSBram Moolenaar     curbuf = curwin->w_buffer;
1264261f346fSBram Moolenaar     return OK;
1265261f346fSBram Moolenaar }
1266261f346fSBram Moolenaar 
1267261f346fSBram Moolenaar /*
1268261f346fSBram Moolenaar  * Restore current tabpage and window saved by switch_win(), if still valid.
1269261f346fSBram Moolenaar  * When "no_display" is TRUE the display won't be affected, no redraw is
1270261f346fSBram Moolenaar  * triggered.
1271261f346fSBram Moolenaar  */
1272261f346fSBram Moolenaar     void
restore_win(win_T * save_curwin,tabpage_T * save_curtab,int no_display)1273261f346fSBram Moolenaar restore_win(
1274261f346fSBram Moolenaar     win_T	*save_curwin,
1275261f346fSBram Moolenaar     tabpage_T	*save_curtab,
1276261f346fSBram Moolenaar     int		no_display)
1277261f346fSBram Moolenaar {
1278261f346fSBram Moolenaar     restore_win_noblock(save_curwin, save_curtab, no_display);
1279261f346fSBram Moolenaar     unblock_autocmds();
1280261f346fSBram Moolenaar }
1281261f346fSBram Moolenaar 
1282261f346fSBram Moolenaar /*
1283261f346fSBram Moolenaar  * As restore_win() but without unblocking autocommands.
1284261f346fSBram Moolenaar  */
1285261f346fSBram Moolenaar     void
restore_win_noblock(win_T * save_curwin,tabpage_T * save_curtab,int no_display)1286261f346fSBram Moolenaar restore_win_noblock(
1287261f346fSBram Moolenaar     win_T	*save_curwin,
1288261f346fSBram Moolenaar     tabpage_T	*save_curtab,
1289261f346fSBram Moolenaar     int		no_display)
1290261f346fSBram Moolenaar {
1291261f346fSBram Moolenaar     if (save_curtab != NULL && valid_tabpage(save_curtab))
1292261f346fSBram Moolenaar     {
1293261f346fSBram Moolenaar 	if (no_display)
1294261f346fSBram Moolenaar 	{
1295261f346fSBram Moolenaar 	    curtab->tp_firstwin = firstwin;
1296261f346fSBram Moolenaar 	    curtab->tp_lastwin = lastwin;
1297261f346fSBram Moolenaar 	    curtab = save_curtab;
1298261f346fSBram Moolenaar 	    firstwin = curtab->tp_firstwin;
1299261f346fSBram Moolenaar 	    lastwin = curtab->tp_lastwin;
1300261f346fSBram Moolenaar 	}
1301261f346fSBram Moolenaar 	else
1302261f346fSBram Moolenaar 	    goto_tabpage_tp(save_curtab, FALSE, FALSE);
1303261f346fSBram Moolenaar     }
1304261f346fSBram Moolenaar     if (win_valid(save_curwin))
1305261f346fSBram Moolenaar     {
1306261f346fSBram Moolenaar 	curwin = save_curwin;
1307261f346fSBram Moolenaar 	curbuf = curwin->w_buffer;
1308261f346fSBram Moolenaar     }
130905ad5ff0SBram Moolenaar # ifdef FEAT_PROP_POPUP
1310261f346fSBram Moolenaar     else if (WIN_IS_POPUP(curwin))
1311261f346fSBram Moolenaar 	// original window was closed and now we're in a popup window: Go
1312261f346fSBram Moolenaar 	// to the first valid window.
1313261f346fSBram Moolenaar 	win_goto(firstwin);
1314261f346fSBram Moolenaar # endif
13157f13b24aSBram Moolenaar 
13167f13b24aSBram Moolenaar     // If called by win_execute() and executing the command changed the
13177f13b24aSBram Moolenaar     // directory, it now has to be restored.
13187f13b24aSBram Moolenaar     fix_current_dir();
1319261f346fSBram Moolenaar }
1320261f346fSBram Moolenaar #endif
1321