diff --git a/Filelist b/Filelist index 5038e67687..353cb24d38 100644 --- a/Filelist +++ b/Filelist @@ -200,6 +200,7 @@ SRC_ALL = \ src/libvterm/.gitignore \ src/libvterm/LICENSE \ src/libvterm/Makefile \ + src/libvterm/Makefile.msc \ src/libvterm/README \ src/libvterm/tbl2inc_c.pl \ src/libvterm/vterm.pc.in \ diff --git a/src/INSTALLpc.txt b/src/INSTALLpc.txt index 562b42ce97..b875b77c9a 100644 --- a/src/INSTALLpc.txt +++ b/src/INSTALLpc.txt @@ -706,17 +706,20 @@ Or when using MinGW (as one line): 13. Building with Terminal support ================================== -Vim with Terminal support can be built with MinGW or Cygwin. -Terminal support require winpty which provide following two files. +Vim with Terminal support can be built with either MSVC, or MinGW or Cygwin. +This uses the included libvterm and winpty. No extra header files or +libraries are needed for building. + +Running Vim with terminal support requires the following two winpty files: winpty.dll winpty-agent.dll -You can download following page: +You can download them from the following page: https://github.com/rprichard/winpty -It don't need header files or libraries. Just put them on your PATH. +Just put the DLL files somewhere in your PATH. 14. Windows 3.1x diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index 6ad368b39f..99dcb294dc 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -36,6 +36,8 @@ # is yes) # Global IME support: GIME=yes (requires GUI=yes) # +# Terminal support: TERMINAL=yes (default is no) +# # Lua interface: # LUA=[Path to Lua directory] # DYNAMIC_LUA=yes (to load the Lua DLL dynamically) @@ -354,7 +356,8 @@ CSCOPE_DEFS = -DFEAT_CSCOPE !if "$(TERMINAL)" == "yes" TERMINAL_OBJ = $(OBJDIR)/terminal.obj TERMINAL_DEFS = -DFEAT_TERMINAL -TERMINAL_SRC = terminal.c +TERMINAL_SRC = terminal.c +VTERM_LIB = libvterm/vterm.lib !endif !ifndef NETBEANS @@ -1130,7 +1133,7 @@ conflags = $(conflags) /map /mapinfo:lines LINKARGS1 = $(linkdebug) $(conflags) LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(NODEFAULTLIB) $(LIBC) $(OLE_LIB) user32.lib \ $(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) $(PYTHON3_LIB) $(RUBY_LIB) \ - $(TCL_LIB) $(NETBEANS_LIB) $(XPM_LIB) $(LINK_PDB) + $(TCL_LIB) $(NETBEANS_LIB) $(VTERM_LIB) $(XPM_LIB) $(LINK_PDB) # Report link time code generation progress if used. !ifdef NODEBUG @@ -1544,5 +1547,9 @@ proto.h: \ .c.i: $(CC) $(CFLAGS) /P /C $< +libvterm/vterm.lib : + cd libvterm + $(MAKE) /NOLOGO -f Makefile.msc + cd .. # vim: set noet sw=8 ts=8 sts=0 wm=0 tw=0: diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index 5837c0b172..480b8d3b83 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -5606,16 +5606,34 @@ gui_mch_get_color(char_u *name) return name != NULL ? gui_get_color_cmn(name) : INVALCOLOR; #else guicolor_T color; - GdkColor gcolor; - int ret; color = (name != NULL) ? gui_get_color_cmn(name) : INVALCOLOR; if (color == INVALCOLOR) return INVALCOLOR; - gcolor.red = (guint16)(((color & 0xff0000) >> 16) / 255.0 * 65535 + 0.5); - gcolor.green = (guint16)(((color & 0xff00) >> 8) / 255.0 * 65535 + 0.5); - gcolor.blue = (guint16)((color & 0xff) / 255.0 * 65535 + 0.5); + return gui_mch_get_rgb_color( + (color & 0xff0000) >> 16, + (color & 0xff00) >> 8, + color & 0xff); +#endif +} + +/* + * Return the Pixel value (color) for the given RGB values. + * Return INVALCOLOR for error. + */ + guicolor_T +gui_mch_get_rgb_color(int r, int g, int b) +{ +#if GTK_CHECK_VERSION(3,0,0) + return gui_get_rgb_color_cmn(r, g, b); +#else + GdkColor gcolor; + int ret; + + gcolor.red = (guint16)(r / 255.0 * 65535 + 0.5); + gcolor.green = (guint16)(g / 255.0 * 65535 + 0.5); + gcolor.blue = (guint16)(b / 255.0 * 65535 + 0.5); ret = gdk_colormap_alloc_color(gtk_widget_get_colormap(gui.drawarea), &gcolor, FALSE, TRUE); diff --git a/src/gui_mac.c b/src/gui_mac.c index 20c19946af..3628ddb2fa 100644 --- a/src/gui_mac.c +++ b/src/gui_mac.c @@ -3736,6 +3736,12 @@ gui_mch_get_color(char_u *name) return gui_get_color_cmn(name); } + guicolor_T +gui_mch_get_rgb_color(int r, int g, int b) +{ + return gui_get_rgb_color_cmn(r, g, b); +} + /* * Set the current text foreground color. */ diff --git a/src/gui_photon.c b/src/gui_photon.c index 593be56fbe..faed61d7b2 100644 --- a/src/gui_photon.c +++ b/src/gui_photon.c @@ -1986,6 +1986,12 @@ gui_mch_get_color(char_u *name) return gui_get_color_cmn(name); } + guicolor_T +gui_mch_get_rgb_color(int r, int g, int b) +{ + return gui_get_rgb_color_cmn(r, g, b); +} + void gui_mch_set_fg_color(guicolor_T color) { diff --git a/src/gui_w32.c b/src/gui_w32.c index 611902557e..a91e0710be 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -1597,6 +1597,12 @@ gui_mch_get_color(char_u *name) return gui_get_color_cmn(name); } + guicolor_T +gui_mch_get_rgb_color(int r, int g, int b) +{ + return gui_get_rgb_color_cmn(r, g, b); +} + /* * Return OK if the key with the termcap name "name" is supported. */ diff --git a/src/gui_x11.c b/src/gui_x11.c index 2226e89547..e0b91e65cd 100644 --- a/src/gui_x11.c +++ b/src/gui_x11.c @@ -2272,8 +2272,6 @@ gui_mch_get_color(char_u *name) guicolor_T requested; XColor available; Colormap colormap; -#define COLORSPECBUFSIZE 8 /* space enough to hold "#RRGGBB" */ - char spec[COLORSPECBUFSIZE]; /* can't do this when GUI not running */ if (!gui.in_use || name == NULL || *name == NUL) @@ -2283,11 +2281,22 @@ gui_mch_get_color(char_u *name) if (requested == INVALCOLOR) return INVALCOLOR; - vim_snprintf(spec, COLORSPECBUFSIZE, "#%.2x%.2x%.2x", + return gui_mch_get_rgb_color( (requested & 0xff0000) >> 16, (requested & 0xff00) >> 8, requested & 0xff); -#undef COLORSPECBUFSIZE +} + +/* + * Return the Pixel value (color) for the given RGB values. + * Return INVALCOLOR for error. + */ + guicolor_T +gui_mch_get_rgb_color(int r, int g, int b) +{ + char spec[8]; /* space enough to hold "#RRGGBB" */ + + vim_snprintf(spec, sizeof(spec), "#%.2x%.2x%.2x", r, g, b); colormap = DefaultColormap(gui.dpy, DefaultScreen(gui.dpy)); if (XParseColor(gui.dpy, colormap, (char *)spec, &available) != 0 && XAllocColor(gui.dpy, colormap, &available) != 0) diff --git a/src/libvterm/Makefile.msc b/src/libvterm/Makefile.msc new file mode 100644 index 0000000000..18280d256d --- /dev/null +++ b/src/libvterm/Makefile.msc @@ -0,0 +1,30 @@ +OBJS = \ + src\encoding.c \ + src\keyboard.c \ + src\mouse.c \ + src\parser.c \ + src\pen.c \ + src\screen.c \ + src\state.c \ + src\unicode.c \ + src\vterm.c + +OBJS = \ + src\encoding.obj \ + src\keyboard.obj \ + src\mouse.obj \ + src\parser.obj \ + src\pen.obj \ + src\screen.obj \ + src\state.obj \ + src\unicode.obj \ + src\vterm.obj + +all : vterm.lib + + +.c.obj : + cl /DINLINE= /Iinclude /Fo$@ /c $< + +vterm.lib : $(OBJS) + lib /OUT:$@ $(OBJS) diff --git a/src/proto/gui_gtk_x11.pro b/src/proto/gui_gtk_x11.pro index 124e2ae375..aaf710c172 100644 --- a/src/proto/gui_gtk_x11.pro +++ b/src/proto/gui_gtk_x11.pro @@ -36,6 +36,7 @@ GuiFont gui_mch_get_font(char_u *name, int report_error); char_u *gui_mch_get_fontname(GuiFont font, char_u *name); void gui_mch_free_font(GuiFont font); guicolor_T gui_mch_get_color(char_u *name); +guicolor_T gui_mch_get_rgb_color(int r, int g, int b); void gui_mch_set_fg_color(guicolor_T color); void gui_mch_set_bg_color(guicolor_T color); void gui_mch_set_sp_color(guicolor_T color); @@ -53,7 +54,7 @@ void gui_mch_draw_part_cursor(int w, int h, guicolor_T color); void gui_mch_update(void); int gui_mch_wait_for_chars(long wtime); void gui_mch_flush(void); -void gui_mch_clear_block(int row1, int col1, int row2, int col2); +void gui_mch_clear_block(int row1arg, int col1arg, int row2arg, int col2arg); void gui_mch_clear_all(void); void gui_mch_delete_lines(int row, int num_lines); void gui_mch_insert_lines(int row, int num_lines); diff --git a/src/proto/gui_mac.pro b/src/proto/gui_mac.pro index 9b59f1f484..c7ab982049 100644 --- a/src/proto/gui_mac.pro +++ b/src/proto/gui_mac.pro @@ -47,6 +47,7 @@ void gui_mch_set_font(GuiFont font); int gui_mch_same_font(GuiFont f1, GuiFont f2); void gui_mch_free_font(GuiFont font); guicolor_T gui_mch_get_color(char_u *name); +guicolor_T gui_mch_get_rgb_color(int r, int g, int b); void gui_mch_set_fg_color(guicolor_T color); void gui_mch_set_bg_color(guicolor_T color); void gui_mch_set_sp_color(guicolor_T color); diff --git a/src/proto/gui_photon.pro b/src/proto/gui_photon.pro index 7681b87822..cfa735cf20 100644 --- a/src/proto/gui_photon.pro +++ b/src/proto/gui_photon.pro @@ -28,6 +28,7 @@ void gui_mch_setmouse(int x, int y); guicolor_T gui_mch_get_rgb(guicolor_T pixel); void gui_mch_new_colors(void); guicolor_T gui_mch_get_color(char_u *name); +guicolor_T gui_mch_get_rgb_color(int r, int g, int b); void gui_mch_set_fg_color(guicolor_T color); void gui_mch_set_bg_color(guicolor_T color); void gui_mch_set_sp_color(guicolor_T color); diff --git a/src/proto/gui_w32.pro b/src/proto/gui_w32.pro index 3c99f97e5e..3528b5fa20 100644 --- a/src/proto/gui_w32.pro +++ b/src/proto/gui_w32.pro @@ -21,6 +21,7 @@ GuiFont gui_mch_get_font(char_u *name, int giveErrorIfMissing); char_u *gui_mch_get_fontname(GuiFont font, char_u *name); void gui_mch_free_font(GuiFont font); guicolor_T gui_mch_get_color(char_u *name); +guicolor_T gui_mch_get_rgb_color(int r, int g, int b); int gui_mch_haskey(char_u *name); void gui_mch_beep(void); void gui_mch_invert_rectangle(int r, int c, int nr, int nc); diff --git a/src/proto/gui_x11.pro b/src/proto/gui_x11.pro index 1e4410e318..e490d0cf33 100644 --- a/src/proto/gui_x11.pro +++ b/src/proto/gui_x11.pro @@ -25,6 +25,7 @@ GuiFontset gui_mch_get_fontset(char_u *name, int giveErrorIfMissing, int fixed_w int fontset_height(XFontSet fs); int fontset_height2(XFontSet fs); guicolor_T gui_mch_get_color(char_u *name); +guicolor_T gui_mch_get_rgb_color(int r, int g, int b); void gui_mch_set_fg_color(guicolor_T color); void gui_mch_set_bg_color(guicolor_T color); void gui_mch_set_sp_color(guicolor_T color); diff --git a/src/proto/syntax.pro b/src/proto/syntax.pro index a505ee7a17..be34258341 100644 --- a/src/proto/syntax.pro +++ b/src/proto/syntax.pro @@ -31,6 +31,9 @@ char_u *hl_get_font_name(void); void hl_set_font_name(char_u *font_name); void hl_set_bg_color_name(char_u *name); void hl_set_fg_color_name(char_u *name); +int get_cterm_attr_idx(int attr, int fg, int bg); +int get_tgc_attr_idx(int attr, guicolor_T fg, guicolor_T bg); +int get_gui_attr_idx(int attr, guicolor_T fg, guicolor_T bg); void clear_hl_tables(void); int hl_combine_attr(int char_attr, int prim_attr); attrentry_T *syn_gui_attr2entry(int attr); diff --git a/src/proto/term.pro b/src/proto/term.pro index 9af725ff83..57188e1daa 100644 --- a/src/proto/term.pro +++ b/src/proto/term.pro @@ -24,7 +24,7 @@ void term_append_lines(int line_count); void term_delete_lines(int line_count); void term_set_winpos(int x, int y); int term_get_winpos(int *x, int *y); -void term_set_winsize(int width, int height); +void term_set_winsize(int height, int width); void term_fg_color(int n); void term_bg_color(int n); void term_fg_rgb_color(guicolor_T rgb); @@ -68,4 +68,5 @@ int show_one_termcode(char_u *name, char_u *code, int printit); char_u *translate_mapping(char_u *str, int expmap); void update_tcap(int attr); guicolor_T gui_get_color_cmn(char_u *name); +guicolor_T gui_get_rgb_color_cmn(int r, int g, int b); /* vim: set ft=c : */ diff --git a/src/syntax.c b/src/syntax.c index d39bc919a0..bae93b62f7 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -7909,7 +7909,7 @@ do_highlight( HL_TABLE()[idx].sg_gui_fg = i; # endif vim_free(HL_TABLE()[idx].sg_gui_fg_name); - if (STRCMP(arg, "NONE")) + if (STRCMP(arg, "NONE") != 0) HL_TABLE()[idx].sg_gui_fg_name = vim_strsave(arg); else HL_TABLE()[idx].sg_gui_fg_name = NULL; @@ -8781,6 +8781,58 @@ get_attr_entry(garray_T *table, attrentry_T *aep) return (table->ga_len - 1 + ATTR_OFF); } +/* + * Get an attribute index for a cterm entry. + * Uses an existing entry when possible or adds one when needed. + */ + int +get_cterm_attr_idx(int attr, int fg, int bg) +{ + attrentry_T at_en; + + vim_memset(&at_en, 0, sizeof(attrentry_T)); + at_en.ae_attr = attr; + at_en.ae_u.cterm.fg_color = fg; + at_en.ae_u.cterm.bg_color = bg; + return get_attr_entry(&cterm_attr_table, &at_en); +} + +#if defined(FEAT_TERMGUICOLORS) || defined(PROTO) +/* + * Get an attribute index for a 'termguicolors' entry. + * Uses an existing entry when possible or adds one when needed. + */ + int +get_tgc_attr_idx(int attr, guicolor_T fg, guicolor_T bg) +{ + attrentry_T at_en; + + vim_memset(&at_en, 0, sizeof(attrentry_T)); + at_en.ae_attr = attr; + at_en.ae_u.cterm.fg_rgb = fg; + at_en.ae_u.cterm.bg_rgb = bg; + return get_attr_entry(&cterm_attr_table, &at_en); +} +#endif + +#if defined(FEAT_GUI) || defined(PROTO) +/* + * Get an attribute index for a cterm entry. + * Uses an existing entry when possible or adds one when needed. + */ + int +get_gui_attr_idx(int attr, guicolor_T fg, guicolor_T bg) +{ + attrentry_T at_en; + + vim_memset(&at_en, 0, sizeof(attrentry_T)); + at_en.ae_attr = attr; + at_en.ae_u.gui.fg_color = fg; + at_en.ae_u.gui.bg_color = bg; + return get_attr_entry(&gui_attr_table, &at_en); +} +#endif + /* * Clear all highlight tables. */ diff --git a/src/term.c b/src/term.c index e5162afc0a..12d0fbff72 100644 --- a/src/term.c +++ b/src/term.c @@ -6405,4 +6405,14 @@ gui_get_color_cmn(char_u *name) return INVALCOLOR; } + + guicolor_T +gui_get_rgb_color_cmn(int r, int g, int b) +{ + guicolor_T color = RGB(r, g, b); + + if (color > 0xffffff) + return INVALCOLOR; + return color; +} #endif diff --git a/src/terminal.c b/src/terminal.c index f3cb124280..3f1a91d154 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -33,6 +33,7 @@ * while, if the terminal window is visible, the screen contents is drawn. * * TODO: + * - cursor flickers when moving the cursor * - set buffer options to be scratch, hidden, nomodifiable, etc. * - set buffer name to command, add (1) to avoid duplicates. * - Add a scrollback buffer (contains lines to scroll off the top). @@ -116,6 +117,7 @@ static term_T *first_term = NULL; * Functions with separate implementation for MS-Windows and Unix-like systems. */ static int term_and_job_init(term_T *term, int rows, int cols, char_u *cmd); +static void term_report_winsize(term_T *term, int rows, int cols); static void term_free(term_T *term); /************************************** @@ -586,6 +588,164 @@ handle_resize(int rows, int cols, void *user) return 1; } +/* + * Reverse engineer the RGB value into a cterm color index. + * First color is 1. Return 0 if no match found. + */ + static int +color2index(VTermColor *color) +{ + int red = color->red; + int blue = color->blue; + int green = color->green; + + if (red == 0) + { + if (green == 0) + { + if (blue == 0) + return 1; /* black */ + if (blue == 224) + return 5; /* blue */ + } + else if (green == 224) + { + if (blue == 0) + return 3; /* green */ + if (blue == 224) + return 7; /* cyan */ + } + } + else if (red == 224) + { + if (green == 0) + { + if (blue == 0) + return 2; /* red */ + if (blue == 224) + return 6; /* magenta */ + } + else if (green == 224) + { + if (blue == 0) + return 4; /* yellow */ + if (blue == 224) + return 8; /* white */ + } + } + else if (red == 128) + { + if (green == 128 && blue == 128) + return 9; /* high intensity bladk */ + } + else if (red == 255) + { + if (green == 64) + { + if (blue == 64) + return 10; /* high intensity red */ + if (blue == 255) + return 14; /* high intensity magenta */ + } + else if (green == 255) + { + if (blue == 64) + return 12; /* high intensity yellow */ + if (blue == 255) + return 16; /* high intensity white */ + } + } + else if (red == 64) + { + if (green == 64) + { + if (blue == 255) + return 13; /* high intensity blue */ + } + else if (green == 255) + { + if (blue == 64) + return 11; /* high intensity green */ + if (blue == 255) + return 15; /* high intensity cyan */ + } + } + if (t_colors >= 256) + { + if (red == blue && red == green) + { + /* 24-color greyscale */ + static int cutoff[23] = { + 0x05, 0x10, 0x1B, 0x26, 0x31, 0x3C, 0x47, 0x52, + 0x5D, 0x68, 0x73, 0x7F, 0x8A, 0x95, 0xA0, 0xAB, + 0xB6, 0xC1, 0xCC, 0xD7, 0xE2, 0xED, 0xF9}; + int i; + + for (i = 0; i < 23; ++i) + if (red < cutoff[i]) + return i + 233; + return 256; + } + + /* 216-color cube */ + return 17 + ((red + 25) / 0x33) * 36 + + ((green + 25) / 0x33) * 6 + + (blue + 25) / 0x33; + } + return 0; +} + +/* + * Convert the attributes of a vterm cell into an attribute index. + */ + static int +cell2attr(VTermScreenCell *cell) +{ + int attr = 0; + + if (cell->attrs.bold) + attr |= HL_BOLD; + if (cell->attrs.underline) + attr |= HL_UNDERLINE; + if (cell->attrs.italic) + attr |= HL_ITALIC; + if (cell->attrs.strike) + attr |= HL_STANDOUT; + if (cell->attrs.reverse) + attr |= HL_INVERSE; + if (cell->attrs.strike) + attr |= HL_UNDERLINE; + +#ifdef FEAT_GUI + if (gui.in_use) + { + guicolor_T fg, bg; + + fg = gui_mch_get_rgb_color(cell->fg.red, cell->fg.green, cell->fg.blue); + bg = gui_mch_get_rgb_color(cell->bg.red, cell->bg.green, cell->bg.blue); + return get_gui_attr_idx(attr, fg, bg); + } + else +#endif +#ifdef FEAT_TERMGUICOLORS + if (p_tgc) + { + guicolor_T fg, bg; + + fg = gui_get_rgb_color_cmn(cell->fg.red, cell->fg.green, cell->fg.blue); + bg = gui_get_rgb_color_cmn(cell->bg.red, cell->bg.green, cell->bg.blue); + + return get_tgc_attr_idx(attr, fg, bg); + } + else +#endif + { + return get_cterm_attr_idx(attr, color2index(&cell->fg), + color2index(&cell->bg)); + } + return 0; +} + /* * Called to update the window that contains the terminal. */ @@ -611,24 +771,7 @@ term_update_window(win_T *wp) vterm_set_size(vterm, rows, cols); ch_logn(term->tl_job->jv_channel, "Resizing terminal to %d lines", rows); - -#if defined(UNIX) - /* Use an ioctl() to report the new window size to the job. */ - if (term->tl_job != NULL && term->tl_job->jv_channel != NULL) - { - int fd = -1; - int part; - - for (part = PART_OUT; part < PART_COUNT; ++part) - { - fd = term->tl_job->jv_channel->ch_part[part].ch_fd; - if (isatty(fd)) - break; - } - if (part < PART_COUNT && mch_report_winsize(fd, rows, cols) == OK) - mch_stop_job(term->tl_job, (char_u *)"winch"); - } -#endif + term_report_winsize(term, rows, cols); } /* The cursor may have been moved when resizing. */ @@ -648,7 +791,10 @@ term_update_window(win_T *wp) VTermScreenCell cell; int c; - vterm_screen_get_cell(screen, pos, &cell); + if (vterm_screen_get_cell(screen, pos, &cell) == 0) + vim_memset(&cell, 0, sizeof(cell)); + + /* TODO: composing chars */ c = cell.chars[0]; if (c == NUL) { @@ -672,8 +818,7 @@ term_update_window(win_T *wp) ScreenLines[off] = c; #endif } - /* TODO: use cell.attrs and colors */ - ScreenAttrs[off] = 0; + ScreenAttrs[off] = cell2attr(&cell); ++pos.col; ++off; @@ -731,6 +876,18 @@ create_vterm(term_T *term, int rows, int cols) vterm_screen_set_callbacks(screen, &screen_callbacks, term); /* TODO: depends on 'encoding'. */ vterm_set_utf8(vterm, 1); + + /* Vterm uses a default black background. Set it to white when + * 'background' is "light". */ + if (*p_bg == 'l') + { + VTermColor fg, bg; + + fg.red = fg.green = fg.blue = 0; + bg.red = bg.green = bg.blue = 255; + vterm_state_set_default_colors(vterm_obtain_state(vterm), &fg, &bg); + } + /* Required to initialize most things. */ vterm_screen_reset(screen, 1 /* hard */); } @@ -753,6 +910,7 @@ void (*winpty_config_free)(void*); void (*winpty_spawn_config_free)(void*); void (*winpty_error_free)(void*); LPCWSTR (*winpty_error_msg)(void*); +BOOL (*winpty_set_size)(void*, int, int, void*); /************************************** * 2. MS-Windows implementation. @@ -785,6 +943,7 @@ dyn_winpty_init(void) {"winpty_spawn_config_free", (FARPROC*)&winpty_spawn_config_free}, {"winpty_spawn_config_new", (FARPROC*)&winpty_spawn_config_new}, {"winpty_error_msg", (FARPROC*)&winpty_error_msg}, + {"winpty_set_size", (FARPROC*)&winpty_set_size}, {NULL, NULL} }; @@ -916,13 +1075,19 @@ failed: if (channel != NULL) channel_clear(channel); if (job != NULL) + { + job->jv_channel = NULL; job_cleanup(job); + } + term->tl_job = NULL; if (jo != NULL) CloseHandle(jo); if (term->tl_winpty != NULL) winpty_free(term->tl_winpty); + term->tl_winpty = NULL; if (term->tl_winpty_config != NULL) winpty_config_free(term->tl_winpty_config); + term->tl_winpty_config = NULL; if (winpty_err != NULL) { char_u *msg = utf16_to_enc( @@ -940,9 +1105,21 @@ failed: static void term_free(term_T *term) { - winpty_free(term->tl_winpty); - winpty_config_free(term->tl_winpty_config); - vterm_free(term->tl_vterm); + if (term->tl_winpty != NULL) + winpty_free(term->tl_winpty); + if (term->tl_winpty_config != NULL) + winpty_config_free(term->tl_winpty_config); + if (term->tl_vterm != NULL) + vterm_free(term->tl_vterm); +} + +/* + * Request size to terminal. + */ + static void +term_report_winsize(term_T *term, int rows, int cols) +{ + winpty_set_size(term->tl_winpty, cols, rows, NULL); } # else @@ -981,8 +1158,33 @@ term_and_job_init(term_T *term, int rows, int cols, char_u *cmd) static void term_free(term_T *term) { - vterm_free(term->tl_vterm); + if (term->tl_vterm != NULL) + vterm_free(term->tl_vterm); } + +/* + * Request size to terminal. + */ + static void +term_report_winsize(term_T *term, int rows, int cols) +{ + /* Use an ioctl() to report the new window size to the job. */ + if (term->tl_job != NULL && term->tl_job->jv_channel != NULL) + { + int fd = -1; + int part; + + for (part = PART_OUT; part < PART_COUNT; ++part) + { + fd = term->tl_job->jv_channel->ch_part[part].ch_fd; + if (isatty(fd)) + break; + } + if (part < PART_COUNT && mch_report_winsize(fd, rows, cols) == OK) + mch_stop_job(term->tl_job, (char_u *)"winch"); + } +} + # endif #endif /* FEAT_TERMINAL */ diff --git a/src/version.c b/src/version.c index f0bcb71c9c..befc80a129 100644 --- a/src/version.c +++ b/src/version.c @@ -784,6 +784,20 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 760, +/**/ + 759, +/**/ + 758, +/**/ + 757, +/**/ + 756, +/**/ + 755, +/**/ + 754, /**/ 753, /**/