]> granicus.if.org Git - vim/commitdiff
patch 8.2.0191: cannot put a terminal in a popup window v8.2.0191
authorBram Moolenaar <Bram@vim.org>
Sat, 1 Feb 2020 20:57:29 +0000 (21:57 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 1 Feb 2020 20:57:29 +0000 (21:57 +0100)
Problem:    Cannot put a terminal in a popup window.
Solution:   Allow opening a terminal in a popup window.  It will always have
            keyboard focus until closed.

15 files changed:
src/drawline.c
src/highlight.c
src/macros.h
src/mouse.c
src/optionstr.c
src/popupwin.c
src/proto/popupwin.pro
src/proto/terminal.pro
src/terminal.c
src/testdir/dumps/Test_terminal_popup_1.dump [new file with mode: 0644]
src/testdir/dumps/Test_terminal_popup_2.dump [new file with mode: 0644]
src/testdir/dumps/Test_terminal_popup_3.dump [new file with mode: 0644]
src/testdir/test_terminal.vim
src/version.c
src/window.c

index 4723915830df1145e6892a8d7cbc6e17db0faa8a..176aa69598d71e201ae1ac6891c1225cf5fddd6e 100644 (file)
@@ -491,7 +491,7 @@ win_line(
        {
            extra_check = TRUE;
            get_term_attr = TRUE;
-           win_attr = term_get_attr(wp->w_buffer, lnum, -1);
+           win_attr = term_get_attr(wp, lnum, -1);
        }
 #endif
 
@@ -1419,7 +1419,7 @@ win_line(
                syntax_attr = 0;
 # ifdef FEAT_TERMINAL
                if (get_term_attr)
-                   syntax_attr = term_get_attr(wp->w_buffer, lnum, vcol);
+                   syntax_attr = term_get_attr(wp, lnum, vcol);
 # endif
                // Get syntax attribute.
                if (has_syntax)
index 19a9c50a20e0dbaecc3ad572196674ad28dc1ecc..44888e97e5940d385d442fcdc4fdc03acc655954 100644 (file)
@@ -3134,8 +3134,9 @@ syn_id2colors(int hl_id, guicolor_T *fgp, guicolor_T *bgp)
 #endif
 
 #if (defined(MSWIN) \
-       && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) \
-       && defined(FEAT_TERMGUICOLORS)) || defined(PROTO)
+           && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) \
+           && defined(FEAT_TERMGUICOLORS)) \
+       || defined(FEAT_TERMINAL) || defined(PROTO)
     void
 syn_id2cterm_bg(int hl_id, int *fgp, int *bgp)
 {
index 6631d4d9ba0ea4d604c9d1b64ec0c44e84b42a40..ce226e3efe5070e0bc1b11a20936f650af72c2c9 100644 (file)
 // Give an error in curwin is a popup window and evaluate to TRUE.
 #ifdef FEAT_PROP_POPUP
 # define ERROR_IF_POPUP_WINDOW error_if_popup_window()
+# define ERROR_IF_TERM_POPUP_WINDOW error_if_term_popup_window()
 #else
 # define ERROR_IF_POPUP_WINDOW 0
+# define ERROR_IF_TERM_POPUP_WINDOW 0
 #endif
 
 
index c94f3228f133e9436d85241deba0ee90a686f824..5b468d63f8f9e7005dc0bdda4d3d8460042df52e 100644 (file)
@@ -1735,6 +1735,11 @@ retnomove:
            wp = curwin;
 # endif
        }
+#endif
+#if defined(FEAT_PROP_POPUP) && defined(FEAT_TERMINAL)
+       if (popup_is_popup(curwin) && curbuf->b_term != NULL)
+           // terminal in popup window: don't jump to another window
+           return IN_OTHER_WIN;
 #endif
        // Only change window focus when not clicking on or dragging the
        // status line.  Do change focus when releasing the mouse button
index 98e90a4536c9bead109d4d0d5b0a3ceb274dd87c..af4b749f26665f9403babb56cdbaf62c7d295e0d 100644 (file)
@@ -2128,6 +2128,12 @@ did_set_string_option(
                errmsg = e_invarg;
        }
     }
