commit a7a7cdbcda1f0ef5a29742aea973d2d1c0bfa9a0
parent 1ed064625c1cb71161c4683c5cb0b2d19bf3c091
Author: glepnir <glephunter@gmail.com>
Date: Fri, 13 Feb 2026 19:29:48 +0800
fix(cmd): filter stdin file "-" from v:argv on :restart #37165
Problem:
restart hangs when nvim was started with stdin input, "-" marker stays
in v:argv, causing the restarted instance to block reading from stdin.
Solution:
filter out the "-" argument when rebuilding v:argv during restart.
Stdin content is ephemeral and shouldn't be re-read after restart.
Diffstat:
2 files changed, 73 insertions(+), 21 deletions(-)
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
@@ -4940,27 +4940,31 @@ static void ex_quitall(exarg_T *eap)
/// ":restart +cmd <command>": restart the Nvim server using ":cmd" and add -c <command> to the new server.
static void ex_restart(exarg_T *eap)
{
- // Patch v:argv to include "-c <arg>" when it restarts.
- if (eap->arg != NULL) {
- const list_T *l = get_vim_var_list(VV_ARGV);
- int argc = tv_list_len(l);
- list_T *argv_cpy = tv_list_alloc(argc + 2);
- bool added_startup_arg = false;
- TV_LIST_ITER_CONST(l, li, {
- const char *arg = tv_get_string(TV_LIST_ITEM_TV(li));
- size_t arg_size = strlen(arg);
- assert(arg_size <= (size_t)SSIZE_MAX);
- tv_list_append_string(argv_cpy, arg, (ssize_t)arg_size);
- if (!added_startup_arg) {
- tv_list_append_string(argv_cpy, "-c", 2);
- size_t cmd_size = strlen(eap->arg);
- assert(cmd_size <= (size_t)SSIZE_MAX);
- tv_list_append_string(argv_cpy, eap->arg, (ssize_t)cmd_size);
- added_startup_arg = true;
- }
- });
- set_vim_var_list(VV_ARGV, argv_cpy);
- }
+ const list_T *l = get_vim_var_list(VV_ARGV);
+ int argc = tv_list_len(l);
+ list_T *argv_cpy = tv_list_alloc(eap->arg ? argc + 2 : argc);
+ bool added_startup_arg = false;
+
+ TV_LIST_ITER_CONST(l, li, {
+ const char *arg = tv_get_string(TV_LIST_ITEM_TV(li));
+ size_t arg_size = strlen(arg);
+ assert(arg_size <= (size_t)SSIZE_MAX);
+ // Skip "-" argument (stdin input marker).
+ if (strequal(arg, "-")) {
+ continue;
+ }
+
+ tv_list_append_string(argv_cpy, arg, (ssize_t)arg_size);
+
+ // Patch v:argv to include "-c <arg>" when it restarts.
+ if (eap->arg && !added_startup_arg) {
+ tv_list_append_string(argv_cpy, "-c", 2);
+ tv_list_append_string(argv_cpy, eap->arg, (ssize_t)strlen(eap->arg));
+ added_startup_arg = true;
+ }
+ });
+
+ set_vim_var_list(VV_ARGV, argv_cpy);
char *quit_cmd = (eap->do_ecmd_cmd) ? eap->do_ecmd_cmd : "qall";
char *quit_cmd_copy = NULL;
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
@@ -428,6 +428,54 @@ describe('TUI :restart', function()
restart_pid_check()
gui_running_check()
end)
+
+ it('filters stdin marker from v:argv on restart #34417', function()
+ t.skip(is_os('win'), 'stdin behavior differs on Windows')
+ clear()
+ local server_session
+ finally(function()
+ if server_session then
+ server_session:close()
+ end
+ n.check_close()
+ end)
+ local server_pipe = new_pipename()
+ local screen = tt.setup_child_nvim({
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--listen',
+ server_pipe,
+ '--cmd',
+ 'set notermguicolors',
+ '-',
+ })
+ screen:expect([[
+ ^ |
+ ~ |*3
+ {2:[No Name] [RO] 1,0-1 All}|
+ |
+ {5:-- TERMINAL --} |
+ ]])
+ server_session = n.connect(server_pipe)
+ local expr = 'index(v:argv, "-") >= 0 ? v:true : v:false'
+ local _, has_stdin = server_session:request('nvim_eval', expr)
+ eq(true, has_stdin)
+
+ tt.feed_data(':restart\013')
+ screen:expect([[
+ ^ |
+ ~ |*3
+ {2:[No Name] 0,0-1 All}|
+ |
+ {5:-- TERMINAL --} |
+ ]])
+ server_session:close()
+ server_session = n.connect(server_pipe)
+ local _, has_stdin_after = server_session:request('nvim_eval', expr)
+ eq(false, has_stdin_after)
+ end)
end)
describe('TUI :connect', function()