Skip to content

Commit aa5df7e

Browse files
committed
patch 8.1.0870: Vim doesn't use the new ConPTY support in Windows 10
Problem: Vim doesn't use the new ConPTY support in Windows 10. Solution: Use ConPTY support, if available. (Nobuhiro Takasaki, closes #3794)
1 parent 01a6c21 commit aa5df7e

17 files changed

Lines changed: 694 additions & 73 deletions

runtime/doc/eval.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*eval.txt* For Vim version 8.1. Last change: 2019 Jan 29
1+
*eval.txt* For Vim version 8.1. Last change: 2019 Feb 03
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -696,7 +696,7 @@ similar to -1. >
696696
:let otherblob = myblob[:] " make a copy of the Blob
697697
698698
If the first index is beyond the last byte of the Blob or the second index is
699-
before the first index, the result is an empty list. There is no error
699+
before the first index, the result is an empty Blob. There is no error
700700
message.
701701

702702
If the second index is equal to or greater than the length of the list the
@@ -9469,6 +9469,10 @@ term_start({cmd}, {options}) *term_start()*
94699469
"ansi_colors" A list of 16 color names or hex codes
94709470
defining the ANSI palette used in GUI
94719471
color modes. See |g:terminal_ansi_colors|.
9472+
"term_mode" (MS-Windows only): Specify which pty to
9473+
use:
9474+
"winpty": Use winpty
9475+
"conpty": Use ConPTY (if available)
94729476

94739477
{only available when compiled with the |+terminal| feature}
94749478

@@ -10186,6 +10190,7 @@ cmdline_hist Compiled with |cmdline-history| support.
1018610190
cmdline_info Compiled with 'showcmd' and 'ruler' support.
1018710191
comments Compiled with |'comments'| support.
1018810192
compatible Compiled to be very Vi compatible.
10193+
conpty Platform where |ConPTY| can be used.
1018910194
cryptv Compiled with encryption support |encryption|.
1019010195
cscope Compiled with |cscope| support.
1019110196
cursorbind Compiled with |cursorbind| (always true)

runtime/doc/options.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8054,6 +8054,23 @@ A jump table for the options with a short description can be found at |Q_op|.
80548054
Note that the "cterm" attributes are still used, not the "gui" ones.
80558055
NOTE: This option is reset when 'compatible' is set.
80568056

8057+
*'termmode'* *'tmod'*
8058+
'termmode' 'tmod' string (default "")
8059+
local to window
8060+
{not in Vi, MS-Windows only}
8061+
Whether the window uses winpty or |ConPTY| as the virtual console.
8062+
When set before opening the terminal, it influences what pty is used.
8063+
When opening the terminal it will be set to the actually used pty.
8064+
8065+
Possible values are:
8066+
"" use ConPTY if possible, winpty otherwise
8067+
"winpty" use winpty, fail if not supported
8068+
"conpty" use |ConPTY|, fail if not supported
8069+
8070+
|ConPTY| support depends on the platform (Windows 10 October 2018
8071+
edition). winpty support needs to be installed. If neither is
8072+
supported then you cannot open a terminal window.
8073+
80578074
*'termwinscroll'* *'twsl'*
80588075
'termwinscroll' 'twsl' number (default 10000)
80598076
local to buffer