+    // 'wincolor'
+    else if (varp == &curwin->w_p_wcr)
+    {
+       if (curwin->w_buffer->b_term != NULL)
+           term_update_colors();
+    }
 # if defined(MSWIN)
     // 'termwintype'
     else if (varp == &p_twt)
index 8a3f500d211fa13e9d194b6b2aa6adc462a87610..b1ae16d1608553c782c5b3feb8dd7df7eab97bb7 100644 (file)
@@ -1337,6 +1337,11 @@ popup_adjust_position(win_T *wp)
 
     wp->w_has_scrollbar = wp->w_want_scrollbar
           && (wp->w_topline > 1 || lnum <= wp->w_buffer->b_ml.ml_line_count);
+#ifdef FEAT_TERMINAL
+    if (wp->w_buffer->b_term != NULL)
+       // Terminal window never has a scrollbar, adjusts to window height.
+       wp->w_has_scrollbar = FALSE;
+#endif
     if (wp->w_has_scrollbar)
     {
        ++right_extra;
@@ -1769,20 +1774,13 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
                semsg(_(e_nobufnr), argvars[0].vval.v_number);
                return NULL;
            }
-#ifdef FEAT_TERMINAL
-           if (buf->b_term != NULL)
-           {
-               emsg(_("E278: Cannot put a terminal buffer in a popup window"));
-               return NULL;
-           }
-#endif
        }
        else if (!(argvars[0].v_type == VAR_STRING
                        && argvars[0].vval.v_string != NULL)
                    && !(argvars[0].v_type == VAR_LIST
                        && argvars[0].vval.v_list != NULL))
        {
-           emsg(_(e_listreq));
+           emsg(_("E450: buffer number, text or a list required"));
            return NULL;
        }
        if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL)
@@ -2031,6 +2029,10 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
     redraw_all_later(NOT_VALID);
     popup_mask_refresh = TRUE;
 
+    // When running a terminal in the popup it becomes the current window.
+    if (buf->b_term != NULL)
+       win_enter(wp, FALSE);
+
     return wp;
 }
 
@@ -2107,6 +2109,13 @@ popup_close_and_callback(win_T *wp, typval_T *arg)
 {
     int id = wp->w_id;
 
+    if (wp == curwin && curbuf->b_term != NULL)
+    {
+       // Closing popup window with a terminal: put focus back on the previous
+       // window.
+       win_enter(prevwin, FALSE);
+    }
+
     // Just in case a check higher up is missing.
     if (wp == curwin && ERROR_IF_POPUP_WINDOW)
        return;
@@ -2118,7 +2127,7 @@ popup_close_and_callback(win_T *wp, typval_T *arg)
     popup_close(id);
 }
 
