To: vim_dev@googlegroups.com Subject: Patch 8.2.0191 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0191 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. Files: src/popupwin.c, src/proto/popupwin.pro, src/terminal.c, src/proto/terminal.pro, src/macros.h, src/mouse.c, src/highlight.c, src/drawline.c, src/optionstr.c, src/window.c, src/testdir/test_terminal.vim, src/testdir/dumps/Test_terminal_popup_1.dump, src/testdir/dumps/Test_terminal_popup_2.dump, src/testdir/dumps/Test_terminal_popup_3.dump *** ../vim-8.2.0190/src/popupwin.c 2020-01-30 14:55:29.010670407 +0100 --- src/popupwin.c 2020-02-01 20:12:15.087566967 +0100 *************** *** 1337,1342 **** --- 1337,1347 ---- 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,1788 **** 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)); return NULL; } if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL) --- 1774,1786 ---- semsg(_(e_nobufnr), argvars[0].vval.v_number); return NULL; } } 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(_("E450: buffer number, text or a list required")); return NULL; } if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL) *************** *** 2031,2036 **** --- 2029,2038 ---- 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,2112 **** --- 2109,2121 ---- { 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,2124 **** popup_close(id); } ! static void popup_close_with_retval(win_T *wp, int retval) { typval_T res; --- 2127,2133 ---- popup_close(id); } ! void popup_close_with_retval(win_T *wp, int retval) { typval_T res; *************** *** 2834,2840 **** int error_if_popup_window() { ! if (WIN_IS_POPUP(curwin)) { emsg(_("E994: Not allowed in a popup window")); return TRUE; --- 2843,2852 ---- int error_if_popup_window() { ! // 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,2847 **** --- 2854,2870 ---- 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,2966 **** --- 2984,2993 ---- 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,3435 **** --- 3457,3465 ---- 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); *** ../vim-8.2.0190/src/proto/popupwin.pro 2019-12-12 12:55:30.000000000 +0100 --- src/proto/popupwin.pro 2020-02-01 17:23:53.190844110 +0100 *************** *** 19,24 **** --- 19,25 ---- 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,46 **** --- 42,48 ---- 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); *** ../vim-8.2.0190/src/terminal.c 2020-01-30 16:27:02.068562909 +0100 --- src/terminal.c 2020-02-01 20:57:12.393256154 +0100 *************** *** 1158,1166 **** term_send_mouse(VTerm *vterm, int button, int pressed) { VTermModifier mod = VTERM_MOD_NONE; ! vterm_mouse_move(vterm, mouse_row - W_WINROW(curwin), ! mouse_col - curwin->w_wincol, mod); if (button != 0) vterm_mouse_button(vterm, button, pressed, mod); return TRUE; --- 1158,1174 ---- 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; ! #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,2046 **** 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) { ! stuffcharReadbuff(c); ! mouse_was_outside = TRUE; } - return FAIL; } } if (typed) --- 2035,2066 ---- case K_MOUSEDOWN: case K_MOUSELEFT: case K_MOUSERIGHT: ! { ! 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) { ! // click or scroll outside the current window or on status ! // line or vertical separator ! if (typed) ! { ! stuffcharReadbuff(c); ! mouse_was_outside = TRUE; ! } ! return FAIL; } } } if (typed) *************** *** 2057,2066 **** } static void ! position_cursor(win_T *wp, VTermPos *pos) { wp->w_wrow = MIN(pos->row, MAX(0, wp->w_height - 1)); wp->w_wcol = MIN(pos->col, MAX(0, wp->w_width - 1)); wp->w_valid |= (VALID_WCOL|VALID_WROW); } --- 2077,2093 ---- } static void ! 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,2367 **** if (termwinkey == Ctrl_W) termwinkey = 0; } ! position_cursor(curwin, &curbuf->b_term->tl_cursor_pos); may_set_cursor_props(curbuf->b_term); while (blocking || vpeekc_nomap() != NUL) --- 2388,2394 ---- if (termwinkey == Ctrl_W) termwinkey = 0; } ! position_cursor(curwin, &curbuf->b_term->tl_cursor_pos, TRUE); may_set_cursor_props(curbuf->b_term); while (blocking || vpeekc_nomap() != NUL) *************** *** 2668,2674 **** * Convert the attributes of a vterm cell into an attribute index. */ static int ! cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg) { int attr = vtermAttr2hl(cellattrs); --- 2695,2705 ---- * Convert the attributes of a vterm cell into an attribute index. */ static int ! cell2attr( ! win_T *wp, ! VTermScreenCellAttrs cellattrs, ! VTermColor cellfg, ! VTermColor cellbg) { int attr = vtermAttr2hl(cellattrs); *************** *** 2700,2712 **** int fg = color2index(&cellfg, TRUE, &bold); int bg = color2index(&cellbg, FALSE, &bold); ! // Use the "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; } // with 8 colors set the bold attribute to get a bright foreground --- 2731,2765 ---- int fg = color2index(&cellfg, TRUE, &bold); int bg = color2index(&cellbg, FALSE, &bold); ! // Use the 'wincolor' or "Terminal" highlighting for the default ! // colors. if ((fg == 0 || bg == 0) && t_colors >= 16) { ! 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,2766 **** 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) win_del_lines(wp, start_row, count, FALSE, FALSE, clear_attr); } } --- 2804,2821 ---- VTermScreenCellAttrs attr; int clear_attr; vim_memset(&attr, 0, sizeof(attr)); 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,2815 **** FOR_ALL_WINDOWS(wp) { if (wp->w_buffer == term->tl_buffer) ! position_cursor(wp, &pos); } if (term->tl_buffer == curbuf && !term->tl_normal_mode) { --- 2864,2870 ---- FOR_ALL_WINDOWS(wp) { if (wp->w_buffer == term->tl_buffer) ! position_cursor(wp, &pos, FALSE); } if (term->tl_buffer == curbuf && !term->tl_normal_mode) { *************** *** 3143,3149 **** --- 3198,3216 ---- { 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,3171 **** --- 3233,3242 ---- 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,3283 **** * Advances "pos" to past the last column. */ static void ! term_line2screenline(VTermScreen *screen, VTermPos *pos, int max_col) { int off = screen_get_current_line_off(); --- 3348,3358 ---- * Advances "pos" to past the last column. */ static void ! term_line2screenline( ! win_T *wp, ! VTermScreen *screen, ! VTermPos *pos, ! int max_col) { int off = screen_get_current_line_off(); *************** *** 3342,3348 **** else ScreenLines[off] = c; } ! ScreenAttrs[off] = cell2attr(cell.attrs, cell.fg, cell.bg); ++pos->col; ++off; --- 3417,3423 ---- else ScreenLines[off] = c; } ! ScreenAttrs[off] = cell2attr(wp, cell.attrs, cell.fg, cell.bg); ++pos->col; ++off; *************** *** 3393,3399 **** { int max_col = MIN(Columns, term->tl_cols); ! term_line2screenline(screen, &pos, max_col); } else pos.col = 0; --- 3468,3474 ---- { int max_col = MIN(Columns, term->tl_cols); ! term_line2screenline(NULL, screen, &pos, max_col); } else pos.col = 0; *************** *** 3462,3476 **** newrows = 99999; newcols = 99999; ! FOR_ALL_WINDOWS(twp) { // When more than one window shows the same terminal, use the // smallest size. ! if (twp->w_buffer == term->tl_buffer) { ! newrows = MIN(newrows, twp->w_height); ! newcols = MIN(newcols, twp->w_width); } } if (newrows == 99999 || newcols == 99999) return; // safety exit --- 3537,3556 ---- newrows = 99999; newcols = 99999; ! 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 (wwp->w_buffer == term->tl_buffer) { ! 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,3499 **** // The cursor may have been moved when resizing. vterm_state_get_cursorpos(state, &pos); ! position_cursor(wp, &pos); for (pos.row = term->tl_dirty_row_start; pos.row < term->tl_dirty_row_end && pos.row < wp->w_height; ++pos.row) --- 3573,3579 ---- // The cursor may have been moved when resizing. vterm_state_get_cursorpos(state, &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,3508 **** { int max_col = MIN(wp->w_width, term->tl_cols); ! term_line2screenline(screen, &pos, max_col); } else pos.col = 0; --- 3582,3588 ---- { int max_col = MIN(wp->w_width, term->tl_cols); ! term_line2screenline(wp, screen, &pos, max_col); } else pos.col = 0; *************** *** 3511,3517 **** #ifdef FEAT_MENU + winbar_height(wp) #endif ! , wp->w_wincol, pos.col, wp->w_width, 0); } term->tl_dirty_row_start = MAX_ROW; term->tl_dirty_row_end = 0; --- 3591,3601 ---- #ifdef FEAT_MENU + winbar_height(wp) #endif ! , 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,3571 **** * Use a negative "col" to get the filler background color. */ int ! term_get_attr(buf_T *buf, linenr_T lnum, int col) { term_T *term = buf->b_term; sb_line_T *line; cellattr_T *cellattr; --- 3648,3656 ---- * Use a negative "col" to get the filler background color. */ int ! 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,3586 **** else cellattr = line->sb_cells + col; } ! return cell2attr(cellattr->attrs, cellattr->fg, cellattr->bg); } /* --- 3665,3671 ---- else cellattr = line->sb_cells + col; } ! return cell2attr(wp, cellattr->attrs, cellattr->fg, cellattr->bg); } /* *************** *** 3597,3603 **** * Initialize term->tl_default_color from the environment. */ static void ! init_default_colors(term_T *term) { VTermColor *fg, *bg; int fgval, bgval; --- 3682,3688 ---- * Initialize term->tl_default_color from the environment. */ static void ! init_default_colors(term_T *term, win_T *wp) { VTermColor *fg, *bg; int fgval, bgval; *************** *** 3624,3631 **** 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"); // Use the actual color for the GUI and when 'termguicolors' is set. #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) --- 3709,3719 ---- bg->red = bg->green = bg->blue = bgval; fg->ansi_index = bg->ansi_index = VTERM_ANSI_INDEX_DEFAULT; ! // 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,4128 **** // TODO: depends on 'encoding'. vterm_set_utf8(vterm, 1); ! init_default_colors(term); vterm_state_set_default_colors( state, --- 4210,4216 ---- // TODO: depends on 'encoding'. vterm_set_utf8(vterm, 1); ! init_default_colors(term, NULL); vterm_state_set_default_colors( state, *************** *** 4158,4163 **** --- 4246,4266 ---- } /* + * 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. */ char_u * *************** *** 4857,4863 **** VTermPos cursor_pos1; VTermPos cursor_pos2; ! init_default_colors(term); rettv->vval.v_number = buf->b_fnum; --- 4960,4966 ---- VTermPos cursor_pos1; VTermPos cursor_pos2; ! init_default_colors(term, NULL); rettv->vval.v_number = buf->b_fnum; *************** *** 5571,5577 **** 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, "width", width); ++pos.col; --- 5674,5680 ---- bg.red, bg.green, bg.blue); dict_add_string(dcell, "bg", rgb); ! dict_add_number(dcell, "attr", cell2attr(NULL, attrs, fg, bg)); dict_add_number(dcell, "width", width); ++pos.col; *** ../vim-8.2.0190/src/proto/terminal.pro 2019-12-12 12:55:35.000000000 +0100 --- src/proto/terminal.pro 2020-02-01 20:57:18.469235494 +0100 *************** *** 26,32 **** 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); 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); --- 26,33 ---- int term_is_finished(buf_T *buf); int term_show_buffer(buf_T *buf); void term_change_in_curbuf(void); ! 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); *** ../vim-8.2.0190/src/macros.h 2020-01-26 15:52:33.023833239 +0100 --- src/macros.h 2020-02-01 17:24:40.098697195 +0100 *************** *** 345,352 **** --- 345,354 ---- // 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 *** ../vim-8.2.0190/src/mouse.c 2019-11-30 22:40:44.000000000 +0100 --- src/mouse.c 2020-02-01 18:02:20.582051074 +0100 *************** *** 1736,1741 **** --- 1736,1746 ---- # 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 // (MOUSE_FOCUS was set above if we dragged first). *** ../vim-8.2.0190/src/highlight.c 2020-01-27 22:09:35.796838619 +0100 --- src/highlight.c 2020-02-01 20:20:13.021334838 +0100 *************** *** 3134,3141 **** #endif #if (defined(MSWIN) \ ! && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) \ ! && defined(FEAT_TERMGUICOLORS)) || defined(PROTO) void syn_id2cterm_bg(int hl_id, int *fgp, int *bgp) { --- 3134,3142 ---- #endif #if (defined(MSWIN) \ ! && (!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) { *** ../vim-8.2.0190/src/drawline.c 2020-01-23 19:59:16.285588199 +0100 --- src/drawline.c 2020-02-01 20:30:21.442794285 +0100 *************** *** 491,497 **** { extra_check = TRUE; get_term_attr = TRUE; ! win_attr = term_get_attr(wp->w_buffer, lnum, -1); } #endif --- 491,497 ---- { extra_check = TRUE; get_term_attr = TRUE; ! win_attr = term_get_attr(wp, lnum, -1); } #endif *************** *** 1419,1425 **** syntax_attr = 0; # ifdef FEAT_TERMINAL if (get_term_attr) ! syntax_attr = term_get_attr(wp->w_buffer, lnum, vcol); # endif // Get syntax attribute. if (has_syntax) --- 1419,1425 ---- syntax_attr = 0; # ifdef FEAT_TERMINAL if (get_term_attr) ! syntax_attr = term_get_attr(wp, lnum, vcol); # endif // Get syntax attribute. if (has_syntax) *** ../vim-8.2.0190/src/optionstr.c 2019-11-30 22:40:44.000000000 +0100 --- src/optionstr.c 2020-02-01 20:54:43.601756449 +0100 *************** *** 2128,2133 **** --- 2128,2139 ---- 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) *** ../vim-8.2.0190/src/window.c 2020-01-23 15:33:31.526017874 +0100 --- src/window.c 2020-02-01 17:25:53.566462124 +0100 *************** *** 4344,4350 **** #endif #ifdef FEAT_PROP_POPUP ! if (ERROR_IF_POPUP_WINDOW) return; if (popup_is_popup(wp)) { --- 4344,4350 ---- #endif #ifdef FEAT_PROP_POPUP ! if (ERROR_IF_POPUP_WINDOW || ERROR_IF_TERM_POPUP_WINDOW) return; if (popup_is_popup(wp)) { *************** *** 4486,4491 **** --- 4486,4495 ---- { 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,4569 **** --- 4568,4577 ---- { 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); *** ../vim-8.2.0190/src/testdir/test_terminal.vim 2020-01-30 16:27:02.068562909 +0100 --- src/testdir/test_terminal.vim 2020-02-01 21:52:12.349570725 +0100 *************** *** 2321,2323 **** --- 2321,2364 ---- 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\") + call VerifyScreenDump(buf, 'Test_terminal_popup_2', {}) + + call term_sendkeys(buf, ":call OpenTerm(1)\") + call term_sendkeys(buf, ":set hlsearch\") + call term_sendkeys(buf, "/edit\") + call VerifyScreenDump(buf, 'Test_terminal_popup_3', {}) + + call term_sendkeys(buf, ":q\") + call term_wait(buf, 50) " wait for terminal to vanish + + call StopVimInTerminal(buf) + call delete('XtermPopup') + endfunc *** ../vim-8.2.0190/src/testdir/dumps/Test_terminal_popup_1.dump 2020-02-01 21:55:48.144785078 +0100 --- src/testdir/dumps/Test_terminal_popup_1.dump 2020-02-01 21:41:02.611984970 +0100 *************** *** 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| *** ../vim-8.2.0190/src/testdir/dumps/Test_terminal_popup_2.dump 2020-02-01 21:55:48.148785064 +0100 --- src/testdir/dumps/Test_terminal_popup_2.dump 2020-02-01 21:42:15.435723466 +0100 *************** *** 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| *** ../vim-8.2.0190/src/testdir/dumps/Test_terminal_popup_3.dump 2020-02-01 21:55:48.152785050 +0100 --- src/testdir/dumps/Test_terminal_popup_3.dump 2020-02-01 21:46:56.646712095 +0100 *************** *** 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| *** ../vim-8.2.0190/src/version.c 2020-01-31 22:57:56.600690726 +0100 --- src/version.c 2020-02-01 21:55:28.848855221 +0100 *************** *** 744,745 **** --- 744,747 ---- { /* Add new patch number below this line */ + /**/ + 191, /**/ -- Far back in the mists of ancient time, in the great and glorious days of the former Galactic Empire, life was wild, rich and largely tax free. Mighty starships plied their way between exotic suns, seeking adventure and reward among the furthest reaches of Galactic space. In those days, spirits were brave, the stakes were high, men were real men, women were real women and small furry creatures from Alpha Centauri were real small furry creatures from Alpha Centauri. And all dared to brave unknown terrors, to do mighty deeds, to boldly split infinitives that no man had split before -- and thus was the Empire forged. -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy" /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///