diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt index ca32fff420..3f9c3f650f 100644 --- a/runtime/doc/terminal.txt +++ b/runtime/doc/terminal.txt @@ -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* diff --git a/src/nvim/os/pty_conpty_win.c b/src/nvim/os/pty_conpty_win.c index 5e0253089b..cb343bb876 100644 --- a/src/nvim/os/pty_conpty_win.c +++ b/src/nvim/os/pty_conpty_win.c @@ -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; } }