-    static void
+    void
 popup_close_with_retval(win_T *wp, int retval)
 {
     typval_T res;
@@ -2834,7 +2843,10 @@ f_popup_getoptions(typval_T *argvars, typval_T *rettv)
     int
 error_if_popup_window()
 {
-    if (WIN_IS_POPUP(curwin))
+    // win_execute() may set "curwin" to a popup window temporarily, but many
+    // commands are disallowed then.  When a terminal runs in the popup most
+    // things are allowed.
+    if (WIN_IS_POPUP(curwin) && curbuf->b_term == NULL)
     {
        emsg(_("E994: Not allowed in a popup window"));
        return TRUE;
@@ -2842,6 +2854,17 @@ error_if_popup_window()
     return FALSE;
 }
 
+    int
+error_if_term_popup_window()
+{
+    if (WIN_IS_POPUP(curwin) && curbuf->b_term != NULL)
+    {
+       emsg(_("E899: Not allowed for a terminal in a popup window"));
+       return TRUE;
+    }
+    return FALSE;
+}
+
 /*
  * Reset all the "handled_flag" flags in global popup windows and popup windows
  * in the current tab page.
@@ -2961,6 +2984,10 @@ popup_do_filter(int c)
     int                state;
     int                was_must_redraw = must_redraw;
 
+    // Popup window with terminal always gets focus.
+    if (popup_is_popup(curwin) && curbuf->b_term != NULL)
+       return FALSE;
+
     if (recursive)
        return FALSE;
     recursive = TRUE;
@@ -3430,6 +3457,9 @@ update_popups(void (*win_update)(win_T *wp))
 
        wp->w_winrow -= top_off;
        wp->w_wincol -= left_extra;
+       // cursor position matters in terminal
+       wp->w_wrow += top_off;
+       wp->w_wcol += left_extra;
 
        total_width = popup_width(wp);
        total_height = popup_height(wp);
index 11db3622bc1e0659a03635aa1e4af32dab0975b5..bfbd883cad7fd7fb9d14793e380d1d815d1888b4 100644 (file)
@@ -19,6 +19,7 @@ void f_popup_clear(typval_T *argvars, typval_T *rettv);
 void f_popup_create(typval_T *argvars, typval_T *rettv);
 void f_popup_atcursor(typval_T *argvars, typval_T *rettv);
 void f_popup_beval(typval_T *argvars, typval_T *rettv);
+void popup_close_with_retval(win_T *wp, int retval);
 void popup_close_for_mouse_click(win_T *wp);
 void popup_handle_mouse_moved(void);
 void f_popup_filter_menu(typval_T *argvars, typval_T *rettv);
@@ -41,6 +42,7 @@ void f_popup_getpos(typval_T *argvars, typval_T *rettv);
 void f_popup_locate(typval_T *argvars, typval_T *rettv);
 void f_popup_getoptions(typval_T *argvars, typval_T *rettv);
 int error_if_popup_window(void);
+int error_if_term_popup_window(void);
 void popup_reset_handled(int handled_flag);
 win_T *find_next_popup(int lowest, int handled_flag);
 int popup_do_filter(int c);
index 5206addd459cb49f482e0ff077f550723a7cbcc0..8d37db8e36bb682a97b511dca7e6384f3f8dc143 100644 (file)
@@ -26,7 +26,8 @@ void term_update_window(win_T *wp);
 int term_is_finished(buf_T *buf);
 int term_show_buffer(buf_T *buf);
 void term_change_in_curbuf(void);
-int term_get_attr(buf_T *buf, linenr_T lnum, int col);
+int term_get_attr(win_T *wp, linenr_T lnum, int col);
+void term_update_colors(void);
 char_u *term_get_status_text(term_T *term);
 int set_ref_in_term(int copyID);
 void set_terminal_default_colors(int cterm_fg, int cterm_bg);
index d789ab0563603dc6eb93da291a0e51a84698c1c3..7f92ab1a445da41f36f5c9dd478d512e96a34c5c 100644 (file)
@@ -1158,9 +1158,17 @@ write_to_term(buf_T *buffer, char_u *msg, channel_T *channel)
 term_send_mouse(VTerm *vterm, int button, int pressed)
 {
     VTermModifier   mod = VTERM_MOD_NONE;
+    int                    row = mouse_row - W_WINROW(curwin);
+    int                    col = mouse_col - curwin->w_wincol;
 
-    vterm_mouse_move(vterm, mouse_row - W_WINROW(curwin),
-                                           mouse_col - curwin->w_wincol, mod);
+#ifdef FEAT_PROP_POPUP
+    if (popup_is_popup(curwin))
+    {
+       row -= popup_top_extra(curwin);
+       col -= popup_left_extra(curwin);
+    }
+#endif
+    vterm_mouse_move(vterm, row, col, mod);
     if (button != 0)
        vterm_mouse_button(vterm, button, pressed, mod);
     return TRUE;
@@ -2027,20 +2035,32 @@ send_keys_to_term(term_T *term, int c, int modmask, int typed)
        case K_MOUSEDOWN:
        case K_MOUSELEFT:
        case K_MOUSERIGHT:
-           if (mouse_row < W_WINROW(curwin)
-                   || mouse_row >= (W_WINROW(curwin) + curwin->w_height)
-                   || mouse_col < curwin->w_wincol
-                   || mouse_col >= W_ENDCOL(curwin)
-                   || dragging_outside)
            {
-               // click or scroll outside the current window or on status line
-               // or vertical separator
-               if (typed)
+               int     row = mouse_row;
+               int     col = mouse_col;
+
+#ifdef FEAT_PROP_POPUP
+               if (popup_is_popup(curwin))
+               {
+                   row -= popup_top_extra(curwin);
+                   col -= popup_left_extra(curwin);
+               }
+#endif
+               if (row < W_WINROW(curwin)
+                       || row >= (W_WINROW(curwin) + curwin->w_height)
+                       || col < curwin->w_wincol
+                       || col >= W_ENDCOL(curwin)
+                       || dragging_outside)
                {
-                   stuffcharReadbuff(c);
-                   mouse_was_outside = TRUE;
+                   // click or scroll outside the current window or on status
+                   // line or vertical separator
+                   if (typed)
+                   {
+                       stuffcharReadbuff(c);
+                       mouse_was_outside = TRUE;
+                   }
+                   return FAIL;
                }
-               return FAIL;
            }
     }
     if (typed)
@@ -2057,10 +2077,17 @@ send_keys_to_term(term_T *term, int c, int modmask, int typed)
 }
 
     static void
-position_cursor(win_T *wp, VTermPos *pos)
+position_cursor(win_T *wp, VTermPos *pos, int add_off UNUSED)
 {
     wp->w_wrow = MIN(pos->row, MAX(0, wp->w_height - 1));
     wp->w_wcol = MIN(pos->col, MAX(0, wp->w_width - 1));
+#ifdef FEAT_PROP_POPUP
+    if (add_off && popup_is_popup(curwin))
+    {
+       wp->w_wrow += popup_top_extra(curwin);
+       wp->w_wcol += popup_left_extra(curwin);
+    }
+#endif
     wp->w_valid |= (VALID_WCOL|VALID_WROW);
 }
 
@@ -2361,7 +2388,7 @@ terminal_loop(int blocking)
        if (termwinkey == Ctrl_W)
            termwinkey = 0;
     }
-    position_cursor(curwin, &curbuf->b_term->tl_cursor_pos);
+    position_cursor(curwin, &curbuf->b_term->tl_cursor_pos, TRUE);
     may_set_cursor_props(curbuf->b_term);
 
     while (blocking || vpeekc_nomap() != NUL)
@@ -2668,7 +2695,11 @@ hl2vtermAttr(int attr, cellattr_T *cell)
  * Convert the attributes of a vterm cell into an attribute index.
  */
     static int
-cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg)
+cell2attr(
+       win_T                   *wp,
+       VTermScreenCellAttrs    cellattrs,
+       VTermColor              cellfg,
+       VTermColor              cellbg)
 {
     int attr = vtermAttr2hl(cellattrs);
 
@@ -2700,13 +2731,35 @@ cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg)
        int fg = color2index(&cellfg, TRUE, &bold);
        int bg = color2index(&cellbg, FALSE, &bold);
 
-       // Use the "Terminal" highlighting for the default colors.
+       // Use the 'wincolor' or "Terminal" highlighting for the default
+       // colors.
        if ((fg == 0 || bg == 0) && t_colors >= 16)
        {
-           if (fg == 0 && term_default_cterm_fg >= 0)
-               fg = term_default_cterm_fg + 1;
-           if (bg == 0 && term_default_cterm_bg >= 0)
-               bg = term_default_cterm_bg + 1;
+           int wincolor_fg = -1;
+           int wincolor_bg = -1;
+
+           if (wp != NULL && *wp->w_p_wcr != NUL)
+           {
+               int id = syn_name2id(curwin->w_p_wcr);
+
+               // Get the 'wincolor' group colors.
+               if (id > 0)
+                   syn_id2cterm_bg(id, &wincolor_fg, &wincolor_bg);
+           }
+           if (fg == 0)
+           {
+               if (wincolor_fg >= 0)
+                   fg = wincolor_fg + 1;
+               else if (term_default_cterm_fg >= 0)
+                   fg = term_default_cterm_fg + 1;
+           }
+           if (bg == 0)
+           {
+               if (wincolor_bg >= 0)
+                   bg = wincolor_bg + 1;
+               else if (term_default_cterm_bg >= 0)
+                   bg = term_default_cterm_bg + 1;
+           }
        }
 
        // with 8 colors set the bold attribute to get a bright foreground
@@ -2751,16 +2804,18 @@ term_scroll_up(term_T *term, int start_row, int count)
     VTermScreenCellAttrs attr;
     int                         clear_attr;
 
-    // Set the color to clear lines with.
-    vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
-                                                                    &fg, &bg);
     vim_memset(&attr, 0, sizeof(attr));