runtime/doc/terminal.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,8 @@ Syntax ~
228228
for Python "++eof=exit()". Special
229229
codes can be used like with `:map`,
230230
e.g. "<C-Z>" for CTRL-Z.
231-
231+
++winpty Use winpty as the virtual console.
232+
++conpty Use |ConPTY| as the virtual console.
232233
If you want to use more options use the |term_start()|
233234
function.
234235
If you want to split the window vertically, use: >
@@ -410,6 +411,13 @@ Just put the files somewhere in your PATH. You can set the 'winptydll' option
410411
to point to the right file, if needed. If you have both the 32-bit and 64-bit
411412
version, rename to winpty32.dll and winpty64.dll to match the way Vim was
412413
build.
414+
*ConPTY*
415+
On more recent versions of MS-Windows 10 (beginning with the "October 2018
416+
Update"), winpty is no longer required. On those versions, |:terminal| will use
417+
Windows' built-in support for hosting terminal applications, "ConPTY". When
418+
ConPTY is in use, there may be rendering artifacts regarding ambiguous-width
419+
characters. If you encounter any such issues, set 'termmode' to winpty (which
420+
you then must have instlled).
413421

414422
Environment variables are used to pass information to the running job:
415423
VIM_SERVERNAME v:servername

src/channel.c

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,11 +1720,7 @@ channel_get_all(channel_T *channel, ch_part_T part, int *outlen)
17201720
char_u *res;
17211721
char_u *p;
17221722

1723-
/* If there is only one buffer just get that one. */
1724-
if (head->rq_next == NULL || head->rq_next->rq_next == NULL)
1725-
return channel_get(channel, part, outlen);
1726-
1727-
/* Concatenate everything into one buffer. */
1723+
// Concatenate everything into one buffer.
17281724
for (node = head->rq_next; node != NULL; node = node->rq_next)
17291725
len += node->rq_buflen;
17301726
res = lalloc(len + 1, TRUE);
@@ -1738,7 +1734,7 @@ channel_get_all(channel_T *channel, ch_part_T part, int *outlen)
17381734
}
17391735
*p = NUL;
17401736

1741-
/* Free all buffers */
1737+
// Free all buffers
17421738
do
17431739
{
17441740
p = channel_get(channel, part, NULL);
@@ -1747,16 +1743,37 @@ channel_get_all(channel_T *channel, ch_part_T part, int *outlen)
17471743

17481744
if (outlen != NULL)
17491745
{
1746+
// Returning the length, keep NUL characters.
17501747
*outlen += len;
17511748
return res;
17521749
}
17531750

1754-
/* turn all NUL into NL */
1755-
while (len > 0)
1751+
// Turn all NUL into NL, so that the result can be used as a string.
1752+
p = res;
1753+
while (p < res + len)
17561754
{
1757-
--len;
1758-
if (res[len] == NUL)
1759-
res[len] = NL;
1755+
if (*p == NUL)
1756+
*p = NL;
1757+
#ifdef WIN32
1758+
else if (*p == 0x1b)
1759+
{
1760+
// crush the escape sequence OSC 0/1/2: ESC ]0;
1761+
if (p + 3 < res + len
1762+
&& p[1] == ']'
1763+
&& (p[2] == '0' || p[2] == '1' || p[2] == '2')
1764+
&& p[3] == ';')
1765+
{
1766+
// '\a' becomes a NL
1767+
while (p < res + (len - 1) && *p != '\a')
1768+
++p;
1769+
// BEL is zero width characters, suppress display mistake
1770+
// ConPTY (after 10.0.18317) requires advance checking
1771+
if (p[-1] == NUL)
1772+
p[-1] = 0x07;
1773+
}
1774+
}
1775+
#endif
1776+
++p;
17601777
}
17611778

17621779
return res;
@@ -4330,7 +4347,7 @@ channel_parse_messages(void)
43304347
channel = first_channel;
43314348
continue;
43324349
}
4333-
if (channel->ch_to_be_freed)
4350+
if (channel->ch_to_be_freed || channel->ch_killing)
43344351
{
43354352
channel_free(channel);
43364353
/* channel has been freed, start over */
@@ -4930,6 +4947,28 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
49304947
opt->jo_set2 |= JO2_TERM_KILL;
49314948
opt->jo_term_kill = tv_get_string_chk(item);
49324949
}
4950+
else if (STRCMP(hi->hi_key, "term_mode") == 0)
4951+
{
4952+
char_u *p;
4953+
4954+
if (!(supported2 & JO2_TERM_MODE))
4955+
break;
4956+
opt->jo_set2 |= JO2_TERM_MODE;
4957+
p = tv_get_string_chk(item);
4958+
if (p == NULL)
4959+
{
4960+
semsg(_(e_invargval), "term_mode");
4961+
return FAIL;
4962+
}
4963+
// Allow empty string, "winpty", "conpty".
4964+
if (!(*p == NUL || STRCMP(p, "winpty") == 0
4965+
|| STRCMP(p, "conpty") == 0))
4966+
{
4967+
semsg(_(e_invargval), "term_mode");
4968+
return FAIL;
4969+
}
4970+
opt->jo_term_mode = p[0];
4971+
}
49334972
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
49344973
else if (STRCMP(hi->hi_key, "ansi_colors") == 0)
49354974
{
@@ -5440,6 +5479,16 @@ job_cleanup(job_T *job)
54405479
channel_need_redraw = TRUE;
54415480
}
54425481

