mirror of
https://github.com/neovim/neovim.git
synced 2026-07-31 04:39:07 +00:00
refactor(:restart): unnecessary console allocation on Windows #40919
Problem: `:restart` on Windows always forces `AllocConsole`, even though we could reuse old server's existing console + unnecessary env. Analysis: Afterd5516daf12changed the restart lifecycle and789741bb83separated the Windows console paths, we no longer need to force `AllocConsole()` for `:restart`. The `:detach` path now allocates its own console when it actually runs. Solution: Try to attach the replacement server to its parent’s console and fall back to `AllocConsole()` if attachment fails. Drop the restart-specific env that forced allocation. As documented by Microsoft, [“A console is closed when the last process attached to it terminates or calls `FreeConsole`.”](https://learn.microsoft.com/en-us/windows/console/attachconsole) Btw, this way we can preserve `io.stdout:write()`, though if for some reason `AttachConsole` would fail then it won't work; but now at least it's not always not rendering on `:restart`.
This commit is contained in:
@@ -563,19 +563,13 @@ uint64_t channel_from_stdio(bool rpc, CallbackReader on_output, const char **err
|
||||
if (embedded_mode && os_has_conpty_working()) {
|
||||
stdin_dup_fd = os_dup_cloexec(STDIN_FILENO);
|
||||
stdout_dup_fd = os_dup_cloexec(STDOUT_FILENO);
|
||||
// :restart spawns a replacement server that must not borrow the parent
|
||||
// Nvim process console, because that parent process will soon exit.
|
||||
const bool restart_alloc_console = os_env_exists(ENV_RESTART_ALLOC_CONSOLE, true);
|
||||
if (restart_alloc_console) {
|
||||
os_unsetenv(ENV_RESTART_ALLOC_CONSOLE);
|
||||
}
|
||||
if (!GetConsoleWindow()) {
|
||||
// Borrow the parent's console so CONOUT$ resolves to the real terminal,
|
||||
// preserving io.stdout rendering (e.g. SIXEL/Kitty images). Only fall
|
||||
// back to a hidden AllocConsole when there is no parent console (e.g.
|
||||
// launched from a non-console parent), or for the replacement server
|
||||
// spawned by :restart, because the parent Nvim process will soon exit.
|
||||
if (restart_alloc_console || !AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||
// preserving io.stdout rendering (e.g. SIXEL/Kitty images). A replacement
|
||||
// server started by :restart can reuse the current server's console.
|
||||
// Only fall back to a hidden console when the parent has no console.
|
||||
if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||
ILOG("parent console attach failed: %lu; allocating hidden console", GetLastError());
|
||||
AllocConsole();
|
||||
ShowWindow(GetConsoleWindow(), SW_HIDE);
|
||||
}
|
||||
|
||||
@@ -5079,9 +5079,6 @@ static void ex_restart(exarg_T *eap)
|
||||
|
||||
dict_T *env = create_environment(NULL, false, false, false, NULL);
|
||||
tv_dict_add_str(env, S_LEN(ENV_STARTREASON), startreason);
|
||||
#ifdef MSWIN
|
||||
tv_dict_add_str(env, S_LEN(ENV_RESTART_ALLOC_CONSOLE), "1");
|
||||
#endif
|
||||
|
||||
CallbackReader on_err = CALLBACK_READER_INIT;
|
||||
#ifdef MSWIN
|
||||
|
||||
@@ -27,6 +27,5 @@ extern char *default_lib_dir;
|
||||
#define ENV_LOGFILE "NVIM_LOG_FILE"
|
||||
#define ENV_LOGFILE_WANT "__NVIM_LOG_FILE_WANT"
|
||||
#define ENV_NVIM "NVIM"
|
||||
#define ENV_RESTART_ALLOC_CONSOLE "__NVIM_RESTART_ALLOC_CONSOLE"
|
||||
#define ENV_STARTREASON "__NVIM_STARTREASON"
|
||||
#define ENV_TEST_LOG "__NVIM_TEST_LOG"
|
||||
|
||||
Reference in New Issue
Block a user