-    clear_attr = cell2attr(attr, fg, bg);
 
     FOR_ALL_WINDOWS(wp)
     {
        if (wp->w_buffer == term->tl_buffer)
+       {
+           // Set the color to clear lines with.
+           vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
+                                                                    &fg, &bg);
+           clear_attr = cell2attr(wp, attr, fg, bg);
            win_del_lines(wp, start_row, count, FALSE, FALSE, clear_attr);
+       }
     }
 }
 
@@ -2809,7 +2864,7 @@ handle_movecursor(
     FOR_ALL_WINDOWS(wp)
     {
        if (wp->w_buffer == term->tl_buffer)
-           position_cursor(wp, &pos);
+           position_cursor(wp, &pos, FALSE);
     }
     if (term->tl_buffer == curbuf && !term->tl_normal_mode)
     {
@@ -3143,7 +3198,19 @@ term_after_channel_closed(term_T *term)
        {
            aco_save_T  aco;
            int         do_set_w_closing = term->tl_buffer->b_nwindows == 0;
+#ifdef FEAT_PROP_POPUP
+           win_T       *pwin = NULL;
 
+           // If this was a terminal in a popup window, go back to the
+           // previous window.
+           if (popup_is_popup(curwin) && curbuf == term->tl_buffer)
+           {
+               pwin = curwin;
+               if (win_valid(prevwin))
+                   win_enter(prevwin, FALSE);
+           }
+           else
+#endif
            // If this is the last normal window: exit Vim.
            if (term->tl_buffer->b_nwindows > 0 && only_one_window())
            {
@@ -3166,6 +3233,10 @@ term_after_channel_closed(term_T *term)
            if (do_set_w_closing)
                curwin->w_closing = FALSE;
            aucmd_restbuf(&aco);
+#ifdef FEAT_PROP_POPUP
+           if (pwin != NULL)
+               popup_close_with_retval(pwin, 0);
+#endif
            return TRUE;
        }
        if (term->tl_finish == TL_FINISH_OPEN
@@ -3277,7 +3348,11 @@ term_check_channel_closed_recently()
  * Advances "pos" to past the last column.
  */
     static void
-term_line2screenline(VTermScreen *screen, VTermPos *pos, int max_col)
+term_line2screenline(
+       win_T           *wp,
+       VTermScreen     *screen,
+       VTermPos        *pos,
+       int             max_col)
 {
     int off = screen_get_current_line_off();
 
@@ -3342,7 +3417,7 @@ term_line2screenline(VTermScreen *screen, VTermPos *pos, int max_col)
            else
                ScreenLines[off] = c;
        }
-       ScreenAttrs[off] = cell2attr(cell.attrs, cell.fg, cell.bg);
+       ScreenAttrs[off] = cell2attr(wp, cell.attrs, cell.fg, cell.bg);
 
        ++pos->col;
        ++off;
@@ -3393,7 +3468,7 @@ update_system_term(term_T *term)
        {
            int max_col = MIN(Columns, term->tl_cols);
 
-           term_line2screenline(screen, &pos, max_col);
+           term_line2screenline(NULL, screen, &pos, max_col);
        }
        else
            pos.col = 0;
@@ -3462,15 +3537,20 @@ term_update_window(win_T *wp)
 
     newrows = 99999;
     newcols = 99999;
-    FOR_ALL_WINDOWS(twp)
+    for (twp = firstwin; ; twp = twp->w_next)
     {
+       // Always use curwin, it may be a popup window.
+       win_T *wwp = twp == NULL ? curwin : twp;
+
        // When more than one window shows the same terminal, use the
        // smallest size.
-       if (twp->w_buffer == term->tl_buffer)
+       if (wwp->w_buffer == term->tl_buffer)
        {
-           newrows = MIN(newrows, twp->w_height);
-           newcols = MIN(newcols, twp->w_width);
+           newrows = MIN(newrows, wwp->w_height);
+           newcols = MIN(newcols, wwp->w_width);
        }
+       if (twp == NULL)
+           break;
     }
     if (newrows == 99999 || newcols == 99999)
        return; // safety exit
@@ -3493,7 +3573,7 @@ term_update_window(win_T *wp)
 
     // The cursor may have been moved when resizing.
     vterm_state_get_cursorpos(state, &pos);
-    position_cursor(wp, &pos);
+    position_cursor(wp, &pos, FALSE);
 
     for (pos.row = term->tl_dirty_row_start; pos.row < term->tl_dirty_row_end
                                          && pos.row < wp->w_height; ++pos.row)
@@ -3502,7 +3582,7 @@ term_update_window(win_T *wp)
        {
            int max_col = MIN(wp->w_width, term->tl_cols);
 
-           term_line2screenline(screen, &pos, max_col);
+           term_line2screenline(wp, screen, &pos, max_col);
        }
        else
            pos.col = 0;
@@ -3511,7 +3591,11 @@ term_update_window(win_T *wp)
 #ifdef FEAT_MENU
                                + winbar_height(wp)
 #endif
-                               , wp->w_wincol, pos.col, wp->w_width, 0);
+                               , wp->w_wincol, pos.col, wp->w_width,
+#ifdef FEAT_PROP_POPUP
+                               popup_is_popup(wp) ? SLF_POPUP :
+#endif
+                               0);
     }
     term->tl_dirty_row_start = MAX_ROW;
     term->tl_dirty_row_end = 0;
@@ -3564,8 +3648,9 @@ term_change_in_curbuf(void)
  * Use a negative "col" to get the filler background color.
  */
     int
-term_get_attr(buf_T *buf, linenr_T lnum, int col)
+term_get_attr(win_T *wp, linenr_T lnum, int col)
 {
+    buf_T      *buf = wp->w_buffer;
     term_T     *term = buf->b_term;
     sb_line_T  *line;
     cellattr_T *cellattr;
@@ -3580,7 +3665,7 @@ term_get_attr(buf_T *buf, linenr_T lnum, int col)
        else
            cellattr = line->sb_cells + col;
     }
-    return cell2attr(cellattr->attrs, cellattr->fg, cellattr->bg);
+    return cell2attr(wp, cellattr->attrs, cellattr->fg, cellattr->bg);
 }
 
 /*
@@ -3597,7 +3682,7 @@ cterm_color2vterm(int nr, VTermColor *rgb)
  * Initialize term->tl_default_color from the environment.
  */
     static void
