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