Patch 8.1.0870
Problem: Vim doesn't use the new ConPTY support in Windows 10.
Solution: Use ConPTY support, if available. (Nobuhiro Takasaki, closes #3794)
Files: runtime/doc/eval.txt, runtime/doc/options.txt,
runtime/doc/terminal.txt, src/channel.c, src/evalfunc.c,
src/globals.h, src/option.c, src/option.h, src/os_win32.c,
src/proto/terminal.pro, src/structs.h, src/terminal.c,
src/testdir/gen_opt_test.vim, src/testdir/test_autocmd.vim,
src/testdir/test_mksession.vim, src/testdir/test_terminal.vim
*** ../vim-8.1.0869/runtime/doc/eval.txt 2019-01-31 15:52:05.265907656
+0100
--- runtime/doc/eval.txt 2019-02-03 13:52:16.589856140 +0100
***************
*** 9410,9415 ****
--- 9469,9478 ----
"ansi_colors" A list of 16 color names or hex codes
defining the ANSI palette used in GUI
color modes. See |g:terminal_ansi_colors|.
+ "term_mode" (MS-Windows only): Specify which pty to
+ use:
+ "winpty": Use winpty
+ "conpty": Use ConPTY (if available)
{only available when compiled with the |+terminal| feature}
***************
*** 10126,10133 ****
--- 10190,10199 ----
cmdline_info Compiled with 'showcmd' and 'ruler' support.
comments Compiled with |'comments'| support.
compatible Compiled to be very Vi compatible.
+ conpty Platform where |ConPTY| can be used.
cryptv Compiled with encryption support |encryption|.
cscope Compiled with |cscope| support.
+ cursorbind Compiled with |cursorbind| (always true)
debug Compiled with "DEBUG" defined.
dialog_con Compiled with console dialog support.
dialog_gui Compiled with GUI dialog support.
*** ../vim-8.1.0869/runtime/doc/options.txt 2019-01-31 18:26:05.730803572
+0100
--- runtime/doc/options.txt 2019-02-03 14:35:38.054496226 +0100
***************
*** 8009,8014 ****
--- 8054,8076 ----
Note that the "cterm" attributes are still used, not the "gui" ones.
NOTE: This option is reset when 'compatible' is set.
+ *'termmode'* *'tmod'*
+ 'termmode' 'tmod' string (default "")
+ local to window
+ {not in Vi, MS-Windows only}
+ Whether the window uses winpty or |ConPTY| as the virtual console.
+ When set before opening the terminal, it influences what pty is used.
+ When opening the terminal it will be set to the actually used pty.
+
+ Possible values are:
+ "" use ConPTY if possible, winpty otherwise
+ "winpty" use winpty, fail if not supported
+ "conpty" use |ConPTY|, fail if not supported
+
+ |ConPTY| support depends on the platform (Windows 10 October 2018
+ edition). winpty support needs to be installed. If neither is
+ supported then you cannot open a terminal window.
+
*'termwinscroll'* *'twsl'*
'termwinscroll' 'twsl' number (default 10000)
local to buffer
*** ../vim-8.1.0869/runtime/doc/terminal.txt 2018-10-19 22:35:04.885189994
+0200
--- runtime/doc/terminal.txt 2019-02-03 13:53:49.233271142 +0100
***************
*** 228,234 ****
for Python "++eof=exit()". Special
codes can be used like with `:map`,
e.g. "<C-Z>" for CTRL-Z.
!
If you want to use more options use the |term_start()|
function.
If you want to split the window vertically, use: >
--- 228,235 ----
for Python "++eof=exit()". Special
codes can be used like with `:map`,
e.g. "<C-Z>" for CTRL-Z.
! ++winpty Use winpty as the virtual console.
! ++conpty Use |ConPTY| as the virtual console.
If you want to use more options use the |term_start()|
function.
If you want to split the window vertically, use: >
***************
*** 410,415 ****
--- 411,423 ----
to point to the right file, if needed. If you have both the 32-bit and 64-bit
version, rename to winpty32.dll and winpty64.dll to match the way Vim was
build.
+ *ConPTY*
+ On more recent versions of MS-Windows 10 (beginning with the "October 2018
+ Update"), winpty is no longer required. On those versions, |:terminal| will
use
+ Windows' built-in support for hosting terminal applications, "ConPTY". When
+ ConPTY is in use, there may be rendering artifacts regarding ambiguous-width
+ characters. If you encounter any such issues, set 'termmode' to winpty (which
+ you then must have instlled).
Environment variables are used to pass information to the running job:
VIM_SERVERNAME v:servername
*** ../vim-8.1.0869/src/channel.c 2019-01-31 15:52:05.265907656 +0100
--- src/channel.c 2019-02-03 14:13:11.701910368 +0100
***************
*** 1720,1730 ****
char_u *res;
char_u *p;
! /* If there is only one buffer just get that one. */
! if (head->rq_next == NULL || head->rq_next->rq_next == NULL)
! return channel_get(channel, part, outlen);
!
! /* Concatenate everything into one buffer. */
for (node = head->rq_next; node != NULL; node = node->rq_next)
len += node->rq_buflen;
res = lalloc(len + 1, TRUE);
--- 1720,1726 ----
char_u *res;
char_u *p;
! // Concatenate everything into one buffer.
for (node = head->rq_next; node != NULL; node = node->rq_next)
len += node->rq_buflen;
res = lalloc(len + 1, TRUE);
***************
*** 1738,1744 ****
}
*p = NUL;
! /* Free all buffers */
do
{
p = channel_get(channel, part, NULL);
--- 1734,1740 ----
}
*p = NUL;
! // Free all buffers
do
{
p = channel_get(channel, part, NULL);
***************
*** 1747,1762 ****
if (outlen != NULL)
{
*outlen += len;
return res;
}
! /* turn all NUL into NL */
! while (len > 0)
{
! --len;
! if (res[len] == NUL)
! res[len] = NL;
}
return res;
--- 1743,1779 ----
if (outlen != NULL)
{
+ // Returning the length, keep NUL characters.
*outlen += len;
return res;
}
! // Turn all NUL into NL, so that the result can be used as a string.
! p = res;
! while (p < res + len)
{
! if (*p == NUL)
! *p = NL;
! #ifdef WIN32
! else if (*p == 0x1b)
! {
! // crush the escape sequence OSC 0/1/2: ESC ]0;
! if (p + 3 < res + len
! && p[1] == ']'
! && (p[2] == '0' || p[2] == '1' || p[2] == '2')
! && p[3] == ';')
! {
! // '\a' becomes a NL
! while (p < res + (len - 1) && *p != '\a')
! ++p;
! // BEL is zero width characters, suppress display mistake
! // ConPTY (after 10.0.18317) requires advance checking
! if (p[-1] == NUL)
! p[-1] = 0x07;
! }
! }
! #endif
! ++p;
}
return res;
***************
*** 4330,4336 ****
channel = first_channel;
continue;
}
! if (channel->ch_to_be_freed)
{
channel_free(channel);
/* channel has been freed, start over */
--- 4347,4353 ----
channel = first_channel;
continue;
}
! if (channel->ch_to_be_freed || channel->ch_killing)
{
channel_free(channel);
/* channel has been freed, start over */
***************
*** 4930,4935 ****
--- 4947,4974 ----
opt->jo_set2 |= JO2_TERM_KILL;
opt->jo_term_kill = tv_get_string_chk(item);
}
+ else if (STRCMP(hi->hi_key, "term_mode") == 0)
+ {
+ char_u *p;
+
+ if (!(supported2 & JO2_TERM_MODE))
+ break;
+ opt->jo_set2 |= JO2_TERM_MODE;
+ p = tv_get_string_chk(item);
+ if (p == NULL)
+ {
+ semsg(_(e_invargval), "term_mode");
+ return FAIL;
+ }
+ // Allow empty string, "winpty", "conpty".
+ if (!(*p == NUL || STRCMP(p, "winpty") == 0
+ || STRCMP(p, "conpty") == 0))
+ {
+ semsg(_(e_invargval), "term_mode");
+ return FAIL;
+ }
+ opt->jo_term_mode = p[0];
+ }
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
else if (STRCMP(hi->hi_key, "ansi_colors") == 0)
{
***************
*** 5440,5445 ****
--- 5479,5494 ----
channel_need_redraw = TRUE;
}
+ if (job->jv_channel != NULL
+ && job->jv_channel->ch_anonymous_pipe && !job->jv_channel->ch_killing)
+ {
+ ++safe_to_invoke_callback;
+ channel_free_contents(job->jv_channel);
+ job->jv_channel->ch_job = NULL;
+ job->jv_channel = NULL;
+ --safe_to_invoke_callback;
+ }
+
// Do not free the job in case the close callback of the associated
channel
// isn't invoked yet and may get information by job_info().
if (job->jv_refcount == 0 && !job_channel_still_useful(job))
*** ../vim-8.1.0869/src/evalfunc.c 2019-01-30 22:01:36.982854408 +0100
--- src/evalfunc.c 2019-02-03 13:46:59.595853343 +0100
***************
*** 6738,6743 ****
--- 6738,6747 ----
else if (STRICMP(name, "terminal") == 0)
n = terminal_enabled();
#endif
+ #if defined(FEAT_TERMINAL) && defined(WIN3264)
+ else if (STRICMP(name, "conpty") == 0)
+ n = use_conpty();
+ #endif
}
rettv->vval.v_number = n;
*** ../vim-8.1.0869/src/globals.h 2019-01-26 17:28:22.224599141 +0100
--- src/globals.h 2019-02-03 13:46:59.595853343 +0100
***************
*** 1432,1438 ****
|| defined(DYNAMIC_ICONV) \
|| defined(DYNAMIC_GETTEXT) \
|| defined(DYNAMIC_MZSCHEME) \
! || defined(DYNAMIC_LUA)
EXTERN char e_loadlib[] INIT(= N_("E370: Could not load library %s"));
EXTERN char e_loadfunc[] INIT(= N_("E448: Could not load library
function %s"));
#endif
--- 1432,1439 ----
|| defined(DYNAMIC_ICONV) \
|| defined(DYNAMIC_GETTEXT) \
|| defined(DYNAMIC_MZSCHEME) \
! || defined(DYNAMIC_LUA) \
! || defined(FEAT_TERMINAL)
EXTERN char e_loadlib[] INIT(= N_("E370: Could not load library %s"));
EXTERN char e_loadfunc[] INIT(= N_("E448: Could not load library
function %s"));
#endif
*** ../vim-8.1.0869/src/option.c 2019-01-31 18:26:05.738803509 +0100
--- src/option.c 2019-02-03 14:16:43.164569746 +0100
***************
*** 253,258 ****
--- 253,259 ----
# define PV_TWK OPT_WIN(WV_TWK)
# define PV_TWS OPT_WIN(WV_TWS)
# define PV_TWSL OPT_BUF(BV_TWSL)
+ # define PV_TMOD OPT_WIN(WV_TMOD)
#endif
#ifdef FEAT_SIGNS
# define PV_SCL OPT_WIN(WV_SCL)
***************
*** 2700,2705 ****
--- 2701,2715 ----
{(char_u *)FALSE, (char_u *)FALSE}
#endif
SCTX_INIT},
+ {"termmode", "tmod", P_STRING|P_ALLOCED|P_VI_DEF,
+ #ifdef FEAT_TERMINAL
+ (char_u *)VAR_WIN, PV_TMOD,
+ {(char_u *)"", (char_u *)NULL}
+ #else
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)NULL, (char_u *)0L}
+ #endif
+ SCTX_INIT},
{"termwinkey", "twk", P_STRING|P_ALLOCED|P_RWIN|P_VI_DEF,
#ifdef FEAT_TERMINAL
(char_u *)VAR_WIN, PV_TWK,
***************
*** 3208,3213 ****
--- 3218,3226 ----
#ifdef FEAT_SIGNS
static char *(p_scl_values[]) = {"yes", "no", "auto", NULL};
#endif
+ #ifdef FEAT_TERMINAL
+ static char *(p_tmod_values[]) = {"winpty", "conpty", "", NULL};
+ #endif
static void set_options_default(int opt_flags);
static void set_string_default_esc(char *name, char_u *val, int escape);
***************
*** 3661,3667 ****
{
char buf[50];
! sprintf(buf, "cp%ld", (long)GetConsoleCP());
p_tenc = vim_strsave((char_u *)buf);
if (p_tenc != NULL)
{
--- 3674,3685 ----
{
char buf[50];
! /* Win32 console: In ConPTY, GetConsoleCP() returns zero.
! * Use an alternative value. */
! if (GetConsoleCP() == 0)
! sprintf(buf, "cp%ld", (long)GetACP());
! else
! sprintf(buf, "cp%ld", (long)GetConsoleCP());
p_tenc = vim_strsave((char_u *)buf);
if (p_tenc != NULL)
{
***************
*** 7468,7481 ****
#endif
#ifdef FEAT_TERMINAL
! /* 'termwinkey' */
else if (varp == &curwin->w_p_twk)
{
if (*curwin->w_p_twk != NUL
&& string_to_key(curwin->w_p_twk, TRUE) == 0)
errmsg = e_invarg;
}
! /* 'termwinsize' */
else if (varp == &curwin->w_p_tws)
{
if (*curwin->w_p_tws != NUL)
--- 7486,7499 ----
#endif
#ifdef FEAT_TERMINAL
! // 'termwinkey'
else if (varp == &curwin->w_p_twk)
{
if (*curwin->w_p_twk != NUL
&& string_to_key(curwin->w_p_twk, TRUE) == 0)
errmsg = e_invarg;
}
! // 'termwinsize'
else if (varp == &curwin->w_p_tws)
{
if (*curwin->w_p_tws != NUL)
***************
*** 7487,7492 ****
--- 7505,7516 ----
errmsg = e_invarg;
}
}
+ // 'termmode'
+ else if (varp == &curwin->w_p_tmod)
+ {
+ if (check_opt_strings(*varp, p_tmod_values, FALSE) != OK)
+ errmsg = e_invarg;
+ }
#endif
#ifdef FEAT_VARTABS
***************
*** 8838,8844 ****
if (!has_vtp_working())
{
p_tgc = 0;
! return (char_u*)N_("E954: 24-bit colors are not supported on this
environment");
}
if (is_term_win32())
swap_tcap();
--- 8862,8868 ----
if (!has_vtp_working())
{
p_tgc = 0;
! return N_("E954: 24-bit colors are not supported on this
environment");
}
if (is_term_win32())
swap_tcap();
***************
*** 10928,10933 ****
--- 10952,10958 ----
case PV_TWK: return (char_u *)&(curwin->w_p_twk);
case PV_TWS: return (char_u *)&(curwin->w_p_tws);
case PV_TWSL: return (char_u *)&(curbuf->b_p_twsl);
+ case PV_TMOD: return (char_u *)&(curwin->w_p_tmod);
#endif
case PV_AI: return (char_u *)&(curbuf->b_p_ai);
***************
*** 11128,11133 ****
--- 11153,11159 ----
#ifdef FEAT_TERMINAL
to->wo_twk = vim_strsave(from->wo_twk);
to->wo_tws = vim_strsave(from->wo_tws);
+ to->wo_tmod = vim_strsave(from->wo_tmod);
#endif
#ifdef FEAT_FOLDING
to->wo_fdc = from->wo_fdc;
***************
*** 11198,11203 ****
--- 11224,11230 ----
#ifdef FEAT_TERMINAL
check_string_option(&wop->wo_twk);
check_string_option(&wop->wo_tws);
+ check_string_option(&wop->wo_tmod);
#endif
#ifdef FEAT_LINEBREAK
check_string_option(&wop->wo_briopt);
***************
*** 11241,11246 ****
--- 11268,11274 ----
#ifdef FEAT_TERMINAL
clear_string_option(&wop->wo_twk);
clear_string_option(&wop->wo_tws);
+ clear_string_option(&wop->wo_tmod);
#endif
}
*** ../vim-8.1.0869/src/option.h 2019-01-31 18:26:05.738803509 +0100
--- src/option.h 2019-02-03 13:46:59.599853319 +0100
***************
*** 1112,1117 ****
--- 1112,1118 ----
#ifdef FEAT_TERMINAL
, WV_TWK
, WV_TWS
+ , WV_TMOD
#endif
, WV_CRBIND
#ifdef FEAT_LINEBREAK
*** ../vim-8.1.0869/src/os_win32.c 2019-01-24 23:11:44.631650199 +0100
--- src/os_win32.c 2019-02-03 13:46:59.599853319 +0100
***************
*** 186,193 ****
static int win32_setattrs(char_u *name, int attrs);
static int win32_set_archive(char_u *name);
- #ifndef FEAT_GUI_W32
static int vtp_working = 0;
static void vtp_init();
static void vtp_exit();
static int vtp_printf(char *format, ...);
--- 186,195 ----
static int win32_setattrs(char_u *name, int attrs);
static int win32_set_archive(char_u *name);
static int vtp_working = 0;
+ static void vtp_flag_init();
+
+ #ifndef FEAT_GUI_W32
static void vtp_init();
static void vtp_exit();
static int vtp_printf(char *format, ...);
***************
*** 247,252 ****
--- 249,255 ----
typedef BOOL (WINAPI *PfnSetConsoleScreenBufferInfoEx)(HANDLE,
PDYN_CONSOLE_SCREEN_BUFFER_INFOEX);
static PfnSetConsoleScreenBufferInfoEx pSetConsoleScreenBufferInfoEx;
static BOOL has_csbiex = FALSE;
+ #endif
/*
* Get version number including build number
***************
*** 276,282 ****
return ver;
}
!
/*
* Version of ReadConsoleInput() that works with IME.
* Works around problems on Windows 8.
--- 279,285 ----
return ver;
}
! #ifndef FEAT_GUI_W32
/*
* Version of ReadConsoleInput() that works with IME.
* Works around problems on Windows 8.
***************
*** 1508,1516 ****
/* Wait forever. */
dwEndTime = INFINITE;
! /* We need to loop until the end of the time period, because
! * we might get multiple unusable mouse events in that time.
! */
for (;;)
{
// Only process messages when waiting.
--- 1511,1518 ----
/* Wait forever. */
dwEndTime = INFINITE;
! // We need to loop until the end of the time period, because
! // we might get multiple unusable mouse events in that time.
for (;;)
{
// Only process messages when waiting.
***************
*** 2175,2180 ****
--- 2177,2184 ----
#ifdef FEAT_CLIPBOARD
win_clip_init();
#endif
+
+ vtp_flag_init();
}
***************
*** 2675,2680 ****
--- 2679,2685 ----
win_clip_init();
#endif
+ vtp_flag_init();
vtp_init();
}
***************
*** 5683,5689 ****
--- 5688,5698 ----
{
/* deadly signal */
if (job->jv_job_object != NULL)
+ {
+ if (job->jv_channel != NULL && job->jv_channel->ch_anonymous_pipe)
+ job->jv_channel->ch_killing = TRUE;
return TerminateJobObject(job->jv_job_object, 0) ? OK : FAIL;
+ }
return terminate_all(job->jv_proc_info.hProcess, 0) ? OK : FAIL;
}
***************
*** 7621,7651 ****
return 0;
}
- #ifndef FEAT_GUI_W32
-
/*
* Support for 256 colors and 24-bit colors was added in Windows 10
* version 1703 (Creators update).
*/
! # define VTP_FIRST_SUPPORT_BUILD MAKE_VER(10, 0, 15063)
static void
vtp_init(void)
{
- DWORD ver, mode;
HMODULE hKerneldll;
DYN_CONSOLE_SCREEN_BUFFER_INFOEX csbi;
# ifdef FEAT_TERMGUICOLORS
COLORREF fg, bg;
# endif
- ver = get_build_number();
- vtp_working = (ver >= VTP_FIRST_SUPPORT_BUILD) ? 1 : 0;
- GetConsoleMode(g_hConOut, &mode);
- mode |= (ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
- if (SetConsoleMode(g_hConOut, mode) == 0)
- vtp_working = 0;
-
/* Use functions supported from Vista */
hKerneldll = GetModuleHandle("kernel32.dll");
if (hKerneldll != NULL)
--- 7630,7682 ----
return 0;
}
/*
* Support for 256 colors and 24-bit colors was added in Windows 10
* version 1703 (Creators update).
*/
! #define VTP_FIRST_SUPPORT_BUILD MAKE_VER(10, 0, 15063)
!
! /*
! * Support for pseudo-console (ConPTY) was added in windows 10
! * version 1809 (October 2018 update).
! */
! #define CONPTY_FIRST_SUPPORT_BUILD MAKE_VER(10, 0, 17763)
!
! static void
! vtp_flag_init(void)
! {
! DWORD ver = get_build_number();
! #ifndef FEAT_GUI_W32
! DWORD mode;
! HANDLE out;
!
! out = GetStdHandle(STD_OUTPUT_HANDLE);
!
! vtp_working = (ver >= VTP_FIRST_SUPPORT_BUILD) ? 1 : 0;
! GetConsoleMode(out, &mode);
! mode |= (ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
! if (SetConsoleMode(out, mode) == 0)
! vtp_working = 0;
! #endif
!
! #ifdef FEAT_GUI_W32
! if (ver >= CONPTY_FIRST_SUPPORT_BUILD)
! vtp_working = 1;
! #endif
!
! }
!
! #ifndef FEAT_GUI_W32
static void
vtp_init(void)
{
HMODULE hKerneldll;
DYN_CONSOLE_SCREEN_BUFFER_INFOEX csbi;
# ifdef FEAT_TERMGUICOLORS
COLORREF fg, bg;
# endif
/* Use functions supported from Vista */
hKerneldll = GetModuleHandle("kernel32.dll");
if (hKerneldll != NULL)
***************
*** 7829,7840 ****
}
int
- has_vtp_working(void)
- {
- return vtp_working;
- }
-
- int
use_vtp(void)
{
return USE_VTP;
--- 7860,7865 ----
***************
*** 7847,7849 ****
--- 7872,7880 ----
}
#endif
+
+ int
+ has_vtp_working(void)
+ {
+ return vtp_working;
+ }
*** ../vim-8.1.0869/src/proto/terminal.pro 2019-01-29 22:29:03.550799929
+0100
--- src/proto/terminal.pro 2019-02-03 13:46:59.599853319 +0100
***************
*** 57,60 ****
--- 57,62 ----
void term_send_eof(channel_T *ch);
job_T *term_getjob(term_T *term);
int terminal_enabled(void);
+ void term_free_conpty(term_T *term);
+ int use_conpty(void);
/* vim: set ft=c : */
*** ../vim-8.1.0869/src/structs.h 2019-01-31 18:26:05.738803509 +0100
--- src/structs.h 2019-02-03 14:13:33.145774428 +0100
***************
*** 282,287 ****
--- 282,289 ----
# define w_p_twk w_onebuf_opt.wo_twk /* 'termwinkey' */
char_u *wo_tws;
# define w_p_tws w_onebuf_opt.wo_tws /* 'termwinsize' */
+ char_u *wo_tmod;
+ # define w_p_tmod w_onebuf_opt.wo_tmod /* 'termmode' */
#endif
#ifdef FEAT_EVAL
***************
*** 1728,1740 ****
int ch_keep_open; /* do not close on read error */
int ch_nonblock;
! job_T *ch_job; /* Job that uses this channel; this does not
! * count as a reference to avoid a circular
! * reference, the job refers to the channel. */
! int ch_job_killed; /* TRUE when there was a job and it was
killed
! * or we know it died. */
! int ch_refcount; /* reference count */
int ch_copyID;
};
--- 1730,1744 ----
int ch_keep_open; /* do not close on read error */
int ch_nonblock;
! job_T *ch_job; // Job that uses this channel; this does not
! // count as a reference to avoid a circular
! // reference, the job refers to the channel.
! int ch_job_killed; // TRUE when there was a job and it was
killed
! // or we know it died.
! int ch_anonymous_pipe; // ConPTY
! int ch_killing; // TerminateJobObject() was called
! int ch_refcount; // reference count
int ch_copyID;
};
***************
*** 1787,1792 ****
--- 1791,1797 ----
#define JO2_NORESTORE 0x2000 /* "norestore" */
#define JO2_TERM_KILL 0x4000 /* "term_kill" */
#define JO2_ANSI_COLORS 0x8000 /* "ansi_colors" */
+ #define JO2_TERM_MODE 0x10000 /* "term_mode" */
#define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE)
#define JO_CB_ALL \
***************
*** 1859,1864 ****
--- 1864,1870 ----
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
long_u jo_ansi_colors[16];
# endif
+ int jo_term_mode; // first character of "term_mode"
#endif
} jobopt_T;
*** ../vim-8.1.0869/src/terminal.c 2019-01-29 23:06:50.097182305 +0100
--- src/terminal.c 2019-02-03 14:48:39.219131609 +0100
***************
*** 65,70 ****
--- 65,87 ----
cellattr_T sb_fill_attr; /* for short line */
} sb_line_T;
+ #ifdef WIN3264
+ # ifndef HPCON
+ # define HPCON VOID*
+ # endif
+ # ifndef EXTENDED_STARTUPINFO_PRESENT
+ # define EXTENDED_STARTUPINFO_PRESENT 0x00080000
+ # endif
+ # ifndef PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE
+ # define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE 0x00020016
+ # endif
+ typedef struct _DYN_STARTUPINFOEXW
+ {
+ STARTUPINFOW StartupInfo;
+ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
+ } DYN_STARTUPINFOEXW, *PDYN_STARTUPINFOEXW;
+ #endif
+
/* typedef term_T in structs.h */
struct terminal_S {
term_T *tl_next;
***************
*** 92,101 ****
--- 109,123 ----
char_u *tl_opencmd;
char_u *tl_eof_chars;
+ char_u *tl_arg0_cmd; // To format the status bar
+
#ifdef WIN3264
void *tl_winpty_config;
void *tl_winpty;
+ HPCON tl_conpty;
+ DYN_STARTUPINFOEXW tl_siex; // Structure that always needs to be
hold
+
FILE *tl_out_fd;
#endif
#if defined(FEAT_SESSION)
***************
*** 147,152 ****
--- 169,179 ----
/* Terminal active in terminal_loop(). */
static term_T *in_terminal_loop = NULL;
+ #ifdef WIN3264
+ static BOOL has_winpty = FALSE;
+ static BOOL has_conpty = FALSE;
+ #endif
+
#define MAX_ROW 999999 /* used for tl_dirty_row_end to update all
rows */
#define KEY_BUF_LEN 200
***************
*** 715,720 ****
--- 742,757 ----
vim_free(buf);
*p = ' ';
}
+ else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "winpty", 6) == 0)
+ {
+ opt.jo_set2 |= JO2_TERM_MODE;
+ opt.jo_term_mode = 'w';
+ }
+ else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "conpty", 6) == 0)
+ {
+ opt.jo_set2 |= JO2_TERM_MODE;
+ opt.jo_term_mode = 'c';
+ }
else
{
if (*p)
***************
*** 771,776 ****
--- 808,818 ----
if (fprintf(fd, "terminal ++curwin ++cols=%d ++rows=%d ",
term->tl_cols, term->tl_rows) < 0)
return FAIL;
+ #ifdef WIN3264
+ if (*wp->w_p_tmod != NUL)
+ if (fprintf(fd, "++%s ", wp->w_p_tmod) < 0)
+ return FAIL;
+ #endif
if (term->tl_command != NULL && fputs((char *)term->tl_command, fd) < 0)
return FAIL;
***************
*** 871,876 ****
--- 913,919 ----
vim_free(term->tl_status_text);
vim_free(term->tl_opencmd);
vim_free(term->tl_eof_chars);
+ vim_free(term->tl_arg0_cmd);
#ifdef WIN3264
if (term->tl_out_fd != NULL)
fclose(term->tl_out_fd);
***************
*** 2639,2648 ****
{
case VTERM_PROP_TITLE:
vim_free(term->tl_title);
! /* a blank title isn't useful, make it empty, so that "running" is
! * displayed */
if (*skipwhite((char_u *)value->string) == NUL)
term->tl_title = NULL;
#ifdef WIN3264
else if (!enc_utf8 && enc_codepage > 0)
{
--- 2682,2699 ----
{
case VTERM_PROP_TITLE:
vim_free(term->tl_title);
! // a blank title isn't useful, make it empty, so that "running" is
! // displayed
if (*skipwhite((char_u *)value->string) == NUL)
term->tl_title = NULL;
+ // Same as blank
+ else if (term->tl_arg0_cmd != NULL
+ && STRNCMP(term->tl_arg0_cmd, (char_u *)value->string,
+ (int)STRLEN(term->tl_arg0_cmd)) == 0)
+ term->tl_title = NULL;
+ // Empty corrupted data of winpty
+ else if (STRNCMP(" - ", (char_u *)value->string, 4) == 0)
+ term->tl_title = NULL;
#ifdef WIN3264
else if (!enc_utf8 && enc_codepage > 0)
{
***************
*** 5318,5324 ****
+ JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
+ JO2_CWD + JO2_ENV + JO2_EOF_CHARS
+ JO2_NORESTORE + JO2_TERM_KILL
! + JO2_ANSI_COLORS) == FAIL)
return;
buf = term_start(&argvars[0], NULL, &opt, 0);
--- 5369,5375 ----
+ JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
+ JO2_CWD + JO2_ENV + JO2_EOF_CHARS
+ JO2_NORESTORE + JO2_TERM_KILL
! + JO2_ANSI_COLORS + JO2_TERM_MODE) == FAIL)
return;
buf = term_start(&argvars[0], NULL, &opt, 0);
***************
*** 5426,5431 ****
--- 5477,5803 ----
* 2. MS-Windows implementation.
*/
+ HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON*);
+ HRESULT (WINAPI *pResizePseudoConsole)(HPCON, COORD);
+ HRESULT (WINAPI *pClosePseudoConsole)(HPCON);
+ BOOL (*pInitializeProcThreadAttributeList)(LPPROC_THREAD_ATTRIBUTE_LIST,
DWORD, DWORD, PSIZE_T);
+ BOOL (*pUpdateProcThreadAttribute)(LPPROC_THREAD_ATTRIBUTE_LIST, DWORD,
DWORD_PTR, PVOID, SIZE_T, PVOID, PSIZE_T);
+ void (*pDeleteProcThreadAttributeList)(LPPROC_THREAD_ATTRIBUTE_LIST);
+
+ static int
+ dyn_conpty_init(int verbose)
+ {
+ static BOOL handled = FALSE;
+ static int result;
+ HMODULE hKerneldll;
+ int i;
+ static struct
+ {
+ char *name;
+ FARPROC *ptr;
+ } conpty_entry[] =
+ {
+ {"CreatePseudoConsole", (FARPROC*)&pCreatePseudoConsole},
+ {"ResizePseudoConsole", (FARPROC*)&pResizePseudoConsole},
+ {"ClosePseudoConsole", (FARPROC*)&pClosePseudoConsole},
+ {"InitializeProcThreadAttributeList",
+ (FARPROC*)&pInitializeProcThreadAttributeList},
+ {"UpdateProcThreadAttribute",
+ (FARPROC*)&pUpdateProcThreadAttribute},
+ {"DeleteProcThreadAttributeList",
+ (FARPROC*)&pDeleteProcThreadAttributeList},
+ {NULL, NULL}
+ };
+
+ if (handled)
+ return result;
+
+ if (!has_vtp_working())
+ {
+ handled = TRUE;
+ result = FAIL;
+ return FAIL;
+ }
+
+ hKerneldll = vimLoadLib("kernel32.dll");
+ for (i = 0; conpty_entry[i].name != NULL
+ && conpty_entry[i].ptr != NULL; ++i)
+ {
+ if ((*conpty_entry[i].ptr = (FARPROC)GetProcAddress(hKerneldll,
+ conpty_entry[i].name)) == NULL)
+ {
+ if (verbose)
+ semsg(_(e_loadfunc), conpty_entry[i].name);
+ return FAIL;
+ }
+ }
+
+ handled = TRUE;
+ result = OK;
+ return OK;
+ }
+
+ static int
+ conpty_term_and_job_init(
+ term_T *term,
+ typval_T *argvar,
+ char **argv,
+ jobopt_T *opt,
+ jobopt_T *orig_opt)
+ {
+ WCHAR *cmd_wchar = NULL;
+ WCHAR *cmd_wchar_copy = NULL;
+ WCHAR *cwd_wchar = NULL;
+ WCHAR *env_wchar = NULL;
+ channel_T *channel = NULL;
+ job_T *job = NULL;
+ HANDLE jo = NULL;
+ garray_T ga_cmd, ga_env;
+ char_u *cmd = NULL;
+ HRESULT hr;
+ COORD consize;
+ SIZE_T breq;
+ PROCESS_INFORMATION proc_info;
+ HANDLE i_theirs = NULL;
+ HANDLE o_theirs = NULL;
+ HANDLE i_ours = NULL;
+ HANDLE o_ours = NULL;
+
+ ga_init2(&ga_cmd, (int)sizeof(char*), 20);
+ ga_init2(&ga_env, (int)sizeof(char*), 20);
+
+ if (argvar->v_type == VAR_STRING)
+ {
+ cmd = argvar->vval.v_string;
+ }
+ else if (argvar->v_type == VAR_LIST)
+ {
+ if (win32_build_cmd(argvar->vval.v_list, &ga_cmd) == FAIL)
+ goto failed;
+ cmd = ga_cmd.ga_data;
+ }
+ if (cmd == NULL || *cmd == NUL)
+ {
+ emsg(_(e_invarg));
+ goto failed;
+ }
+
+ term->tl_arg0_cmd = vim_strsave(cmd);
+
+ cmd_wchar = enc_to_utf16(cmd, NULL);
+
+ if (cmd_wchar != NULL)
+ {
+ /* Request by CreateProcessW */
+ breq = wcslen(cmd_wchar) + 1 + 1; /* Addition of NUL by API */
+ cmd_wchar_copy = (PWSTR)alloc((int)(breq * sizeof(WCHAR)));
+ wcsncpy(cmd_wchar_copy, cmd_wchar, breq - 1);
+ }
+
+ ga_clear(&ga_cmd);
+ if (cmd_wchar == NULL)
+ goto failed;
+ if (opt->jo_cwd != NULL)
+ cwd_wchar = enc_to_utf16(opt->jo_cwd, NULL);
+
+ win32_build_env(opt->jo_env, &ga_env, TRUE);
+ env_wchar = ga_env.ga_data;
+
+ if (!CreatePipe(&i_theirs, &i_ours, NULL, 0))
+ goto failed;
+ if (!CreatePipe(&o_ours, &o_theirs, NULL, 0))
+ goto failed;
+
+ consize.X = term->tl_cols;
+ consize.Y = term->tl_rows;
+ hr = pCreatePseudoConsole(consize, i_theirs, o_theirs, 0,
+ &term->tl_conpty);
+ if (FAILED(hr))
+ goto failed;
+
+ term->tl_siex.StartupInfo.cb = sizeof(term->tl_siex);
+
+ /* Set up pipe inheritance safely: Vista or later. */
+ pInitializeProcThreadAttributeList(NULL, 1, 0, &breq);
+ term->tl_siex.lpAttributeList =
+ (PPROC_THREAD_ATTRIBUTE_LIST)alloc((int)breq);
+ if (!term->tl_siex.lpAttributeList)
+ goto failed;
+ if (!pInitializeProcThreadAttributeList(term->tl_siex.lpAttributeList, 1,
+ 0, &breq))
+ goto failed;
+ if (!pUpdateProcThreadAttribute(
+ term->tl_siex.lpAttributeList, 0,
+ PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, term->tl_conpty,
+ sizeof(HPCON), NULL, NULL))
+ goto failed;
+
+ channel = add_channel();
+ if (channel == NULL)
+ goto failed;
+
+ job = job_alloc();
+ if (job == NULL)
+ goto failed;
+ if (argvar->v_type == VAR_STRING)
+ {
+ int argc;
+
+ build_argv_from_string(cmd, &job->jv_argv, &argc);
+ }
+ else
+ {
+ int argc;
+
+ build_argv_from_list(argvar->vval.v_list, &job->jv_argv, &argc);
+ }
+
+ if (opt->jo_set & JO_IN_BUF)
+ job->jv_in_buf = buflist_findnr(opt->jo_io_buf[PART_IN]);
+
+ if (!CreateProcessW(NULL, cmd_wchar_copy, NULL, NULL, FALSE,
+ EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT
+ | CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP
+ | CREATE_DEFAULT_ERROR_MODE,
+ env_wchar, cwd_wchar,
+ &term->tl_siex.StartupInfo, &proc_info))
+ goto failed;
+
+ CloseHandle(i_theirs);
+ CloseHandle(o_theirs);
+
+ channel_set_pipes(channel,
+ (sock_T)i_ours,
+ (sock_T)o_ours,
+ (sock_T)o_ours);
+
+ /* Write lines with CR instead of NL. */
+ channel->ch_write_text_mode = TRUE;
+
+ /* Use to explicitly delete anonymous pipe handle. */
+ channel->ch_anonymous_pipe = TRUE;
+
+ jo = CreateJobObject(NULL, NULL);
+ if (jo == NULL)
+ goto failed;
+
+ if (!AssignProcessToJobObject(jo, proc_info.hProcess))
+ {
+ /* Failed, switch the way to terminate process with TerminateProcess. */
+ CloseHandle(jo);
+ jo = NULL;
+ }
+
+ ResumeThread(proc_info.hThread);
+ CloseHandle(proc_info.hThread);
+
+ vim_free(cmd_wchar);
+ vim_free(cmd_wchar_copy);
+ vim_free(cwd_wchar);
+ vim_free(env_wchar);
+
+ if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
+ goto failed;
+
+ #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+ if (opt->jo_set2 & JO2_ANSI_COLORS)
+ set_vterm_palette(term->tl_vterm, opt->jo_ansi_colors);
+ else
+ init_vterm_ansi_colors(term->tl_vterm);
+ #endif
+
+ channel_set_job(channel, job, opt);
+ job_set_options(job, opt);
+
+ job->jv_channel = channel;
+ job->jv_proc_info = proc_info;
+ job->jv_job_object = jo;
+ job->jv_status = JOB_STARTED;
+ ++job->jv_refcount;
+ term->tl_job = job;
+
+ /* Redirecting stdout and stderr doesn't work at the job level. Instead
+ * open the file here and handle it in. opt->jo_io was changed in
+ * setup_job_options(), use the original flags here. */
+ if (orig_opt->jo_io[PART_OUT] == JIO_FILE)
+ {
+ char_u *fname = opt->jo_io_name[PART_OUT];
+
+ ch_log(channel, "Opening output file %s", fname);
+ term->tl_out_fd = mch_fopen((char *)fname, WRITEBIN);
+ if (term->tl_out_fd == NULL)
+ semsg(_(e_notopen), fname);
+ }
+
+ return OK;
+
+ failed:
+ ga_clear(&ga_cmd);
+ ga_clear(&ga_env);
+ vim_free(cmd_wchar);
+ vim_free(cmd_wchar_copy);
+ vim_free(cwd_wchar);
+ 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_siex.lpAttributeList != NULL)
+ {
+ pDeleteProcThreadAttributeList(term->tl_siex.lpAttributeList);
+ vim_free(term->tl_siex.lpAttributeList);
+ }
+ term->tl_siex.lpAttributeList = NULL;
+ if (o_theirs != NULL)
+ CloseHandle(o_theirs);
+ if (o_ours != NULL)
+ CloseHandle(o_ours);
+ if (i_ours != NULL)
+ CloseHandle(i_ours);
+ if (i_theirs != NULL)
+ CloseHandle(i_theirs);
+ if (term->tl_conpty != NULL)
+ pClosePseudoConsole(term->tl_conpty);
+ term->tl_conpty = NULL;
+ return FAIL;
+ }
+
+ static void
+ conpty_term_report_winsize(term_T *term, int rows, int cols)
+ {
+ COORD consize;
+
+ consize.X = cols;
+ consize.Y = rows;
+ pResizePseudoConsole(term->tl_conpty, consize);
+ }
+
+ void
+ term_free_conpty(term_T *term)
+ {
+ if (term->tl_siex.lpAttributeList != NULL)
+ {
+ pDeleteProcThreadAttributeList(term->tl_siex.lpAttributeList);
+ vim_free(term->tl_siex.lpAttributeList);
+ }
+ term->tl_siex.lpAttributeList = NULL;
+ if (term->tl_conpty != NULL)
+ pClosePseudoConsole(term->tl_conpty);
+ term->tl_conpty = NULL;
+ }
+
+ int
+ use_conpty(void)
+ {
+ return has_conpty;
+ }
+
# ifndef PROTO
#define WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN 1ul
***************
*** 5516,5531 ****
return OK;
}
- /*
- * Create a new terminal of "rows" by "cols" cells.
- * Store a reference in "term".
- * Return OK or FAIL.
- */
static int
! term_and_job_init(
term_T *term,
typval_T *argvar,
! char **argv UNUSED,
jobopt_T *opt,
jobopt_T *orig_opt)
{
--- 5888,5898 ----
return OK;
}
static int
! winpty_term_and_job_init(
term_T *term,
typval_T *argvar,
! char **argv,
jobopt_T *opt,
jobopt_T *orig_opt)
{
***************
*** 5543,5550 ****
garray_T ga_cmd, ga_env;
char_u *cmd = NULL;
- if (dyn_winpty_init(TRUE) == FAIL)
- return FAIL;
ga_init2(&ga_cmd, (int)sizeof(char*), 20);
ga_init2(&ga_env, (int)sizeof(char*), 20);
--- 5910,5915 ----
***************
*** 5564,5569 ****
--- 5929,5936 ----
goto failed;
}
+ term->tl_arg0_cmd = vim_strsave(cmd);
+
cmd_wchar = enc_to_utf16(cmd, NULL);
ga_clear(&ga_cmd);
if (cmd_wchar == NULL)
***************
*** 5676,5684 ****
job->jv_job_object = jo;
job->jv_status = JOB_STARTED;
job->jv_tty_in = utf16_to_enc(
! (short_u*)winpty_conin_name(term->tl_winpty), NULL);
job->jv_tty_out = utf16_to_enc(
! (short_u*)winpty_conout_name(term->tl_winpty), NULL);
++job->jv_refcount;
term->tl_job = job;
--- 6043,6051 ----
job->jv_job_object = jo;
job->jv_status = JOB_STARTED;
job->jv_tty_in = utf16_to_enc(
! (short_u *)winpty_conin_name(term->tl_winpty), NULL);
job->jv_tty_out = utf16_to_enc(
! (short_u *)winpty_conout_name(term->tl_winpty), NULL);
++job->jv_refcount;
term->tl_job = job;
***************
*** 5722,5728 ****
term->tl_winpty_config = NULL;
if (winpty_err != NULL)
{
! char_u *msg = utf16_to_enc(
(short_u *)winpty_error_msg(winpty_err), NULL);
emsg(msg);
--- 6089,6095 ----
term->tl_winpty_config = NULL;
if (winpty_err != NULL)
{
! char *msg = (char *)utf16_to_enc(
(short_u *)winpty_error_msg(winpty_err), NULL);
emsg(msg);
***************
*** 5731,5736 ****
--- 6098,6173 ----
return FAIL;
}
+ /*
+ * Create a new terminal of "rows" by "cols" cells.
+ * Store a reference in "term".
+ * Return OK or FAIL.
+ */
+ static int
+ term_and_job_init(
+ term_T *term,
+ typval_T *argvar,
+ char **argv UNUSED,
+ jobopt_T *opt,
+ jobopt_T *orig_opt)
+ {
+ int use_winpty = FALSE;
+ int use_conpty = FALSE;
+
+ has_winpty = dyn_winpty_init(FALSE) != FAIL ? TRUE : FALSE;
+ has_conpty = dyn_conpty_init(FALSE) != FAIL ? TRUE : FALSE;
+
+ if (!has_winpty && !has_conpty)
+ // If neither is available give the errors for winpty, since when
+ // conpty is not available it can't be installed either.
+ return dyn_winpty_init(TRUE);
+
+ if (opt->jo_term_mode == 'w')
+ set_string_option_direct((char_u *)"tmod", -1, (char_u *)"winpty",
+ OPT_FREE|OPT_LOCAL, 0);
+ if (opt->jo_term_mode == 'c')
+ set_string_option_direct((char_u *)"tmod", -1, (char_u *)"conpty",
+ OPT_FREE|OPT_LOCAL, 0);
+
+ if (curwin->w_p_tmod == NULL || *curwin->w_p_tmod == NUL)
+ {
+ if (has_conpty)
+ use_conpty = TRUE;
+ else if (has_winpty)
+ use_winpty = TRUE;
+ // else: error
+ }
+ else if (STRICMP(curwin->w_p_tmod, "winpty") == 0)
+ {
+ if (has_winpty)
+ use_winpty = TRUE;
+ }
+ else if (STRICMP(curwin->w_p_tmod, "conpty") == 0)
+ {
+ if (has_conpty)
+ use_conpty = TRUE;
+ else
+ return dyn_conpty_init(TRUE);
+ }
+
+ if (use_conpty)
+ {
+ set_string_option_direct((char_u *)"tmod", -1, (char_u *)"conpty",
+ OPT_FREE|OPT_LOCAL, 0);
+ return conpty_term_and_job_init(term, argvar, argv, opt, orig_opt);
+ }
+
+ if (use_winpty)
+ {
+ set_string_option_direct((char_u *)"tmod", -1, (char_u *)"winpty",
+ OPT_FREE|OPT_LOCAL, 0);
+ return winpty_term_and_job_init(term, argvar, argv, opt, orig_opt);
+ }
+
+ // error
+ return dyn_winpty_init(TRUE);
+ }
+
static int
create_pty_only(term_T *term, jobopt_T *options)
{
***************
*** 5804,5809 ****
--- 6241,6247 ----
static void
term_free_vterm(term_T *term)
{
+ term_free_conpty(term);
if (term->tl_winpty != NULL)
winpty_free(term->tl_winpty);
term->tl_winpty = NULL;
***************
*** 5821,5826 ****
--- 6259,6266 ----
static void
term_report_winsize(term_T *term, int rows, int cols)
{
+ if (term->tl_conpty)
+ conpty_term_report_winsize(term, rows, cols);
if (term->tl_winpty)
winpty_set_size(term->tl_winpty, cols, rows, NULL);
}
***************
*** 5828,5834 ****
int
terminal_enabled(void)
{
! return dyn_winpty_init(FALSE) == OK;
}
# else
--- 6268,6274 ----
int
terminal_enabled(void)
{
! return dyn_winpty_init(FALSE) == OK || dyn_conpty_init(FALSE) == OK;
}
# else
***************
*** 5852,5857 ****
--- 6292,6299 ----
jobopt_T *opt,
jobopt_T *orig_opt UNUSED)
{
+ term->tl_arg0_cmd = NULL;
+
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
return FAIL;
*** ../vim-8.1.0869/src/testdir/gen_opt_test.vim 2018-11-05
21:21:29.800286334 +0100
--- src/testdir/gen_opt_test.vim 2019-02-03 13:46:59.603853294 +0100
***************
*** 131,136 ****
--- 131,137 ----
\ 'term': [[], []],
\ 'termguicolors': [[], []],
\ 'termencoding': [has('gui_gtk') ? [] : ['', 'utf-8'], ['xxx']],
+ \ 'termmode': [['', 'winpty', 'conpty'], ['xxx']],
\ 'termwinsize': [['', '24x80', '0x80', '32x0', '0x0'], ['xxx', '80',
'8ax9', '24x80b']],
\ 'toolbar': [['', 'icons', 'text'], ['xxx']],
\ 'toolbariconsize': [['', 'tiny', 'huge'], ['xxx']],
*** ../vim-8.1.0869/src/testdir/test_autocmd.vim 2019-01-30
22:01:36.982854408 +0100
--- src/testdir/test_autocmd.vim 2019-02-03 13:46:59.603853294 +0100
***************
*** 1397,1403 ****
let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'],
{'term_rows': 3})
call assert_equal('running', term_getstatus(buf))
" Wait for the ruler (in the status line) to be shown.
! call WaitForAssert({-> assert_match('\<All$', term_getline(buf, 3))})
" It's only adding autocmd, so that no event occurs.
call term_sendkeys(buf, ":au! TextChanged <buffer> call writefile(['No'],
'Xchanged.txt')\<cr>")
call term_sendkeys(buf, "\<C-\\>\<C-N>:qa!\<cr>")
--- 1397,1409 ----
let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'],
{'term_rows': 3})
call assert_equal('running', term_getstatus(buf))
" Wait for the ruler (in the status line) to be shown.
! " In ConPTY, there is additional character which is drawn up to the width of
! " the screen.
! if has('conpty')
! call WaitForAssert({-> assert_match('\<All.*$', term_getline(buf, 3))})
! else
! call WaitForAssert({-> assert_match('\<All$', term_getline(buf, 3))})
! endif
" It's only adding autocmd, so that no event occurs.
call term_sendkeys(buf, ":au! TextChanged <buffer> call writefile(['No'],
'Xchanged.txt')\<cr>")
call term_sendkeys(buf, "\<C-\\>\<C-N>:qa!\<cr>")
*** ../vim-8.1.0869/src/testdir/test_mksession.vim 2019-01-26
20:07:34.592237223 +0100
--- src/testdir/test_mksession.vim 2019-02-03 13:46:59.603853294 +0100
***************
*** 295,301 ****
call assert_report('unexpected shell line: ' . line)
endif
endfor
! call assert_match('terminal ++curwin ++cols=\d\+ ++rows=\d\+\s*$', term_cmd)
call Stop_shell_in_terminal(bufnr('%'))
call delete('Xtest_mks.out')
--- 295,301 ----
call assert_report('unexpected shell line: ' . line)
endif
endfor
! call assert_match('terminal ++curwin ++cols=\d\+ ++rows=\d\+\s*.*$',
term_cmd)
call Stop_shell_in_terminal(bufnr('%'))
call delete('Xtest_mks.out')
***************
*** 375,381 ****
let term_cmd = line
endif
endfor
! call assert_match('terminal ++curwin ++cols=\d\+ ++rows=\d\+ other',
term_cmd)
call Stop_shell_in_terminal(bufnr('%'))
call delete('Xtest_mks.out')
--- 375,381 ----
let term_cmd = line
endif
endfor
! call assert_match('terminal ++curwin ++cols=\d\+ ++rows=\d\+.*other',
term_cmd)
call Stop_shell_in_terminal(bufnr('%'))
call delete('Xtest_mks.out')
*** ../vim-8.1.0869/src/testdir/test_terminal.vim 2019-01-29
22:58:02.401136295 +0100
--- src/testdir/test_terminal.vim 2019-02-03 13:46:59.603853294 +0100
***************
*** 39,46 ****
call assert_match('^/dev/', job_info(g:job).tty_out)
call assert_match('^/dev/', term_gettty(''))
else
! call assert_match('^\\\\.\\pipe\\', job_info(g:job).tty_out)
! call assert_match('^\\\\.\\pipe\\', term_gettty(''))
endif
call assert_equal('t', mode())
call assert_equal('yes', b:done)
--- 39,49 ----
call assert_match('^/dev/', job_info(g:job).tty_out)
call assert_match('^/dev/', term_gettty(''))
else
! " ConPTY works on anonymous pipe.
! if !has('conpty')
! call assert_match('^\\\\.\\pipe\\', job_info(g:job).tty_out)
! call assert_match('^\\\\.\\pipe\\', term_gettty(''))
! endif
endif
call assert_equal('t', mode())
call assert_equal('yes', b:done)
***************
*** 129,135 ****
func Get_cat_123_cmd()
if has('win32')
! return 'cmd /c "cls && color 2 && echo 123"'
else
call writefile(["\<Esc>[32m123"], 'Xtext')
return "cat Xtext"
--- 132,143 ----
func Get_cat_123_cmd()
if has('win32')
! if !has('conpty')
! return 'cmd /c "cls && color 2 && echo 123"'
! else
! " When clearing twice, extra sequence is not output.
! return 'cmd /c "cls && cls && color 2 && echo 123"'
! endif
else
call writefile(["\<Esc>[32m123"], 'Xtext')
return "cat Xtext"
***************
*** 143,150 ****
call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
call WaitForAssert({-> assert_equal(0, g:buf)})
- unlet g:buf
unlet g:job
call delete('Xtext')
endfunc
--- 151,158 ----
call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
call WaitForAssert({-> assert_equal(0, g:buf)})
unlet g:job
+ unlet g:buf
call delete('Xtext')
endfunc
***************
*** 563,568 ****
--- 571,579 ----
" The shell or something else has a problem dealing with more than 1000
" characters at the same time.
let len = 1000
+ " NPFS is used in Windows, nonblocking mode does not work properly.
+ elseif has('win32')
+ let len = 1
else
let len = 5000
endif
***************
*** 693,700 ****
let cmd = Get_cat_123_cmd()
let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'})
call term_wait(buf)
! call WaitForAssert({-> assert_notequal(0, len(readfile("Xfile")))})
! call assert_match('123', readfile('Xfile')[0])
let g:job = term_getjob(buf)
call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
call delete('Xfile')
--- 704,714 ----
let cmd = Get_cat_123_cmd()
let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'})
call term_wait(buf)
! " ConPTY may precede escape sequence. There are things that are not so.
! if !has('conpty')
! call WaitForAssert({-> assert_notequal(0, len(readfile("Xfile")))})
! call assert_match('123', readfile('Xfile')[0])
! endif
let g:job = term_getjob(buf)
call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
call delete('Xfile')
***************
*** 1661,1666 ****
--- 1675,1684 ----
endfunc
func Test_terminal_does_not_truncate_last_newlines()
+ " This test does not pass through ConPTY.
+ if has('conpty')
+ return
+ endif
let contents = [
\ [ 'One', '', 'X' ],
\ [ 'Two', '', '' ],
*** ../vim-8.1.0869/src/version.c 2019-02-03 13:12:20.344668681 +0100
--- src/version.c 2019-02-03 13:50:03.310696825 +0100
***************
*** 785,786 ****
--- 785,788 ----
{ /* Add new patch number below this line */
+ /**/
+ 870,
/**/
--
A hamburger walks into a bar, and the bartender says: "I'm sorry,
but we don't serve food here."
/// Bram Moolenaar -- [email protected] -- 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 ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.