From a87e91677c8d25d4db9454f96fae3abf295ffdd5 Mon Sep 17 00:00:00 2001 From: Sanzhar Kuandyk <92693103+SanzharKuandyk@users.noreply.github.com> Date: Tue, 21 Jul 2026 16:58:44 +0500 Subject: [PATCH] fix(system): use native path for Windows executables #40885 Problem: When 'shellslash' is set, exepath() returns forward-slashed paths. Passing that path to vim.system() can prevent cmd.exe from launching. Solution: Convert the resolved executable path to native separators before spawning. Add a Windows regression test for cmd.exe with 'shellslash' enabled. --- runtime/lua/vim/_core/system.lua | 3 ++- test/functional/lua/system_spec.lua | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/runtime/lua/vim/_core/system.lua b/runtime/lua/vim/_core/system.lua index bc00042aba..3ff4bcdc2f 100644 --- a/runtime/lua/vim/_core/system.lua +++ b/runtime/lua/vim/_core/system.lua @@ -319,7 +319,8 @@ local function spawn(cmd, opts, on_exit, on_error) if is_win then local cmd1 = vim.fn.exepath(cmd) if cmd1 ~= '' then - cmd = cmd1 + -- Use native separators when launching a resolved Windows executable. + cmd = cmd1:gsub('/', '\\') end end diff --git a/test/functional/lua/system_spec.lua b/test/functional/lua/system_spec.lua index e7a7448fa7..188d430b7c 100644 --- a/test/functional/lua/system_spec.lua +++ b/test/functional/lua/system_spec.lua @@ -130,6 +130,17 @@ describe('vim.system', function() n.system_sync({ 'chmod', '+x', 'test.bat' }) n.system_sync({ './test' }) end) + + it('launches cmd.exe when shellslash is set', function() + n.command('set shellslash') + local path = exec_lua([[return vim.fn.exepath('cmd.exe')]]) + t.neq(nil, path:find('/', 1, true)) + + local result = n.system_sync({ 'cmd.exe', '/c', 'echo OK' }) + eq(0, result.code) + eq('OK\r\n', result.stdout) + eq('', result.stderr) + end) end it('always captures all content of stdout/stderr #30846', function()