From 6291256868f033cae7c3ef2b30406a2c17090046 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 28 Jan 2026 06:50:49 +0800 Subject: [PATCH] fix(process): avoid buffering unnecessary UI event with PTY CWD (#37582) Problem: Calling os_chdir() to change the child processes' CWD may cause some unnecessary UI events to be buffered. These UI events don't go anywhere as execvp() is called before flushing the UI buffer. Solution: Use uv_chdir() instead of os_chdir(). Also fix getting error string incorrectly. Add test for the current behavior. --- src/nvim/os/pty_proc_unix.c | 6 ++++-- test/functional/core/job_spec.lua | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/nvim/os/pty_proc_unix.c b/src/nvim/os/pty_proc_unix.c index 1b5f520b5c..94dc4297bd 100644 --- a/src/nvim/os/pty_proc_unix.c +++ b/src/nvim/os/pty_proc_unix.c @@ -281,8 +281,10 @@ static void init_child(PtyProc *ptyproc) signal(SIGALRM, SIG_DFL); Proc *proc = (Proc *)ptyproc; - if (proc->cwd && os_chdir(proc->cwd) != 0) { - ELOG("chdir(%s) failed: %s", proc->cwd, strerror(errno)); + int err = 0; + // Don't use os_chdir() as that may buffer UI events unnecessarily. + if (proc->cwd && (err = uv_chdir(proc->cwd)) != 0) { + ELOG("chdir(%s) failed: %s", proc->cwd, uv_strerror(err)); return; } diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua index 83f60e994e..bfd0a1612d 100644 --- a/test/functional/core/job_spec.lua +++ b/test/functional/core/job_spec.lua @@ -246,9 +246,12 @@ describe('jobs', function() eq({ 'notification', 'exit', { 0, 0 } }, next_msg()) end) - it('changes to given `cwd` directory', function() + local function test_job_cwd() local dir = eval('resolve(tempname())'):gsub('/', get_pathsep()) mkdir(dir) + finally(function() + rmdir(dir) + end) command("let g:job_opts.cwd = '" .. dir .. "'") if is_os('win') then command("let j = jobstart('cd', g:job_opts)") @@ -269,7 +272,15 @@ describe('jobs', function() { 'notification', 'exit', { 0, 0 } }, } ) - rmdir(dir) + end + + it('changes to given `cwd` directory', function() + test_job_cwd() + end) + + it('changes to given `cwd` directory with pty', function() + command('let g:job_opts.pty = v:true') + test_job_cwd() end) it('fails to change to invalid `cwd`', function()