commit 6291256868f033cae7c3ef2b30406a2c17090046
parent 6a2883532060124d4c64fc8afb04dd93c47e96d3
Author: zeertzjq <zeertzjq@outlook.com>
Date: Wed, 28 Jan 2026 06:50:49 +0800
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.
Diffstat:
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
@@ -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
@@ -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()