Mercurial > vim
changeset 19275:2142fb624658 v8.2.0196
patch 8.2.0196: blocking commands for a finished job in a popup window
Commit: https://github.com/vim/vim/commit/d98c0b63abd7b0e61a383669474abe96044615af
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Feb 2 15:25:16 2020 +0100
patch 8.2.0196: blocking commands for a finished job in a popup window
Problem: Blocking commands for a finished job in a popup window.
Solution: Do not block commands if the job has finished. Adjust test.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 02 Feb 2020 15:30:04 +0100 |
parents | ca1f1b78a0b4 |
children | c062923a350f |
files | src/popupwin.c src/proto/terminal.pro src/terminal.c src/testdir/test_popupwin.vim src/version.c src/window.c |
diffstat | 6 files changed, 56 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/popupwin.c +++ b/src/popupwin.c @@ -2863,10 +2863,15 @@ error_if_popup_window(int also_with_term } # if defined(FEAT_TERMINAL) || defined(PROTO) +/* + * Return TRUE if the current window is running a terminal in a popup window. + * Return FALSE when the job has ended. + */ int error_if_term_popup_window() { - if (WIN_IS_POPUP(curwin) && curbuf->b_term != NULL) + if (WIN_IS_POPUP(curwin) && curbuf->b_term != NULL + && term_job_running(curbuf->b_term)) { emsg(_("E899: Not allowed for a terminal in a popup window")); return TRUE;
--- a/src/proto/terminal.pro +++ b/src/proto/terminal.pro @@ -19,6 +19,7 @@ cursorentry_T *term_get_cursor_shape(gui int term_use_loop(void); void term_win_entered(void); int terminal_loop(int blocking); +int may_close_term_popup(void); void term_channel_closed(channel_T *ch); void term_check_channel_closed_recently(void); int term_do_update_window(win_T *wp);
--- a/src/terminal.c +++ b/src/terminal.c @@ -3260,6 +3260,29 @@ term_after_channel_closed(term_T *term) return FALSE; } +#if defined(FEAT_PROP_POPUP) || defined(PROTO) +/* + * If the current window is a terminal in a popup window and the job has + * finished, close the popup window and to back to the previous window. + * Otherwise return FAIL. + */ + int +may_close_term_popup(void) +{ + if (popup_is_popup(curwin) && curbuf->b_term != NULL + && !term_job_running(curbuf->b_term)) + { + win_T *pwin = curwin; + + if (win_valid(prevwin)) + win_enter(prevwin, FALSE); + popup_close_with_retval(pwin, 0); + return OK; + } + return FAIL; +} +#endif + /* * Called when a channel has been closed. * If this was a channel for a terminal window then finish it up.
--- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -2396,10 +2396,20 @@ endfunc func Test_popupwin_terminal_buffer() CheckFeature terminal - + CheckUnix + + let origwin = win_getid() let ptybuf = term_start(&shell, #{hidden: 1}) - call assert_fails('let winnr = popup_create(ptybuf, #{})', 'E278:') - exe 'bwipe! ' .. ptybuf + let winnr = popup_create(ptybuf, #{minwidth: 40, minheight: 10}) + " Wait for shell to start + sleep 200m + " Cannot quit while job is running + call assert_fails('call feedkeys("\<C-W>:quit\<CR>", "xt")', 'E948:') + call feedkeys("exit\<CR>", 'xt') + " Wait for shell to exit + sleep 100m + call feedkeys(":quit\<CR>", 'xt') + call assert_equal(origwin, win_getid()) endfunc func Test_popupwin_with_buffer_and_filter()
--- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 196, +/**/ 195, /**/ 194,
--- a/src/window.c +++ b/src/window.c @@ -2441,6 +2441,11 @@ win_close(win_T *win, int free_buf) int had_diffmode = win->w_p_diff; #endif +#if defined(FEAT_TERMINAL) && defined(FEAT_PROP_POPUP) + // Can close a popup window with a terminal if the job has finished. + if (may_close_term_popup() == OK) + return OK; +#endif if (ERROR_IF_ANY_POPUP_WINDOW) return FAIL; @@ -6439,6 +6444,12 @@ only_one_window(void) int count = 0; win_T *wp; +#if defined(FEAT_PROP_POPUP) + // If the current window is a popup then there always is another window. + if (popup_is_popup(curwin)) + return FALSE; +#endif + // If there is another tab page there always is another window. if (first_tabpage->tp_next != NULL) return FALSE;