Mercurial > vim
comparison src/evalwindow.c @ 18010:cf8e0c7e0cb9 v8.1.2001
patch 8.1.2001: some source files are too big
Commit: https://github.com/vim/vim/commit/261f346f8154c0ec7094a4a211c653c74e9f7c2e
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Sep 7 15:45:32 2019 +0200
patch 8.1.2001: some source files are too big
Problem: Some source files are too big.
Solution: Move buffer and window related functions to evalbuffer.c and
evalwindow.c. (Yegappan Lakshmanan, closes #4898)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 07 Sep 2019 16:00:03 +0200 |
parents | |
children | a9f1656f13c9 |
comparison
equal
deleted
inserted
replaced
18009:40255308856f | 18010:cf8e0c7e0cb9 |
---|---|
1 /* vi:set ts=8 sts=4 sw=4 noet: | |
2 * | |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * | |
5 * Do ":help uganda" in Vim to read copying and usage conditions. | |
6 * Do ":help credits" in Vim to see a list of people who contributed. | |
7 * See README.txt for an overview of the Vim source code. | |
8 */ | |
9 | |
10 /* | |
11 * evalwindow.c: Window related builtin functions | |
12 */ | |
13 | |
14 #include "vim.h" | |
15 | |
16 #if defined(FEAT_EVAL) || defined(PROTO) | |
17 | |
18 static int | |
19 win_getid(typval_T *argvars) | |
20 { | |
21 int winnr; | |
22 win_T *wp; | |
23 | |
24 if (argvars[0].v_type == VAR_UNKNOWN) | |
25 return curwin->w_id; | |
26 winnr = tv_get_number(&argvars[0]); | |
27 if (winnr > 0) | |
28 { | |
29 if (argvars[1].v_type == VAR_UNKNOWN) | |
30 wp = firstwin; | |
31 else | |
32 { | |
33 tabpage_T *tp; | |
34 int tabnr = tv_get_number(&argvars[1]); | |
35 | |
36 FOR_ALL_TABPAGES(tp) | |
37 if (--tabnr == 0) | |
38 break; | |
39 if (tp == NULL) | |
40 return -1; | |
41 if (tp == curtab) | |
42 wp = firstwin; | |
43 else | |
44 wp = tp->tp_firstwin; | |
45 } | |
46 for ( ; wp != NULL; wp = wp->w_next) | |
47 if (--winnr == 0) | |
48 return wp->w_id; | |
49 } | |
50 return 0; | |
51 } | |
52 | |
53 static int | |
54 win_gotoid(typval_T *argvars) | |
55 { | |
56 win_T *wp; | |
57 tabpage_T *tp; | |
58 int id = tv_get_number(&argvars[0]); | |
59 | |
60 FOR_ALL_TAB_WINDOWS(tp, wp) | |
61 if (wp->w_id == id) | |
62 { | |
63 goto_tabpage_win(tp, wp); | |
64 return 1; | |
65 } | |
66 return 0; | |
67 } | |
68 | |
69 static void | |
70 win_id2tabwin(typval_T *argvars, list_T *list) | |
71 { | |
72 win_T *wp; | |
73 tabpage_T *tp; | |
74 int winnr = 1; | |
75 int tabnr = 1; | |
76 int id = tv_get_number(&argvars[0]); | |
77 | |
78 FOR_ALL_TABPAGES(tp) | |
79 { | |
80 FOR_ALL_WINDOWS_IN_TAB(tp, wp) | |
81 { | |
82 if (wp->w_id == id) | |
83 { | |
84 list_append_number(list, tabnr); | |
85 list_append_number(list, winnr); | |
86 return; | |
87 } | |
88 ++winnr; | |
89 } | |
90 ++tabnr; | |
91 winnr = 1; | |
92 } | |
93 list_append_number(list, 0); | |
94 list_append_number(list, 0); | |
95 } | |
96 | |
97 /* | |
98 * Return the window pointer of window "id". | |
99 */ | |
100 win_T * | |
101 win_id2wp(int id) | |
102 { | |
103 return win_id2wp_tp(id, NULL); | |
104 } | |
105 | |
106 /* | |
107 * Return the window and tab pointer of window "id". | |
108 */ | |
109 win_T * | |
110 win_id2wp_tp(int id, tabpage_T **tpp) | |
111 { | |
112 win_T *wp; | |
113 tabpage_T *tp; | |
114 | |
115 FOR_ALL_TAB_WINDOWS(tp, wp) | |
116 if (wp->w_id == id) | |
117 { | |
118 if (tpp != NULL) | |
119 *tpp = tp; | |
120 return wp; | |
121 } | |
122 #ifdef FEAT_TEXT_PROP | |
123 // popup windows are in separate lists | |
124 FOR_ALL_TABPAGES(tp) | |
125 for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) | |
126 if (wp->w_id == id) | |
127 { | |
128 if (tpp != NULL) | |
129 *tpp = tp; | |
130 return wp; | |
131 } | |
132 for (wp = first_popupwin; wp != NULL; wp = wp->w_next) | |
133 if (wp->w_id == id) | |
134 { | |
135 if (tpp != NULL) | |
136 *tpp = tp; | |
137 return wp; | |
138 } | |
139 #endif | |
140 | |
141 return NULL; | |
142 } | |
143 | |
144 static int | |
145 win_id2win(typval_T *argvars) | |
146 { | |
147 win_T *wp; | |
148 int nr = 1; | |
149 int id = tv_get_number(&argvars[0]); | |
150 | |
151 FOR_ALL_WINDOWS(wp) | |
152 { | |
153 if (wp->w_id == id) | |
154 return nr; | |
155 ++nr; | |
156 } | |
157 return 0; | |
158 } | |
159 | |
160 void | |
161 win_findbuf(typval_T *argvars, list_T *list) | |
162 { | |
163 win_T *wp; | |
164 tabpage_T *tp; | |
165 int bufnr = tv_get_number(&argvars[0]); | |
166 | |
167 FOR_ALL_TAB_WINDOWS(tp, wp) | |
168 if (wp->w_buffer->b_fnum == bufnr) | |
169 list_append_number(list, wp->w_id); | |
170 } | |
171 | |
172 /* | |
173 * Find window specified by "vp" in tabpage "tp". | |
174 */ | |
175 win_T * | |
176 find_win_by_nr( | |
177 typval_T *vp, | |
178 tabpage_T *tp) // NULL for current tab page | |
179 { | |
180 win_T *wp; | |
181 int nr = (int)tv_get_number_chk(vp, NULL); | |
182 | |
183 if (nr < 0) | |
184 return NULL; | |
185 if (nr == 0) | |
186 return curwin; | |
187 | |
188 FOR_ALL_WINDOWS_IN_TAB(tp, wp) | |
189 { | |
190 if (nr >= LOWEST_WIN_ID) | |
191 { | |
192 if (wp->w_id == nr) | |
193 return wp; | |
194 } | |
195 else if (--nr <= 0) | |
196 break; | |
197 } | |
198 if (nr >= LOWEST_WIN_ID) | |
199 { | |
200 #ifdef FEAT_TEXT_PROP | |
201 // check tab-local popup windows | |
202 for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) | |
203 if (wp->w_id == nr) | |
204 return wp; | |
205 // check global popup windows | |
206 for (wp = first_popupwin; wp != NULL; wp = wp->w_next) | |
207 if (wp->w_id == nr) | |
208 return wp; | |
209 #endif | |
210 return NULL; | |
211 } | |
212 return wp; | |
213 } | |
214 | |
215 /* | |
216 * Find a window: When using a Window ID in any tab page, when using a number | |
217 * in the current tab page. | |
218 */ | |
219 win_T * | |
220 find_win_by_nr_or_id(typval_T *vp) | |
221 { | |
222 int nr = (int)tv_get_number_chk(vp, NULL); | |
223 | |
224 if (nr >= LOWEST_WIN_ID) | |
225 return win_id2wp(tv_get_number(vp)); | |
226 return find_win_by_nr(vp, NULL); | |
227 } | |
228 | |
229 /* | |
230 * Find window specified by "wvp" in tabpage "tvp". | |
231 * Returns the tab page in 'ptp' | |
232 */ | |
233 win_T * | |
234 find_tabwin( | |
235 typval_T *wvp, // VAR_UNKNOWN for current window | |
236 typval_T *tvp, // VAR_UNKNOWN for current tab page | |
237 tabpage_T **ptp) | |
238 { | |
239 win_T *wp = NULL; | |
240 tabpage_T *tp = NULL; | |
241 long n; | |
242 | |
243 if (wvp->v_type != VAR_UNKNOWN) | |
244 { | |
245 if (tvp->v_type != VAR_UNKNOWN) | |
246 { | |
247 n = (long)tv_get_number(tvp); | |
248 if (n >= 0) | |
249 tp = find_tabpage(n); | |
250 } | |
251 else | |
252 tp = curtab; | |
253 | |
254 if (tp != NULL) | |
255 { | |
256 wp = find_win_by_nr(wvp, tp); | |
257 if (wp == NULL && wvp->v_type == VAR_NUMBER | |
258 && wvp->vval.v_number != -1) | |
259 // A window with the specified number is not found | |
260 tp = NULL; | |
261 } | |
262 } | |
263 else | |
264 { | |
265 wp = curwin; | |
266 tp = curtab; | |
267 } | |
268 | |
269 if (ptp != NULL) | |
270 *ptp = tp; | |
271 | |
272 return wp; | |
273 } | |
274 | |
275 /* | |
276 * Get the layout of the given tab page for winlayout(). | |
277 */ | |
278 static void | |
279 get_framelayout(frame_T *fr, list_T *l, int outer) | |
280 { | |
281 frame_T *child; | |
282 list_T *fr_list; | |
283 list_T *win_list; | |
284 | |
285 if (fr == NULL) | |
286 return; | |
287 | |
288 if (outer) | |
289 // outermost call from f_winlayout() | |
290 fr_list = l; | |
291 else | |
292 { | |
293 fr_list = list_alloc(); | |
294 if (fr_list == NULL) | |
295 return; | |
296 list_append_list(l, fr_list); | |
297 } | |
298 | |
299 if (fr->fr_layout == FR_LEAF) | |
300 { | |
301 if (fr->fr_win != NULL) | |
302 { | |
303 list_append_string(fr_list, (char_u *)"leaf", -1); | |
304 list_append_number(fr_list, fr->fr_win->w_id); | |
305 } | |
306 } | |
307 else | |
308 { | |
309 list_append_string(fr_list, | |
310 fr->fr_layout == FR_ROW ? (char_u *)"row" : (char_u *)"col", -1); | |
311 | |
312 win_list = list_alloc(); | |
313 if (win_list == NULL) | |
314 return; | |
315 list_append_list(fr_list, win_list); | |
316 child = fr->fr_child; | |
317 while (child != NULL) | |
318 { | |
319 get_framelayout(child, win_list, FALSE); | |
320 child = child->fr_next; | |
321 } | |
322 } | |
323 } | |
324 | |
325 /* | |
326 * Common code for tabpagewinnr() and winnr(). | |
327 */ | |
328 static int | |
329 get_winnr(tabpage_T *tp, typval_T *argvar) | |
330 { | |
331 win_T *twin; | |
332 int nr = 1; | |
333 win_T *wp; | |
334 char_u *arg; | |
335 | |
336 twin = (tp == curtab) ? curwin : tp->tp_curwin; | |
337 if (argvar->v_type != VAR_UNKNOWN) | |
338 { | |
339 int invalid_arg = FALSE; | |
340 | |
341 arg = tv_get_string_chk(argvar); | |
342 if (arg == NULL) | |
343 nr = 0; // type error; errmsg already given | |
344 else if (STRCMP(arg, "$") == 0) | |
345 twin = (tp == curtab) ? lastwin : tp->tp_lastwin; | |
346 else if (STRCMP(arg, "#") == 0) | |
347 { | |
348 twin = (tp == curtab) ? prevwin : tp->tp_prevwin; | |
349 if (twin == NULL) | |
350 nr = 0; | |
351 } | |
352 else | |
353 { | |
354 long count; | |
355 char_u *endp; | |
356 | |
357 // Extract the window count (if specified). e.g. winnr('3j') | |
358 count = strtol((char *)arg, (char **)&endp, 10); | |
359 if (count <= 0) | |
360 count = 1; // if count is not specified, default to 1 | |
361 if (endp != NULL && *endp != '\0') | |
362 { | |
363 if (STRCMP(endp, "j") == 0) | |
364 twin = win_vert_neighbor(tp, twin, FALSE, count); | |
365 else if (STRCMP(endp, "k") == 0) | |
366 twin = win_vert_neighbor(tp, twin, TRUE, count); | |
367 else if (STRCMP(endp, "h") == 0) | |
368 twin = win_horz_neighbor(tp, twin, TRUE, count); | |
369 else if (STRCMP(endp, "l") == 0) | |
370 twin = win_horz_neighbor(tp, twin, FALSE, count); | |
371 else | |
372 invalid_arg = TRUE; | |
373 } | |
374 else | |
375 invalid_arg = TRUE; | |
376 } | |
377 | |
378 if (invalid_arg) | |
379 { | |
380 semsg(_(e_invexpr2), arg); | |
381 nr = 0; | |
382 } | |
383 } | |
384 | |
385 if (nr > 0) | |
386 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; | |
387 wp != twin; wp = wp->w_next) | |
388 { | |
389 if (wp == NULL) | |
390 { | |
391 // didn't find it in this tabpage | |
392 nr = 0; | |
393 break; | |
394 } | |
395 ++nr; | |
396 } | |
397 return nr; | |
398 } | |
399 | |
400 /* | |
401 * Returns information about a window as a dictionary. | |
402 */ | |
403 static dict_T * | |
404 get_win_info(win_T *wp, short tpnr, short winnr) | |
405 { | |
406 dict_T *dict; | |
407 | |
408 dict = dict_alloc(); | |
409 if (dict == NULL) | |
410 return NULL; | |
411 | |
412 dict_add_number(dict, "tabnr", tpnr); | |
413 dict_add_number(dict, "winnr", winnr); | |
414 dict_add_number(dict, "winid", wp->w_id); | |
415 dict_add_number(dict, "height", wp->w_height); | |
416 dict_add_number(dict, "winrow", wp->w_winrow + 1); | |
417 dict_add_number(dict, "topline", wp->w_topline); | |
418 dict_add_number(dict, "botline", wp->w_botline - 1); | |
419 #ifdef FEAT_MENU | |
420 dict_add_number(dict, "winbar", wp->w_winbar_height); | |
421 #endif | |
422 dict_add_number(dict, "width", wp->w_width); | |
423 dict_add_number(dict, "wincol", wp->w_wincol + 1); | |
424 dict_add_number(dict, "bufnr", wp->w_buffer->b_fnum); | |
425 | |
426 #ifdef FEAT_TERMINAL | |
427 dict_add_number(dict, "terminal", bt_terminal(wp->w_buffer)); | |
428 #endif | |
429 #ifdef FEAT_QUICKFIX | |
430 dict_add_number(dict, "quickfix", bt_quickfix(wp->w_buffer)); | |
431 dict_add_number(dict, "loclist", | |
432 (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)); | |
433 #endif | |
434 | |
435 // Add a reference to window variables | |
436 dict_add_dict(dict, "variables", wp->w_vars); | |
437 | |
438 return dict; | |
439 } | |
440 | |
441 /* | |
442 * Returns information (variables, options, etc.) about a tab page | |
443 * as a dictionary. | |
444 */ | |
445 static dict_T * | |
446 get_tabpage_info(tabpage_T *tp, int tp_idx) | |
447 { | |
448 win_T *wp; | |
449 dict_T *dict; | |
450 list_T *l; | |
451 | |
452 dict = dict_alloc(); | |
453 if (dict == NULL) | |
454 return NULL; | |
455 | |
456 dict_add_number(dict, "tabnr", tp_idx); | |
457 | |
458 l = list_alloc(); | |
459 if (l != NULL) | |
460 { | |
461 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; | |
462 wp != NULL; wp = wp->w_next) | |
463 list_append_number(l, (varnumber_T)wp->w_id); | |
464 dict_add_list(dict, "windows", l); | |
465 } | |
466 | |
467 // Make a reference to tabpage variables | |
468 dict_add_dict(dict, "variables", tp->tp_vars); | |
469 | |
470 return dict; | |
471 } | |
472 | |
473 /* | |
474 * "gettabinfo()" function | |
475 */ | |
476 void | |
477 f_gettabinfo(typval_T *argvars, typval_T *rettv) | |
478 { | |
479 tabpage_T *tp, *tparg = NULL; | |
480 dict_T *d; | |
481 int tpnr = 0; | |
482 | |
483 if (rettv_list_alloc(rettv) != OK) | |
484 return; | |
485 | |
486 if (argvars[0].v_type != VAR_UNKNOWN) | |
487 { | |
488 // Information about one tab page | |
489 tparg = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); | |
490 if (tparg == NULL) | |
491 return; | |
492 } | |
493 | |
494 // Get information about a specific tab page or all tab pages | |
495 FOR_ALL_TABPAGES(tp) | |
496 { | |
497 tpnr++; | |
498 if (tparg != NULL && tp != tparg) | |
499 continue; | |
500 d = get_tabpage_info(tp, tpnr); | |
501 if (d != NULL) | |
502 list_append_dict(rettv->vval.v_list, d); | |
503 if (tparg != NULL) | |
504 return; | |
505 } | |
506 } | |
507 | |
508 /* | |
509 * "getwininfo()" function | |
510 */ | |
511 void | |
512 f_getwininfo(typval_T *argvars, typval_T *rettv) | |
513 { | |
514 tabpage_T *tp; | |
515 win_T *wp = NULL, *wparg = NULL; | |
516 dict_T *d; | |
517 short tabnr = 0, winnr; | |
518 | |
519 if (rettv_list_alloc(rettv) != OK) | |
520 return; | |
521 | |
522 if (argvars[0].v_type != VAR_UNKNOWN) | |
523 { | |
524 wparg = win_id2wp(tv_get_number(&argvars[0])); | |
525 if (wparg == NULL) | |
526 return; | |
527 } | |
528 | |
529 // Collect information about either all the windows across all the tab | |
530 // pages or one particular window. | |
531 FOR_ALL_TABPAGES(tp) | |
532 { | |
533 tabnr++; | |
534 winnr = 0; | |
535 FOR_ALL_WINDOWS_IN_TAB(tp, wp) | |
536 { | |
537 winnr++; | |
538 if (wparg != NULL && wp != wparg) | |
539 continue; | |
540 d = get_win_info(wp, tabnr, winnr); | |
541 if (d != NULL) | |
542 list_append_dict(rettv->vval.v_list, d); | |
543 if (wparg != NULL) | |
544 // found information about a specific window | |
545 return; | |
546 } | |
547 } | |
548 } | |
549 | |
550 /* | |
551 * "getwinpos({timeout})" function | |
552 */ | |
553 void | |
554 f_getwinpos(typval_T *argvars UNUSED, typval_T *rettv) | |
555 { | |
556 int x = -1; | |
557 int y = -1; | |
558 | |
559 if (rettv_list_alloc(rettv) == FAIL) | |
560 return; | |
561 #if defined(FEAT_GUI) \ | |
562 || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \ | |
563 || defined(MSWIN) | |
564 { | |
565 varnumber_T timeout = 100; | |
566 | |
567 if (argvars[0].v_type != VAR_UNKNOWN) | |
568 timeout = tv_get_number(&argvars[0]); | |
569 | |
570 (void)ui_get_winpos(&x, &y, timeout); | |
571 } | |
572 #endif | |
573 list_append_number(rettv->vval.v_list, (varnumber_T)x); | |
574 list_append_number(rettv->vval.v_list, (varnumber_T)y); | |
575 } | |
576 | |
577 | |
578 /* | |
579 * "getwinposx()" function | |
580 */ | |
581 void | |
582 f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv) | |
583 { | |
584 rettv->vval.v_number = -1; | |
585 #if defined(FEAT_GUI) \ | |
586 || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \ | |
587 || defined(MSWIN) | |
588 | |
589 { | |
590 int x, y; | |
591 | |
592 if (ui_get_winpos(&x, &y, 100) == OK) | |
593 rettv->vval.v_number = x; | |
594 } | |
595 #endif | |
596 } | |
597 | |
598 /* | |
599 * "getwinposy()" function | |
600 */ | |
601 void | |
602 f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv) | |
603 { | |
604 rettv->vval.v_number = -1; | |
605 #if defined(FEAT_GUI) \ | |
606 || (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)) \ | |
607 || defined(MSWIN) | |
608 { | |
609 int x, y; | |
610 | |
611 if (ui_get_winpos(&x, &y, 100) == OK) | |
612 rettv->vval.v_number = y; | |
613 } | |
614 #endif | |
615 } | |
616 | |
617 /* | |
618 * "tabpagenr()" function | |
619 */ | |
620 void | |
621 f_tabpagenr(typval_T *argvars UNUSED, typval_T *rettv) | |
622 { | |
623 int nr = 1; | |
624 char_u *arg; | |
625 | |
626 if (argvars[0].v_type != VAR_UNKNOWN) | |
627 { | |
628 arg = tv_get_string_chk(&argvars[0]); | |
629 nr = 0; | |
630 if (arg != NULL) | |
631 { | |
632 if (STRCMP(arg, "$") == 0) | |
633 nr = tabpage_index(NULL) - 1; | |
634 else | |
635 semsg(_(e_invexpr2), arg); | |
636 } | |
637 } | |
638 else | |
639 nr = tabpage_index(curtab); | |
640 rettv->vval.v_number = nr; | |
641 } | |
642 | |
643 /* | |
644 * "tabpagewinnr()" function | |
645 */ | |
646 void | |
647 f_tabpagewinnr(typval_T *argvars UNUSED, typval_T *rettv) | |
648 { | |
649 int nr = 1; | |
650 tabpage_T *tp; | |
651 | |
652 tp = find_tabpage((int)tv_get_number(&argvars[0])); | |
653 if (tp == NULL) | |
654 nr = 0; | |
655 else | |
656 nr = get_winnr(tp, &argvars[1]); | |
657 rettv->vval.v_number = nr; | |
658 } | |
659 | |
660 /* | |
661 * "win_execute()" function | |
662 */ | |
663 void | |
664 f_win_execute(typval_T *argvars, typval_T *rettv) | |
665 { | |
666 int id = (int)tv_get_number(argvars); | |
667 tabpage_T *tp; | |
668 win_T *wp = win_id2wp_tp(id, &tp); | |
669 win_T *save_curwin; | |
670 tabpage_T *save_curtab; | |
671 | |
672 if (wp != NULL && tp != NULL) | |
673 { | |
674 if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, TRUE) == OK) | |
675 { | |
676 check_cursor(); | |
677 execute_common(argvars, rettv, 1); | |
678 } | |
679 restore_win_noblock(save_curwin, save_curtab, TRUE); | |
680 } | |
681 } | |
682 | |
683 /* | |
684 * "win_findbuf()" function | |
685 */ | |
686 void | |
687 f_win_findbuf(typval_T *argvars, typval_T *rettv) | |
688 { | |
689 if (rettv_list_alloc(rettv) != FAIL) | |
690 win_findbuf(argvars, rettv->vval.v_list); | |
691 } | |
692 | |
693 /* | |
694 * "win_getid()" function | |
695 */ | |
696 void | |
697 f_win_getid(typval_T *argvars, typval_T *rettv) | |
698 { | |
699 rettv->vval.v_number = win_getid(argvars); | |
700 } | |
701 | |
702 /* | |
703 * "win_gotoid()" function | |
704 */ | |
705 void | |
706 f_win_gotoid(typval_T *argvars, typval_T *rettv) | |
707 { | |
708 rettv->vval.v_number = win_gotoid(argvars); | |
709 } | |
710 | |
711 /* | |
712 * "win_id2tabwin()" function | |
713 */ | |
714 void | |
715 f_win_id2tabwin(typval_T *argvars, typval_T *rettv) | |
716 { | |
717 if (rettv_list_alloc(rettv) != FAIL) | |
718 win_id2tabwin(argvars, rettv->vval.v_list); | |
719 } | |
720 | |
721 /* | |
722 * "win_id2win()" function | |
723 */ | |
724 void | |
725 f_win_id2win(typval_T *argvars, typval_T *rettv) | |
726 { | |
727 rettv->vval.v_number = win_id2win(argvars); | |
728 } | |
729 | |
730 /* | |
731 * "win_screenpos()" function | |
732 */ | |
733 void | |
734 f_win_screenpos(typval_T *argvars, typval_T *rettv) | |
735 { | |
736 win_T *wp; | |
737 | |
738 if (rettv_list_alloc(rettv) == FAIL) | |
739 return; | |
740 | |
741 wp = find_win_by_nr_or_id(&argvars[0]); | |
742 list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_winrow + 1); | |
743 list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_wincol + 1); | |
744 } | |
745 | |
746 /* | |
747 * "winbufnr(nr)" function | |
748 */ | |
749 void | |
750 f_winbufnr(typval_T *argvars, typval_T *rettv) | |
751 { | |
752 win_T *wp; | |
753 | |
754 wp = find_win_by_nr_or_id(&argvars[0]); | |
755 if (wp == NULL) | |
756 rettv->vval.v_number = -1; | |
757 else | |
758 rettv->vval.v_number = wp->w_buffer->b_fnum; | |
759 } | |
760 | |
761 /* | |
762 * "wincol()" function | |
763 */ | |
764 void | |
765 f_wincol(typval_T *argvars UNUSED, typval_T *rettv) | |
766 { | |
767 validate_cursor(); | |
768 rettv->vval.v_number = curwin->w_wcol + 1; | |
769 } | |
770 | |
771 /* | |
772 * "winheight(nr)" function | |
773 */ | |
774 void | |
775 f_winheight(typval_T *argvars, typval_T *rettv) | |
776 { | |
777 win_T *wp; | |
778 | |
779 wp = find_win_by_nr_or_id(&argvars[0]); | |
780 if (wp == NULL) | |
781 rettv->vval.v_number = -1; | |
782 else | |
783 rettv->vval.v_number = wp->w_height; | |
784 } | |
785 | |
786 /* | |
787 * "winlayout()" function | |
788 */ | |
789 void | |
790 f_winlayout(typval_T *argvars, typval_T *rettv) | |
791 { | |
792 tabpage_T *tp; | |
793 | |
794 if (rettv_list_alloc(rettv) != OK) | |
795 return; | |
796 | |
797 if (argvars[0].v_type == VAR_UNKNOWN) | |
798 tp = curtab; | |
799 else | |
800 { | |
801 tp = find_tabpage((int)tv_get_number(&argvars[0])); | |
802 if (tp == NULL) | |
803 return; | |
804 } | |
805 | |
806 get_framelayout(tp->tp_topframe, rettv->vval.v_list, TRUE); | |
807 } | |
808 | |
809 /* | |
810 * "winline()" function | |
811 */ | |
812 void | |
813 f_winline(typval_T *argvars UNUSED, typval_T *rettv) | |
814 { | |
815 validate_cursor(); | |
816 rettv->vval.v_number = curwin->w_wrow + 1; | |
817 } | |
818 | |
819 /* | |
820 * "winnr()" function | |
821 */ | |
822 void | |
823 f_winnr(typval_T *argvars UNUSED, typval_T *rettv) | |
824 { | |
825 int nr = 1; | |
826 | |
827 nr = get_winnr(curtab, &argvars[0]); | |
828 rettv->vval.v_number = nr; | |
829 } | |
830 | |
831 /* | |
832 * "winrestcmd()" function | |
833 */ | |
834 void | |
835 f_winrestcmd(typval_T *argvars UNUSED, typval_T *rettv) | |
836 { | |
837 win_T *wp; | |
838 int winnr = 1; | |
839 garray_T ga; | |
840 char_u buf[50]; | |
841 | |
842 ga_init2(&ga, (int)sizeof(char), 70); | |
843 FOR_ALL_WINDOWS(wp) | |
844 { | |
845 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); | |
846 ga_concat(&ga, buf); | |
847 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); | |
848 ga_concat(&ga, buf); | |
849 ++winnr; | |
850 } | |
851 ga_append(&ga, NUL); | |
852 | |
853 rettv->vval.v_string = ga.ga_data; | |
854 rettv->v_type = VAR_STRING; | |
855 } | |
856 | |
857 /* | |
858 * "winrestview()" function | |
859 */ | |
860 void | |
861 f_winrestview(typval_T *argvars, typval_T *rettv UNUSED) | |
862 { | |
863 dict_T *dict; | |
864 | |
865 if (argvars[0].v_type != VAR_DICT | |
866 || (dict = argvars[0].vval.v_dict) == NULL) | |
867 emsg(_(e_invarg)); | |
868 else | |
869 { | |
870 if (dict_find(dict, (char_u *)"lnum", -1) != NULL) | |
871 curwin->w_cursor.lnum = (linenr_T)dict_get_number(dict, (char_u *)"lnum"); | |
872 if (dict_find(dict, (char_u *)"col", -1) != NULL) | |
873 curwin->w_cursor.col = (colnr_T)dict_get_number(dict, (char_u *)"col"); | |
874 if (dict_find(dict, (char_u *)"coladd", -1) != NULL) | |
875 curwin->w_cursor.coladd = (colnr_T)dict_get_number(dict, (char_u *)"coladd"); | |
876 if (dict_find(dict, (char_u *)"curswant", -1) != NULL) | |
877 { | |
878 curwin->w_curswant = (colnr_T)dict_get_number(dict, (char_u *)"curswant"); | |
879 curwin->w_set_curswant = FALSE; | |
880 } | |
881 | |
882 if (dict_find(dict, (char_u *)"topline", -1) != NULL) | |
883 set_topline(curwin, (linenr_T)dict_get_number(dict, (char_u *)"topline")); | |
884 #ifdef FEAT_DIFF | |
885 if (dict_find(dict, (char_u *)"topfill", -1) != NULL) | |
886 curwin->w_topfill = (int)dict_get_number(dict, (char_u *)"topfill"); | |
887 #endif | |
888 if (dict_find(dict, (char_u *)"leftcol", -1) != NULL) | |
889 curwin->w_leftcol = (colnr_T)dict_get_number(dict, (char_u *)"leftcol"); | |
890 if (dict_find(dict, (char_u *)"skipcol", -1) != NULL) | |
891 curwin->w_skipcol = (colnr_T)dict_get_number(dict, (char_u *)"skipcol"); | |
892 | |
893 check_cursor(); | |
894 win_new_height(curwin, curwin->w_height); | |
895 win_new_width(curwin, curwin->w_width); | |
896 changed_window_setting(); | |
897 | |
898 if (curwin->w_topline <= 0) | |
899 curwin->w_topline = 1; | |
900 if (curwin->w_topline > curbuf->b_ml.ml_line_count) | |
901 curwin->w_topline = curbuf->b_ml.ml_line_count; | |
902 #ifdef FEAT_DIFF | |
903 check_topfill(curwin, TRUE); | |
904 #endif | |
905 } | |
906 } | |
907 | |
908 /* | |
909 * "winsaveview()" function | |
910 */ | |
911 void | |
912 f_winsaveview(typval_T *argvars UNUSED, typval_T *rettv) | |
913 { | |
914 dict_T *dict; | |
915 | |
916 if (rettv_dict_alloc(rettv) == FAIL) | |
917 return; | |
918 dict = rettv->vval.v_dict; | |
919 | |
920 dict_add_number(dict, "lnum", (long)curwin->w_cursor.lnum); | |
921 dict_add_number(dict, "col", (long)curwin->w_cursor.col); | |
922 dict_add_number(dict, "coladd", (long)curwin->w_cursor.coladd); | |
923 update_curswant(); | |
924 dict_add_number(dict, "curswant", (long)curwin->w_curswant); | |
925 | |
926 dict_add_number(dict, "topline", (long)curwin->w_topline); | |
927 #ifdef FEAT_DIFF | |
928 dict_add_number(dict, "topfill", (long)curwin->w_topfill); | |
929 #endif | |
930 dict_add_number(dict, "leftcol", (long)curwin->w_leftcol); | |
931 dict_add_number(dict, "skipcol", (long)curwin->w_skipcol); | |
932 } | |
933 | |
934 /* | |
935 * "winwidth(nr)" function | |
936 */ | |
937 void | |
938 f_winwidth(typval_T *argvars, typval_T *rettv) | |
939 { | |
940 win_T *wp; | |
941 | |
942 wp = find_win_by_nr_or_id(&argvars[0]); | |
943 if (wp == NULL) | |
944 rettv->vval.v_number = -1; | |
945 else | |
946 rettv->vval.v_number = wp->w_width; | |
947 } | |
948 #endif // FEAT_EVAL | |
949 | |
950 #if defined(FEAT_EVAL) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \ | |
951 || defined(PROTO) | |
952 /* | |
953 * Set "win" to be the curwin and "tp" to be the current tab page. | |
954 * restore_win() MUST be called to undo, also when FAIL is returned. | |
955 * No autocommands will be executed until restore_win() is called. | |
956 * When "no_display" is TRUE the display won't be affected, no redraw is | |
957 * triggered, another tabpage access is limited. | |
958 * Returns FAIL if switching to "win" failed. | |
959 */ | |
960 int | |
961 switch_win( | |
962 win_T **save_curwin, | |
963 tabpage_T **save_curtab, | |
964 win_T *win, | |
965 tabpage_T *tp, | |
966 int no_display) | |
967 { | |
968 block_autocmds(); | |
969 return switch_win_noblock(save_curwin, save_curtab, win, tp, no_display); | |
970 } | |
971 | |
972 /* | |
973 * As switch_win() but without blocking autocommands. | |
974 */ | |
975 int | |
976 switch_win_noblock( | |
977 win_T **save_curwin, | |
978 tabpage_T **save_curtab, | |
979 win_T *win, | |
980 tabpage_T *tp, | |
981 int no_display) | |
982 { | |
983 *save_curwin = curwin; | |
984 if (tp != NULL) | |
985 { | |
986 *save_curtab = curtab; | |
987 if (no_display) | |
988 { | |
989 curtab->tp_firstwin = firstwin; | |
990 curtab->tp_lastwin = lastwin; | |
991 curtab = tp; | |
992 firstwin = curtab->tp_firstwin; | |
993 lastwin = curtab->tp_lastwin; | |
994 } | |
995 else | |
996 goto_tabpage_tp(tp, FALSE, FALSE); | |
997 } | |
998 if (!win_valid(win)) | |
999 return FAIL; | |
1000 curwin = win; | |
1001 curbuf = curwin->w_buffer; | |
1002 return OK; | |
1003 } | |
1004 | |
1005 /* | |
1006 * Restore current tabpage and window saved by switch_win(), if still valid. | |
1007 * When "no_display" is TRUE the display won't be affected, no redraw is | |
1008 * triggered. | |
1009 */ | |
1010 void | |
1011 restore_win( | |
1012 win_T *save_curwin, | |
1013 tabpage_T *save_curtab, | |
1014 int no_display) | |
1015 { | |
1016 restore_win_noblock(save_curwin, save_curtab, no_display); | |
1017 unblock_autocmds(); | |
1018 } | |
1019 | |
1020 /* | |
1021 * As restore_win() but without unblocking autocommands. | |
1022 */ | |
1023 void | |
1024 restore_win_noblock( | |
1025 win_T *save_curwin, | |
1026 tabpage_T *save_curtab, | |
1027 int no_display) | |
1028 { | |
1029 if (save_curtab != NULL && valid_tabpage(save_curtab)) | |
1030 { | |
1031 if (no_display) | |
1032 { | |
1033 curtab->tp_firstwin = firstwin; | |
1034 curtab->tp_lastwin = lastwin; | |
1035 curtab = save_curtab; | |
1036 firstwin = curtab->tp_firstwin; | |
1037 lastwin = curtab->tp_lastwin; | |
1038 } | |
1039 else | |
1040 goto_tabpage_tp(save_curtab, FALSE, FALSE); | |
1041 } | |
1042 if (win_valid(save_curwin)) | |
1043 { | |
1044 curwin = save_curwin; | |
1045 curbuf = curwin->w_buffer; | |
1046 } | |
1047 # ifdef FEAT_TEXT_PROP | |
1048 else if (WIN_IS_POPUP(curwin)) | |
1049 // original window was closed and now we're in a popup window: Go | |
1050 // to the first valid window. | |
1051 win_goto(firstwin); | |
1052 # endif | |
1053 } | |
1054 #endif |