5482+
if (job->jv_channel != NULL
5483+
&& job->jv_channel->ch_anonymous_pipe && !job->jv_channel->ch_killing)
5484+
{
5485+
++safe_to_invoke_callback;
5486+
channel_free_contents(job->jv_channel);
5487+
job->jv_channel->ch_job = NULL;
5488+
job->jv_channel = NULL;
5489+
--safe_to_invoke_callback;
5490+
}
5491+
54435492
// Do not free the job in case the close callback of the associated channel
54445493
// isn't invoked yet and may get information by job_info().
54455494
if (job->jv_refcount == 0 && !job_channel_still_useful(job))

src/evalfunc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6737,6 +6737,10 @@ f_has(typval_T *argvars, typval_T *rettv)
67376737
#if defined(FEAT_TERMINAL) && defined(WIN3264)
67386738
else if (STRICMP(name, "terminal") == 0)
67396739
n = terminal_enabled();
6740+
#endif
6741+
#if defined(FEAT_TERMINAL) && defined(WIN3264)
6742+
else if (STRICMP(name, "conpty") == 0)
6743+
n = use_conpty();
67406744
#endif
67416745
}
67426746

src/globals.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1432,7 +1432,8 @@ EXTERN char e_fsync[] INIT(= N_("E667: Fsync failed"));
14321432
|| defined(DYNAMIC_ICONV) \
14331433
|| defined(DYNAMIC_GETTEXT) \
14341434
|| defined(DYNAMIC_MZSCHEME) \
1435-
|| defined(DYNAMIC_LUA)
1435+
|| defined(DYNAMIC_LUA) \
1436+
|| defined(FEAT_TERMINAL)
14361437
EXTERN char e_loadlib[] INIT(= N_("E370: Could not load library %s"));
14371438
EXTERN char e_loadfunc[] INIT(= N_("E448: Could not load library function %s"));
14381439
#endif