-init_default_colors(term_T *term)
+init_default_colors(term_T *term, win_T *wp)
 {
     VTermColor     *fg, *bg;
     int                    fgval, bgval;
@@ -3624,8 +3709,11 @@ init_default_colors(term_T *term)
     bg->red = bg->green = bg->blue = bgval;
     fg->ansi_index = bg->ansi_index = VTERM_ANSI_INDEX_DEFAULT;
 
-    // The "Terminal" highlight group overrules the defaults.
-    id = syn_name2id((char_u *)"Terminal");
+    // The 'wincolor' or "Terminal" highlight group overrules the defaults.
+    if (wp != NULL && *wp->w_p_wcr != NUL)
+       id = syn_name2id(wp->w_p_wcr);
+    else
+       id = syn_name2id((char_u *)"Terminal");
 
     // Use the actual color for the GUI and when 'termguicolors' is set.
 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
@@ -4122,7 +4210,7 @@ create_vterm(term_T *term, int rows, int cols)
     // TODO: depends on 'encoding'.
     vterm_set_utf8(vterm, 1);
 
-    init_default_colors(term);
+    init_default_colors(term, NULL);
 
     vterm_state_set_default_colors(
            state,
@@ -4157,6 +4245,21 @@ create_vterm(term_T *term, int rows, int cols)
     return OK;
 }
 
+/*
+ * Called when 'wincolor' was set.
+ */
+    void
+term_update_colors(void)
+{
+    term_T *term = curwin->w_buffer->b_term;
+
+    init_default_colors(term, curwin);
+    vterm_state_set_default_colors(
+           vterm_obtain_state(term->tl_vterm),
+           &term->tl_default_color.fg,
+           &term->tl_default_color.bg);
+}
+
 /*
  * Return the text to show for the buffer name and status.
  */
@@ -4857,7 +4960,7 @@ term_load_dump(typval_T *argvars, typval_T *rettv, int do_diff)
        VTermPos        cursor_pos1;
        VTermPos        cursor_pos2;
 
-       init_default_colors(term);
+       init_default_colors(term, NULL);
 
        rettv->vval.v_number = buf->b_fnum;
 
@@ -5571,7 +5674,7 @@ f_term_scrape(typval_T *argvars, typval_T *rettv)
                                     bg.red, bg.green, bg.blue);
        dict_add_string(dcell, "bg", rgb);
 
