From 208951cbc0ccf05b78edbaa10cfa00175e84f864 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 22 Apr 2026 08:12:55 +0800 Subject: [PATCH] fix(:restart): avoid ERR/WRN logging on Windows with --listen (#39287) Problem: :restart leads to ERR/WRN logging on Windows with --listen. Solution: Add a log_level flag to vim._with() and use it to suppress logging from serverstart()/serverstop() during restart. --- runtime/lua/vim/_core/server.lua | 14 ++++++++++++-- src/nvim/log.c | 6 +----- src/nvim/log.h | 6 ++++++ src/nvim/lua/stdlib.c | 15 +++++++++++++-- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/runtime/lua/vim/_core/server.lua b/runtime/lua/vim/_core/server.lua index a79f871cd6..9c18b3811e 100644 --- a/runtime/lua/vim/_core/server.lua +++ b/runtime/lua/vim/_core/server.lua @@ -58,6 +58,9 @@ function M.rebind_old_addr_after_restart(canonical_addr, bootstrap_addr, expecte local poll_elapsed = 0 timer:start(poll_ms, poll_ms, function() vim.schedule(function() + if timer:is_closing() then + return + end poll_elapsed = poll_elapsed + poll_ms if poll_elapsed >= max_wait_ms then timer:stop() @@ -65,7 +68,9 @@ function M.rebind_old_addr_after_restart(canonical_addr, bootstrap_addr, expecte return end if not vim.list_contains(vim.fn.serverlist(), canonical_addr) then - local ok = pcall(vim.fn.serverstart, canonical_addr) + local ok = vim._with({ log_level = 5 }, function() + return pcall(vim.fn.serverstart, canonical_addr) + end) if not ok then return -- pipe still held by old server; retry next tick end @@ -76,11 +81,16 @@ function M.rebind_old_addr_after_restart(canonical_addr, bootstrap_addr, expecte timer:stop() timer:start(poll_ms, poll_ms, function() vim.schedule(function() + if timer:is_closing() then + return + end elapsed = elapsed + poll_ms local all_uis = expected_uis <= 0 or #vim.api.nvim_list_uis() >= expected_uis if all_uis or elapsed >= max_wait_ms then if canonical_addr ~= bootstrap_addr then - pcall(vim.fn.serverstop, bootstrap_addr) + vim._with({ log_level = 5 }, function() + pcall(vim.fn.serverstop, bootstrap_addr) + end) end timer:stop() timer:close() diff --git a/src/nvim/log.c b/src/nvim/log.c index c8cee3bffa..fe119ca41c 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -149,13 +149,9 @@ bool logmsg(int log_level, const char *context, const char *func_name, int line_ return false; } -#ifndef NVIM_LOG_DEBUG - // This should rarely happen (callsites are compiled out), but to be sure. - // TODO(bfredl): allow log levels to be configured at runtime - if (log_level < LOGLVL_WRN) { + if (log_level < g_min_log_level) { return false; } -#endif #ifdef EXITFREE // Logging after we've already started freeing all our memory will only cause diff --git a/src/nvim/log.h b/src/nvim/log.h index d6b5784c10..18f9096b8c 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -51,4 +51,10 @@ # define LOG_CALLSTACK_TO_FILE(fp) log_callstack_to_file(fp, __func__, __LINE__) #endif +#ifndef NVIM_LOG_DEBUG +EXTERN int g_min_log_level INIT( = LOGLVL_WRN); +#else +EXTERN int g_min_log_level INIT( = 0); +#endif + #include "log.h.generated.h" diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c index d6e750e1c1..1b36da4fbb 100644 --- a/src/nvim/lua/stdlib.c +++ b/src/nvim/lua/stdlib.c @@ -8,6 +8,7 @@ #include #include +#include "nvim/log.h" #ifdef NVIM_VENDOR_BIT # include "bit.h" #endif @@ -581,6 +582,7 @@ static int nlua_with(lua_State *L) int flags = 0; buf_T *buf = NULL; win_T *win = NULL; + int log_level = -1; #define APPLY_FLAG(key, flag) \ if (strequal((key), k) && (v)) { \ @@ -594,10 +596,12 @@ static int nlua_with(lua_State *L) if (lua_type(L, -2) == LUA_TSTRING) { const char *k = lua_tostring(L, -2); bool v = lua_toboolean(L, -1); - if (strequal("buf", k)) { \ + if (strequal("buf", k)) { buf = handle_get_buffer((int)luaL_checkinteger(L, -1)); - } else if (strequal("win", k)) { \ + } else if (strequal("win", k)) { win = handle_get_window((int)luaL_checkinteger(L, -1)); + } else if (strequal("log_level", k)) { + log_level = (int)luaL_checkinteger(L, -1); } else { APPLY_FLAG("sandbox", CMOD_SANDBOX); APPLY_FLAG("silent", CMOD_SILENT); @@ -618,6 +622,10 @@ static int nlua_with(lua_State *L) int status = 0; int rets = 0; + const int save_min_log_level = g_min_log_level; + if (log_level >= 0) { + g_min_log_level = log_level; + } cmdmod_T save_cmdmod = cmdmod; CLEAR_FIELD(cmdmod); cmdmod.cmod_flags = flags; @@ -652,6 +660,9 @@ static int nlua_with(lua_State *L) undo_cmdmod(&cmdmod); cmdmod = save_cmdmod; + if (log_level >= 0) { + g_min_log_level = save_min_log_level; + } if (status) { return lua_error(L);