src/option.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@
253253
# define PV_TWK OPT_WIN(WV_TWK)
254254
# define PV_TWS OPT_WIN(WV_TWS)
255255
# define PV_TWSL OPT_BUF(BV_TWSL)
256+
# define PV_TMOD OPT_WIN(WV_TMOD)
256257
#endif
257258
#ifdef FEAT_SIGNS
258259
# define PV_SCL OPT_WIN(WV_SCL)
@@ -2698,6 +2699,15 @@ static struct vimoption options[] =
26982699
#else
26992700
(char_u*)NULL, PV_NONE,
27002701
{(char_u *)FALSE, (char_u *)FALSE}
2702+
#endif
2703+
SCTX_INIT},
2704+
{"termmode", "tmod", P_STRING|P_ALLOCED|P_VI_DEF,
2705+
#ifdef FEAT_TERMINAL
2706+
(char_u *)VAR_WIN, PV_TMOD,
2707+
{(char_u *)"", (char_u *)NULL}
2708+
#else
2709+
(char_u *)NULL, PV_NONE,
2710+
{(char_u *)NULL, (char_u *)0L}
27012711
#endif
27022712
SCTX_INIT},
27032713
{"termwinkey", "twk", P_STRING|P_ALLOCED|P_RWIN|P_VI_DEF,
@@ -3208,6 +3218,9 @@ static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", "noins
32083218
#ifdef FEAT_SIGNS
32093219
static char *(p_scl_values[]) = {"yes", "no", "auto", NULL};
32103220
#endif
3221+
#ifdef FEAT_TERMINAL
3222+
static char *(p_tmod_values[]) = {"winpty", "conpty", "", NULL};
3223+
#endif
32113224

32123225
static void set_options_default(int opt_flags);
32133226
static void set_string_default_esc(char *name, char_u *val, int escape);
@@ -3661,7 +3674,12 @@ set_init_1(int clean_arg)
36613674
{
36623675
char buf[50];
36633676

3664-
sprintf(buf, "cp%ld", (long)GetConsoleCP());
3677+
/* Win32 console: In ConPTY, GetConsoleCP() returns zero.
3678+
* Use an alternative value. */
3679+
if (GetConsoleCP() == 0)
3680+
sprintf(buf, "cp%ld", (long)GetACP());
3681+
else
3682+
sprintf(buf, "cp%ld", (long)GetConsoleCP());
36653683
p_tenc = vim_strsave((char_u *)buf);
36663684
if (p_tenc != NULL)
36673685
{
@@ -7468,14 +7486,14 @@ did_set_string_option(
74687486
#endif
74697487

74707488
#ifdef FEAT_TERMINAL
7471-
/* 'termwinkey' */
7489+
// 'termwinkey'
74727490
else if (varp == &curwin->w_p_twk)
74737491
{
74747492
if (*curwin->w_p_twk != NUL
74757493
&& string_to_key(curwin->w_p_twk, TRUE) == 0)
74767494
errmsg = e_invarg;
74777495
}
7478-
/* 'termwinsize' */
7496+
// 'termwinsize'
74797497
else if (varp == &curwin->w_p_tws)
74807498
{
74817499
if (*curwin->w_p_tws != NUL)
@@ -7487,6 +7505,12 @@ did_set_string_option(
74877505
errmsg = e_invarg;
74887506
}
74897507
}
7508+
// 'termmode'
7509+
else if (varp == &curwin->w_p_tmod)
7510+
{
7511+
if (check_opt_strings(*varp, p_tmod_values, FALSE) != OK)
7512+
errmsg = e_invarg;
7513+
}
74907514
#endif
74917515

74927516
#ifdef FEAT_VARTABS
@@ -8838,7 +8862,7 @@ set_bool_option(
88388862
if (!has_vtp_working())
88398863
{
88408864
p_tgc = 0;
8841-
return (char_u*)N_("E954: 24-bit colors are not supported on this environment");
8865+
return N_("E954: 24-bit colors are not supported on this environment");
88428866
}
88438867
if (is_term_win32())
88448868
swap_tcap();
@@ -10928,6 +10952,7 @@ get_varp(struct vimoption *p)
1092810952
case PV_TWK: return (char_u *)&(curwin->w_p_twk);
1092910953
case PV_TWS: return (char_u *)&(curwin->w_p_tws);
1093010954
case PV_TWSL: return (char_u *)&(curbuf->b_p_twsl);
10955+
case PV_TMOD: return (char_u *)&(curwin->w_p_tmod);
1093110956
#endif
1093210957

1093310958
case PV_AI: return (char_u *)&(curbuf->b_p_ai);
@@ -11128,6 +11153,7 @@ copy_winopt(winopt_T *from, winopt_T *to)
1112811153
#ifdef FEAT_TERMINAL
1112911154
to->wo_twk = vim_strsave(from->wo_twk);
1113011155
to->wo_tws = vim_strsave(from->wo_tws);
11156+
to->wo_tmod = vim_strsave(from->wo_tmod);
1113111157
#endif
1113211158
#ifdef FEAT_FOLDING
1113311159
to->wo_fdc = from->wo_fdc;
@@ -11198,6 +11224,7 @@ check_winopt(winopt_T *wop UNUSED)
1119811224
#ifdef FEAT_TERMINAL
1119911225
check_string_option(&wop->wo_twk);
1120011226
check_string_option(&wop->wo_tws);
11227+
check_string_option(&wop->wo_tmod);
1120111228
#endif
1120211229
#ifdef FEAT_LINEBREAK
1120311230
check_string_option(&wop->wo_briopt);
@@ -11241,6 +11268,7 @@ clear_winopt(winopt_T *wop UNUSED)
1124111268
#ifdef FEAT_TERMINAL
1124211269
clear_string_option(&wop->wo_twk);
1124311270
clear_string_option(&wop->wo_tws);
11271+
clear_string_option(&wop->wo_tmod);
1124411272
#endif
1124511273
}
1124611274

src/option.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,7 @@ enum
11121112
#ifdef FEAT_TERMINAL
11131113
, WV_TWK
11141114
, WV_TWS
1115+
, WV_TMOD
11151116
#endif
11161117
, WV_CRBIND
11171118
#ifdef FEAT_LINEBREAK

0 commit comments

Comments
 (0)