-       dict_add_number(dcell, "attr", cell2attr(attrs, fg, bg));
+       dict_add_number(dcell, "attr", cell2attr(NULL, attrs, fg, bg));
        dict_add_number(dcell, "width", width);
 
        ++pos.col;
diff --git a/src/testdir/dumps/Test_terminal_popup_1.dump b/src/testdir/dumps/Test_terminal_popup_1.dump
new file mode 100644 (file)
index 0000000..0628eb0
--- /dev/null
@@ -0,0 +1,15 @@
+|0+0&#ffffff0| @73
+|1| @73
+|2| @73
+|3| @12|╔+0#0000001#ffd7ff255|═@44|╗| +0#0000000#ffffff0@13
+|4| @12|║+0#0000001#ffd7ff255>s+0#0000000#ffffff0|o|m|e| |t|e|x|t| @35|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13
+|5| @12|║+0#0000001#ffd7ff255|t+0#0000000#ffffff0|o| |e|d|i|t| @37|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13
+|6| @12|║+0#0000001#ffd7ff255|i+0#0000000#ffffff0|n| |a| |p|o|p|u|p| |w|i|n|d|o|w| @27|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13
+|7| @12|║+0#0000001#ffd7ff255|~+0#4040ff13#ffffff0| @43|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13
+|8| @12|║+0#0000001#ffd7ff255|~+0#4040ff13#ffffff0| @43|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13
+|9| @12|║+0#0000001#ffd7ff255|~+0#4040ff13#ffffff0| @43|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13
+|1|0| @11|║+0#0000001#ffd7ff255|"+0#0000000#ffffff0|X|t|e|x|t|"| |3|L|,| |3|6|C| @11|1|,|1| @10|A|l@1| |║+0#0000001#ffd7ff255| +0#0000000#ffffff0@13
+|1@1| @11|╚+0#0000001#ffd7ff255|═@44|⇲| +0#0000000#ffffff0@13
+|1|2| @72
+|1|3| @72
+@57|0|,|0|-|1| @8|A|l@1| 
diff --git a/src/testdir/dumps/Test_terminal_popup_2.dump b/src/testdir/dumps/Test_terminal_popup_2.dump
new file mode 100644 (file)
index 0000000..478d0b4
--- /dev/null
@@ -0,0 +1,15 @@
+>0+0&#ffffff0| @73
+|1| @73
+|2| @73
+|3| @73
+|4| @73
+|5| @73
+|6| @73
+|7| @73
+|8| @73
+|9| @73
+|1|0| @72
+|1@1| @72
+|1|2| @72
+|1|3| @72
+|"|[|N|o| |N|a|m|e|]|"| |[|M|o|d|i|f|i|e|d|]| |2|0| |l|i|n|e|s| |-@1|5|%|-@1| @18|1|,|1| @10|T|o|p| 
diff --git a/src/testdir/dumps/Test_terminal_popup_3.dump b/src/testdir/dumps/Test_terminal_popup_3.dump
new file mode 100644 (file)
index 0000000..6a6e0eb
--- /dev/null
@@ -0,0 +1,15 @@
+|0+0&#ffffff0| @73
+|1| @73
+|2| @73
+|3| @12|╔+0&#a8a8a8255|═@44|╗| +0&#ffffff0@13
+|4| @12|║+0&#a8a8a8255|s|o|m|e| |t|e|x|t| @35|║| +0&#ffffff0@13
+|5| @12|║+0&#a8a8a8255|t|o| >e+0&#ffff4012|d|i|t| +0&#a8a8a8255@37|║| +0&#ffffff0@13
+|6| @12|║+0&#a8a8a8255|i|n| |a| |p|o|p|u|p| |w|i|n|d|o|w| @27|║| +0&#ffffff0@13
+|7| @12|║+0&#a8a8a8255|~+0#4040ff13&| @43|║+0#0000000&| +0&#ffffff0@13
+|8| @12|║+0&#a8a8a8255|~+0#4040ff13&| @43|║+0#0000000&| +0&#ffffff0@13
+|9| @12|║+0&#a8a8a8255|~+0#4040ff13&| @43|║+0#0000000&| +0&#ffffff0@13
+|1|0| @11|║+0&#a8a8a8255|/|e|d|i|t| @21|2|,|4| @10|A|l@1| |║| +0&#ffffff0@13
+|1@1| @11|╚+0&#a8a8a8255|═@44|⇲| +0&#ffffff0@13
+|1|2| @72
+|1|3| @72
+@57|0|,|0|-|1| @8|A|l@1| 
index 431951bea9a1dc716031eb99ecb8866ed9a71ba6..00f0bfe498b552d6d5264e9deebea8e449b4eeee 100644 (file)
@@ -2321,3 +2321,44 @@ func Test_terminal_api_arg()
   unlet! g:called_bufnum
   unlet! g:called_arg
 endfunc
