feat(terminal): try to find newer conpty.dll on Windows #40328

The system version of ConPTY in kernel32.dll is old and will
mangle some VT sequences sent by shells. Newer versions of ConPTY
available as part of the Windows Terminal project fix this by
passing through VT sequences unmodified when the terminal has set
ENABLE_VIRTUAL_TERMINAL_INPUT. This change allows users to fix
buggy behaviour of Neovim's terminal on Windows by copying
conpty.dll to Neovim's bin directory.

Co-authored-by: Scott Young <s@sjy.au>
This commit is contained in:
akiyosi
2026-06-30 03:46:23 +09:00
committed by GitHub
parent 7312df77bb
commit d6a1b4110a
2 changed files with 28 additions and 6 deletions

View File

@@ -42,6 +42,18 @@ by |:mksession| to restore a terminal buffer (by restarting the {cmd}).
The terminal environment is initialized as in |jobstart-env|.
==============================================================================
MS-Windows ConPTY *terminal-ms-windows* *terminal-conpty*
The system ConPTY (in "kernel32.dll") mangles some VT sequences, which can
garble |:terminal| output. To use a newer ConPTY from the Windows Terminal
project, put its "conpty.dll" (and "OpenConsole.exe") next to the Nvim
executable. Nvim uses that "conpty.dll" if present, else falls back to the
system ConPTY, and logs which one (|$NVIM_LOG_FILE|): >
Loaded new ConPTY from conpty.dll
Loaded system ConPTY from kernel32.dll
<
==============================================================================
Input *terminal-input*

View File

@@ -28,11 +28,21 @@ bool os_has_conpty_working(void)
TriState os_dyn_conpty_init(void)
{
uv_lib_t kernel;
if (uv_dlopen("kernel32.dll", &kernel)) {
uv_dlclose(&kernel);
return kFalse;
uv_lib_t conpty_lib;
if (!uv_dlopen("conpty.dll", &conpty_lib)) {
ILOG("Loaded new ConPTY from conpty.dll");
} else {
// uv_dlopen() allocates an error message even on failure, so close the
// handle before reusing conpty_lib for the system ConPTY fallback.
uv_dlclose(&conpty_lib);
if (uv_dlopen("kernel32.dll", &conpty_lib)) {
uv_dlclose(&conpty_lib);
return kFalse;
}
ILOG("Loaded system ConPTY from kernel32.dll");
}
static struct {
char *name;
FARPROC *ptr;
@@ -44,8 +54,8 @@ TriState os_dyn_conpty_init(void)
};
for (int i = 0;
conpty_entry[i].name != NULL && conpty_entry[i].ptr != NULL; i++) {
if (uv_dlsym(&kernel, conpty_entry[i].name, (void **)conpty_entry[i].ptr)) {
uv_dlclose(&kernel);
if (uv_dlsym(&conpty_lib, conpty_entry[i].name, (void **)conpty_entry[i].ptr)) {
uv_dlclose(&conpty_lib);
return kFalse;
}
}