Mercurial > vim
diff 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 |
line wrap: on
line diff
--- a/src/window.c +++ b/src/window.c @@ -1362,6 +1362,21 @@ win_init_some(win_T *newp, win_T *oldp) win_copy_options(oldp, newp); } + static int +win_valid_popup(win_T *win) +{ +#ifdef FEAT_TEXT_PROP + win_T *wp; + + for (wp = first_popupwin; wp != NULL; wp = wp->w_next) + if (wp == win) + return TRUE; + for (wp = first_tab_popupwin; wp != NULL; wp = wp->w_next) + if (wp == win) + return TRUE; +#endif + return FALSE; +} /* * Check if "win" is a pointer to an existing window in the current tab page. @@ -1376,7 +1391,7 @@ win_valid(win_T *win) FOR_ALL_WINDOWS(wp) if (wp == win) return TRUE; - return FALSE; + return win_valid_popup(win); } /* @@ -1398,7 +1413,7 @@ win_valid_any_tab(win_T *win) return TRUE; } } - return FALSE; + return win_valid_popup(win); } /* @@ -2293,6 +2308,44 @@ close_last_window_tabpage( } /* + * Close the buffer of "win" and unload it if "free_buf" is TRUE. + * "abort_if_last" is passed to close_buffer(): abort closing if all other + * windows are closed. + */ + static void +win_close_buffer(win_T *win, int free_buf, int abort_if_last) +{ +#ifdef FEAT_SYN_HL + // Free independent synblock before the buffer is freed. + if (win->w_buffer != NULL) + reset_synblock(win); +#endif + +#ifdef FEAT_QUICKFIX + // When the quickfix/location list window is closed, unlist the buffer. + if (win->w_buffer != NULL && bt_quickfix(win->w_buffer)) + win->w_buffer->b_p_bl = FALSE; +#endif + + // Close the link to the buffer. + if (win->w_buffer != NULL) + { + bufref_T bufref; + + set_bufref(&bufref, curbuf); + win->w_closing = TRUE; + close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, + abort_if_last); + if (win_valid_any_tab(win)) + win->w_closing = FALSE; + // Make sure curbuf is valid. It can become invalid if 'bufhidden' is + // "wipe". + if (!bufref_valid(&bufref)) + curbuf = firstbuf; + } +} + +/* * Close window "win". Only works for the current tab page. * If "free_buf" is TRUE related buffer may be unloaded. * @@ -2319,9 +2372,9 @@ win_close(win_T *win, int free_buf) if (win->w_closing || (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) return FAIL; /* window is already being closed */ - if (win == aucmd_win) - { - emsg(_("E813: Cannot close autocmd window")); + if (win_unlisted(win)) + { + emsg(_("E813: Cannot close autocmd or popup window")); return FAIL; } if ((firstwin == aucmd_win || lastwin == aucmd_win) && one_window()) @@ -2390,35 +2443,7 @@ win_close(win_T *win, int free_buf) out_flush(); #endif -#ifdef FEAT_SYN_HL - // Free independent synblock before the buffer is freed. - if (win->w_buffer != NULL) - reset_synblock(win); -#endif - -#ifdef FEAT_QUICKFIX - // When the quickfix/location list window is closed, unlist the buffer. - if (win->w_buffer != NULL && bt_quickfix(win->w_buffer)) - win->w_buffer->b_p_bl = FALSE; -#endif - - /* - * Close the link to the buffer. - */ - if (win->w_buffer != NULL) - { - bufref_T bufref; - - set_bufref(&bufref, curbuf); - win->w_closing = TRUE; - close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, TRUE); - if (win_valid_any_tab(win)) - win->w_closing = FALSE; - /* Make sure curbuf is valid. It can become invalid if 'bufhidden' is - * "wipe". */ - if (!bufref_valid(&bufref)) - curbuf = firstbuf; - } + win_close_buffer(win, free_buf, TRUE); if (only_one_window() && win_valid(win) && win->w_buffer == NULL && (last_window() || curtab != prev_curtab @@ -2627,6 +2652,9 @@ win_free_all(void) (void)win_free_mem(aucmd_win, &dummy, NULL); aucmd_win = NULL; } +# ifdef FEAT_TEXT_PROP + close_all_popups(); +# endif while (firstwin != NULL) (void)win_free_mem(firstwin, &dummy, NULL); @@ -3458,7 +3486,7 @@ win_init_empty(win_T *wp) wp->w_topfill = 0; #endif wp->w_botline = 2; -#ifdef FEAT_SYN_HL +#if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) wp->w_s = &wp->w_buffer->b_s; #endif } @@ -3484,19 +3512,41 @@ win_alloc_first(void) } /* - * Init "aucmd_win". This can only be done after the first - * window is fully initialized, thus it can't be in win_alloc_first(). + * Allocate and init a window that is not a regular window. + * This can only be done after the first window is fully initialized, thus it + * can't be in win_alloc_first(). + */ + win_T * +win_alloc_popup_win(void) +{ + win_T *wp; + + wp = win_alloc(NULL, TRUE); + if (wp != NULL) + { + // We need to initialize options with something, using the current + // window makes most sense. + win_init_some(wp, curwin); + + RESET_BINDING(wp); + new_frame(wp); + } + return wp; +} + +/* + * Initialize window "wp" to display buffer "buf". */ void -win_alloc_aucmd_win(void) -{ - aucmd_win = win_alloc(NULL, TRUE); - if (aucmd_win != NULL) - { - win_init_some(aucmd_win, curwin); - RESET_BINDING(aucmd_win); - new_frame(aucmd_win); - } +win_init_popup_win(win_T *wp, buf_T *buf) +{ + wp->w_buffer = buf; + ++buf->b_nwindows; + win_init_empty(wp); // set cursor and topline to safe values + + // Make sure w_localdir and globaldir are NULL to avoid a chdir() in + // win_enter_ext(). + VIM_CLEAR(wp->w_localdir); } /* @@ -3619,6 +3669,10 @@ free_tabpage(tabpage_T *tp) # ifdef FEAT_DIFF diff_clear(tp); # endif +# ifdef FEAT_TEXT_PROP + while (tp->tp_first_popupwin != NULL) + popup_close(tp->tp_first_popupwin->w_id); +#endif for (idx = 0; idx < SNAP_COUNT; ++idx) clear_snapshot(tp, idx); #ifdef FEAT_EVAL @@ -4782,7 +4836,7 @@ win_free( vim_free(wp->w_p_cc_cols); #endif - if (wp != aucmd_win) + if (win_valid_any_tab(wp)) win_remove(wp, tp); if (autocmd_busy) { @@ -4796,6 +4850,28 @@ win_free( } /* + * Return TRUE if "wp" is not in the list of windows: the autocmd window or a + * popup window. + */ + int +win_unlisted(win_T *wp) +{ + return wp == aucmd_win || bt_popup(wp->w_buffer); +} + +/* + * Free a popup window. This does not take the window out of the window list + * and assumes there is only one toplevel frame, no split. + */ + void +win_free_popup(win_T *win) +{ + win_close_buffer(win, TRUE, FALSE); + vim_free(win->w_frame); + win_free(win, NULL); +} + +/* * Append window "wp" in the window list after window "after". */ void @@ -6182,7 +6258,7 @@ min_rows(void) /* * Return TRUE if there is only one window (in the current tab page), not * counting a help or preview window, unless it is the current window. - * Does not count "aucmd_win". + * Does not count unlisted windows. */ int only_one_window(void) @@ -6974,6 +7050,16 @@ win_id2wp(int id) FOR_ALL_TAB_WINDOWS(tp, wp) if (wp->w_id == id) return wp; +#ifdef FEAT_TEXT_PROP + // popup windows are in a separate list + FOR_ALL_TABPAGES(tp) + for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_id == id) + return wp; + for (wp = first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_id == id) + return wp; +#endif return NULL; }