+
+func Test_terminal_in_popup()
+  CheckRunVimInTerminal
+
+  let text =<< trim END
+    some text
+    to edit
+    in a popup window
+  END
+  call writefile(text, 'Xtext')
+  let cmd = GetVimCommandClean()
+  let lines = [
+       \ 'call setline(1, range(20))',
+       \ 'hi PopTerm ctermbg=grey',
+       \ 'func OpenTerm(setColor)',
+       \ "  let buf = term_start('" .. cmd .. " Xtext', #{hidden: 1, term_finish: 'close'})",
+       \ '  let winid = popup_create(buf, #{minwidth: 45, minheight: 7, border: [], drag: 1, resize: 1})',
+       \ '  if a:setColor',
+       \ '    call win_execute(winid, "set wincolor=PopTerm")',
+       \ '  endif',
+       \ 'endfunc',
+       \ 'call OpenTerm(0)',
+       \ ]
+  call writefile(lines, 'XtermPopup')
+  let buf = RunVimInTerminal('-S XtermPopup', #{rows: 15})
+  call VerifyScreenDump(buf, 'Test_terminal_popup_1', {})
+
+  call term_sendkeys(buf, ":q\<CR>")
+  call VerifyScreenDump(buf, 'Test_terminal_popup_2', {})
+  call term_sendkeys(buf, ":call OpenTerm(1)\<CR>")
+  call term_sendkeys(buf, ":set hlsearch\<CR>")
+  call term_sendkeys(buf, "/edit\<CR>")
+  call VerifyScreenDump(buf, 'Test_terminal_popup_3', {})
+  call term_sendkeys(buf, ":q\<CR>")
+  call term_wait(buf, 50)  " wait for terminal to vanish
+
+  call StopVimInTerminal(buf)
+  call delete('XtermPopup')
+endfunc
index f351d35b32d3b872e280dc94d297f4cdc8d5f534..6c0f7f73882ed268d5099c77d6738d63f184b488 100644 (file)
@@ -742,6 +742,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    191,
 /**/
     190,
 /**/
index 6672433d52a014520aea4172faef886c9f9630b0..6317c3747d4c1e257cb5a057c361e1fcea947b79 100644 (file)
@@ -4344,7 +4344,7 @@ win_goto(win_T *wp)
 #endif
 
 #ifdef FEAT_PROP_POPUP
-    if (ERROR_IF_POPUP_WINDOW)
+    if (ERROR_IF_POPUP_WINDOW || ERROR_IF_TERM_POPUP_WINDOW)
        return;
     if (popup_is_popup(wp))
     {
@@ -4486,6 +4486,10 @@ win_goto_ver(
 {
     win_T      *win;
 
+#ifdef FEAT_PROP_POPUP
+    if (ERROR_IF_TERM_POPUP_WINDOW)
+       return;
+#endif
     win = win_vert_neighbor(curtab, curwin, up, count);
     if (win != NULL)
        win_goto(win);
@@ -4564,6 +4568,10 @@ win_goto_hor(
 {
     win_T      *win;
 
+#ifdef FEAT_PROP_POPUP
+    if (ERROR_IF_TERM_POPUP_WINDOW)
+       return;
+#endif
     win = win_horz_neighbor(curtab, curwin, left, count);
     if (win != NULL)
        win_goto(win);