comparison src/window.c @ 16778:eda4d65f232c v8.1.1391

patch 8.1.1391: no popup window support commit https://github.com/vim/vim/commit/4d784b21d14fc66e98a2b07f70343cdd4acd62aa Author: Bram Moolenaar <Bram@vim.org> Date: Sat May 25 19:51:39 2019 +0200 patch 8.1.1391: no popup window support Problem: No popup window support. Solution: Add initial code for popup windows. Add the 'wincolor' option.
author Bram Moolenaar <Bram@vim.org>
date Sat, 25 May 2019 20:00:08 +0200
parents 695d9ef00b03
children 491c01280a5d
comparison
equal deleted inserted replaced
16777:20d51e99dd6a 16778:eda4d65f232c
1360 1360
1361 /* copy options from existing window */ 1361 /* copy options from existing window */
1362 win_copy_options(oldp, newp); 1362 win_copy_options(oldp, newp);
1363 } 1363 }
1364 1364
1365 static int
1366 win_valid_popup(win_T *win)
1367 {
1368 #ifdef FEAT_TEXT_PROP
1369 win_T *wp;
1370
1371 for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
1372 if (wp == win)
1373 return TRUE;
1374 for (wp = first_tab_popupwin; wp != NULL; wp = wp->w_next)
1375 if (wp == win)
1376 return TRUE;
1377 #endif
1378 return FALSE;
1379 }
1365 1380
1366 /* 1381 /*
1367 * Check if "win" is a pointer to an existing window in the current tab page. 1382 * Check if "win" is a pointer to an existing window in the current tab page.
1368 */ 1383 */
1369 int 1384 int
1374 if (win == NULL) 1389 if (win == NULL)
1375 return FALSE; 1390 return FALSE;
1376 FOR_ALL_WINDOWS(wp) 1391 FOR_ALL_WINDOWS(wp)
1377 if (wp == win) 1392 if (wp == win)
1378 return TRUE; 1393 return TRUE;
1379 return FALSE; 1394 return win_valid_popup(win);
1380 } 1395 }
1381 1396
1382 /* 1397 /*
1383 * Check if "win" is a pointer to an existing window in any tab page. 1398 * Check if "win" is a pointer to an existing window in any tab page.
1384 */ 1399 */
1396 { 1411 {
1397 if (wp == win) 1412 if (wp == win)
1398 return TRUE; 1413 return TRUE;
1399 } 1414 }
1400 } 1415 }
1401 return FALSE; 1416 return win_valid_popup(win);
1402 } 1417 }
1403 1418
1404 /* 1419 /*
1405 * Return the number of windows. 1420 * Return the number of windows.
1406 */ 1421 */
2291 } 2306 }
2292 return FALSE; 2307 return FALSE;
2293 } 2308 }
2294 2309
2295 /* 2310 /*
2311 * Close the buffer of "win" and unload it if "free_buf" is TRUE.
2312 * "abort_if_last" is passed to close_buffer(): abort closing if all other
2313 * windows are closed.
2314 */
2315 static void
2316 win_close_buffer(win_T *win, int free_buf, int abort_if_last)
2317 {
2318 #ifdef FEAT_SYN_HL
2319 // Free independent synblock before the buffer is freed.
2320 if (win->w_buffer != NULL)
2321 reset_synblock(win);
2322 #endif
2323
2324 #ifdef FEAT_QUICKFIX
2325 // When the quickfix/location list window is closed, unlist the buffer.
2326 if (win->w_buffer != NULL && bt_quickfix(win->w_buffer))
2327 win->w_buffer->b_p_bl = FALSE;
2328 #endif
2329
2330 // Close the link to the buffer.
2331 if (win->w_buffer != NULL)
2332 {
2333 bufref_T bufref;
2334
2335 set_bufref(&bufref, curbuf);
2336 win->w_closing = TRUE;
2337 close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0,
2338 abort_if_last);
2339 if (win_valid_any_tab(win))
2340 win->w_closing = FALSE;
2341 // Make sure curbuf is valid. It can become invalid if 'bufhidden' is
2342 // "wipe".
2343 if (!bufref_valid(&bufref))
2344 curbuf = firstbuf;
2345 }
2346 }
2347
2348 /*
2296 * Close window "win". Only works for the current tab page. 2349 * Close window "win". Only works for the current tab page.
2297 * If "free_buf" is TRUE related buffer may be unloaded. 2350 * If "free_buf" is TRUE related buffer may be unloaded.
2298 * 2351 *
2299 * Called by :quit, :close, :xit, :wq and findtag(). 2352 * Called by :quit, :close, :xit, :wq and findtag().
2300 * Returns FAIL when the window was not closed. 2353 * Returns FAIL when the window was not closed.
2317 } 2370 }
2318 2371
2319 if (win->w_closing || (win->w_buffer != NULL 2372 if (win->w_closing || (win->w_buffer != NULL
2320 && win->w_buffer->b_locked > 0)) 2373 && win->w_buffer->b_locked > 0))
2321 return FAIL; /* window is already being closed */ 2374 return FAIL; /* window is already being closed */
2322 if (win == aucmd_win) 2375 if (win_unlisted(win))
2323 { 2376 {
2324 emsg(_("E813: Cannot close autocmd window")); 2377 emsg(_("E813: Cannot close autocmd or popup window"));
2325 return FAIL; 2378 return FAIL;
2326 } 2379 }
2327 if ((firstwin == aucmd_win || lastwin == aucmd_win) && one_window()) 2380 if ((firstwin == aucmd_win || lastwin == aucmd_win) && one_window())
2328 { 2381 {
2329 emsg(_("E814: Cannot close window, only autocmd window would remain")); 2382 emsg(_("E814: Cannot close window, only autocmd window would remain"));
2388 // win_free(). 2441 // win_free().
2389 if (gui.in_use) 2442 if (gui.in_use)
2390 out_flush(); 2443 out_flush();
2391 #endif 2444 #endif
2392 2445
2393 #ifdef FEAT_SYN_HL 2446 win_close_buffer(win, free_buf, TRUE);
2394 // Free independent synblock before the buffer is freed.
2395 if (win->w_buffer != NULL)
2396 reset_synblock(win);
2397 #endif
2398
2399 #ifdef FEAT_QUICKFIX
2400 // When the quickfix/location list window is closed, unlist the buffer.
2401 if (win->w_buffer != NULL && bt_quickfix(win->w_buffer))
2402 win->w_buffer->b_p_bl = FALSE;
2403 #endif
2404
2405 /*
2406 * Close the link to the buffer.
2407 */
2408 if (win->w_buffer != NULL)
2409 {
2410 bufref_T bufref;
2411
2412 set_bufref(&bufref, curbuf);
2413 win->w_closing = TRUE;
2414 close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, TRUE);
2415 if (win_valid_any_tab(win))
2416 win->w_closing = FALSE;
2417 /* Make sure curbuf is valid. It can become invalid if 'bufhidden' is
2418 * "wipe". */
2419 if (!bufref_valid(&bufref))
2420 curbuf = firstbuf;
2421 }
2422 2447
2423 if (only_one_window() && win_valid(win) && win->w_buffer == NULL 2448 if (only_one_window() && win_valid(win) && win->w_buffer == NULL
2424 && (last_window() || curtab != prev_curtab 2449 && (last_window() || curtab != prev_curtab
2425 || close_last_window_tabpage(win, free_buf, prev_curtab))) 2450 || close_last_window_tabpage(win, free_buf, prev_curtab)))
2426 { 2451 {
2625 if (aucmd_win != NULL) 2650 if (aucmd_win != NULL)
2626 { 2651 {
2627 (void)win_free_mem(aucmd_win, &dummy, NULL); 2652 (void)win_free_mem(aucmd_win, &dummy, NULL);
2628 aucmd_win = NULL; 2653 aucmd_win = NULL;
2629 } 2654 }
2655 # ifdef FEAT_TEXT_PROP
2656 close_all_popups();
2657 # endif
2630 2658
2631 while (firstwin != NULL) 2659 while (firstwin != NULL)
2632 (void)win_free_mem(firstwin, &dummy, NULL); 2660 (void)win_free_mem(firstwin, &dummy, NULL);
2633 2661
2634 /* No window should be used after this. Set curwin to NULL to crash 2662 /* No window should be used after this. Set curwin to NULL to crash
3456 wp->w_topline = 1; 3484 wp->w_topline = 1;
3457 #ifdef FEAT_DIFF 3485 #ifdef FEAT_DIFF
3458 wp->w_topfill = 0; 3486 wp->w_topfill = 0;
3459 #endif 3487 #endif
3460 wp->w_botline = 2; 3488 wp->w_botline = 2;
3461 #ifdef FEAT_SYN_HL 3489 #if defined(FEAT_SYN_HL) || defined(FEAT_SPELL)
3462 wp->w_s = &wp->w_buffer->b_s; 3490 wp->w_s = &wp->w_buffer->b_s;
3463 #endif 3491 #endif
3464 } 3492 }
3465 3493
3466 /* 3494 /*
3482 3510
3483 return OK; 3511 return OK;
3484 } 3512 }
3485 3513
3486 /* 3514 /*
3487 * Init "aucmd_win". This can only be done after the first 3515 * Allocate and init a window that is not a regular window.
3488 * window is fully initialized, thus it can't be in win_alloc_first(). 3516 * This can only be done after the first window is fully initialized, thus it
3517 * can't be in win_alloc_first().
3518 */
3519 win_T *
3520 win_alloc_popup_win(void)
3521 {
3522 win_T *wp;
3523
3524 wp = win_alloc(NULL, TRUE);
3525 if (wp != NULL)
3526 {
3527 // We need to initialize options with something, using the current
3528 // window makes most sense.
3529 win_init_some(wp, curwin);
3530
3531 RESET_BINDING(wp);
3532 new_frame(wp);
3533 }
3534 return wp;
3535 }
3536
3537 /*
3538 * Initialize window "wp" to display buffer "buf".
3489 */ 3539 */
3490 void 3540 void
3491 win_alloc_aucmd_win(void) 3541 win_init_popup_win(win_T *wp, buf_T *buf)
3492 { 3542 {
3493 aucmd_win = win_alloc(NULL, TRUE); 3543 wp->w_buffer = buf;
3494 if (aucmd_win != NULL) 3544 ++buf->b_nwindows;
3495 { 3545 win_init_empty(wp); // set cursor and topline to safe values
3496 win_init_some(aucmd_win, curwin); 3546
3497 RESET_BINDING(aucmd_win); 3547 // Make sure w_localdir and globaldir are NULL to avoid a chdir() in
3498 new_frame(aucmd_win); 3548 // win_enter_ext().
3499 } 3549 VIM_CLEAR(wp->w_localdir);
3500 } 3550 }
3501 3551
3502 /* 3552 /*
3503 * Allocate the first window or the first window in a new tab page. 3553 * Allocate the first window or the first window in a new tab page.
3504 * When "oldwin" is NULL create an empty buffer for it. 3554 * When "oldwin" is NULL create an empty buffer for it.
3617 int idx; 3667 int idx;
3618 3668
3619 # ifdef FEAT_DIFF 3669 # ifdef FEAT_DIFF
3620 diff_clear(tp); 3670 diff_clear(tp);
3621 # endif 3671 # endif
3672 # ifdef FEAT_TEXT_PROP
3673 while (tp->tp_first_popupwin != NULL)
3674 popup_close(tp->tp_first_popupwin->w_id);
3675 #endif
3622 for (idx = 0; idx < SNAP_COUNT; ++idx) 3676 for (idx = 0; idx < SNAP_COUNT; ++idx)
3623 clear_snapshot(tp, idx); 3677 clear_snapshot(tp, idx);
3624 #ifdef FEAT_EVAL 3678 #ifdef FEAT_EVAL
3625 vars_clear(&tp->tp_vars->dv_hashtab); /* free all t: variables */ 3679 vars_clear(&tp->tp_vars->dv_hashtab); /* free all t: variables */
3626 hash_init(&tp->tp_vars->dv_hashtab); 3680 hash_init(&tp->tp_vars->dv_hashtab);
4780 4834
4781 #ifdef FEAT_SYN_HL 4835 #ifdef FEAT_SYN_HL
4782 vim_free(wp->w_p_cc_cols); 4836 vim_free(wp->w_p_cc_cols);
4783 #endif 4837 #endif
4784 4838
4785 if (wp != aucmd_win) 4839 if (win_valid_any_tab(wp))
4786 win_remove(wp, tp); 4840 win_remove(wp, tp);
4787 if (autocmd_busy) 4841 if (autocmd_busy)
4788 { 4842 {
4789 wp->w_next = au_pending_free_win; 4843 wp->w_next = au_pending_free_win;
4790 au_pending_free_win = wp; 4844 au_pending_free_win = wp;
4791 } 4845 }
4792 else 4846 else
4793 vim_free(wp); 4847 vim_free(wp);
4794 4848
4795 unblock_autocmds(); 4849 unblock_autocmds();
4850 }
4851
4852 /*
4853 * Return TRUE if "wp" is not in the list of windows: the autocmd window or a
4854 * popup window.
4855 */
4856 int
4857 win_unlisted(win_T *wp)
4858 {
4859 return wp == aucmd_win || bt_popup(wp->w_buffer);
4860 }
4861
4862 /*
4863 * Free a popup window. This does not take the window out of the window list
4864 * and assumes there is only one toplevel frame, no split.
4865 */
4866 void
4867 win_free_popup(win_T *win)
4868 {
4869 win_close_buffer(win, TRUE, FALSE);
4870 vim_free(win->w_frame);
4871 win_free(win, NULL);
4796 } 4872 }
4797 4873
4798 /* 4874 /*
4799 * Append window "wp" in the window list after window "after". 4875 * Append window "wp" in the window list after window "after".
4800 */ 4876 */
6180 } 6256 }
6181 6257
6182 /* 6258 /*
6183 * Return TRUE if there is only one window (in the current tab page), not 6259 * Return TRUE if there is only one window (in the current tab page), not
6184 * counting a help or preview window, unless it is the current window. 6260 * counting a help or preview window, unless it is the current window.
6185 * Does not count "aucmd_win". 6261 * Does not count unlisted windows.
6186 */ 6262 */
6187 int 6263 int
6188 only_one_window(void) 6264 only_one_window(void)
6189 { 6265 {
6190 int count = 0; 6266 int count = 0;
6972 tabpage_T *tp; 7048 tabpage_T *tp;
6973 7049
6974 FOR_ALL_TAB_WINDOWS(tp, wp) 7050 FOR_ALL_TAB_WINDOWS(tp, wp)
6975 if (wp->w_id == id) 7051 if (wp->w_id == id)
6976 return wp; 7052 return wp;
7053 #ifdef FEAT_TEXT_PROP
7054 // popup windows are in a separate list
7055 FOR_ALL_TABPAGES(tp)
7056 for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next)
7057 if (wp->w_id == id)
7058 return wp;
7059 for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
7060 if (wp->w_id == id)
7061 return wp;
7062 #endif
6977 7063
6978 return NULL; 7064 return NULL;
6979 } 7065 }
6980 7066
6981 int 7067 int