Skip to content

Commit b3a5d4d

Browse files
authored
fix: CMakeRun now actually uses vim.o.shell on Windows (#369)
1 parent de80d38 commit b3a5d4d

1 file changed

Lines changed: 59 additions & 21 deletions

File tree

lua/cmake-tools/terminal.lua

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -520,8 +520,20 @@ local is_fish_shell = function()
520520
return string.find(shell, "fish")
521521
end
522522

523+
local is_cmd = function()
524+
return string.find(vim.o.shell, "cmd") ~= nil
525+
end
526+
523527
local is_power_shell = function()
524-
return vim.o.shell == "pwsh" or vim.o.shell == "powershell"
528+
return string.find(vim.o.shell, "powershell") ~= nil
529+
end
530+
531+
local is_pwsh = function()
532+
return string.find(vim.o.shell, "pwsh") ~= nil
533+
end
534+
535+
local is_windows_shell = function()
536+
return (is_pwsh() or is_cmd() or is_power_shell())
525537
end
526538

527539
---creates command that handles all of our post command stuff for on_exit handling
@@ -530,23 +542,33 @@ local get_command_handling_on_exit = function()
530542
local exit_code_file_path = get_last_exit_code_file_path()
531543
local lock_file_path = get_lock_file_path()
532544

545+
if osys.iswin32 then
546+
if is_power_shell() or is_pwsh() then
547+
exit_code_file_path = exit_code_file_path:gsub("/", "\\")
548+
lock_file_path = lock_file_path:gsub("/", "\\")
549+
return "`$ec = `$LASTEXITCODE; Set-Content -Path "
550+
.. exit_code_file_path
551+
.. " -Value `$ec; Remove-Item "
552+
.. lock_file_path
553+
elseif is_cmd() then
554+
exit_code_file_path = exit_code_file_path:gsub("/", "\\")
555+
lock_file_path = lock_file_path:gsub("/", "\\")
556+
return "echo !errorlevel! > " .. exit_code_file_path .. " && del /Q " .. lock_file_path
557+
else
558+
-- bash-like on windows
559+
exit_code_file_path = exit_code_file_path:gsub("\\", "/")
560+
lock_file_path = lock_file_path:gsub("\\", "/")
561+
end
562+
end
563+
533564
local exit_op = "$?"
534565
local escape_rm = " \\rm -f "
535566
local and_op = " &&"
536-
537567
if is_fish_shell() then
538568
exit_op = "$status"
539569
escape_rm = " command rm -f "
540570
end
541571

542-
if osys.iswin32 then
543-
exit_op = is_power_shell() and "$LASTEXITCODE" or "%errorlevel%"
544-
and_op = is_power_shell() and " -and" or " &&"
545-
escape_rm = is_power_shell() and " Remove-Item " or " del /Q "
546-
exit_code_file_path = exit_code_file_path:gsub("/", "\\")
547-
lock_file_path = lock_file_path:gsub("/", "\\")
548-
end
549-
550572
return "echo " .. exit_op .. " > " .. exit_code_file_path .. and_op .. escape_rm .. lock_file_path
551573
end
552574

@@ -558,7 +580,9 @@ local get_last_exit_code = function()
558580
print("Could not find last tmp file conaining exit code")
559581
return nil
560582
end
561-
return tonumber(file:read("*n"))
583+
local code = tonumber(file:read("*n"))
584+
file:close()
585+
return code
562586
end
563587

564588
---
@@ -574,7 +598,10 @@ function _terminal.run(cmd, env_script, env, args, cwd, opts, on_exit, on_output
574598
local function prepare_run(cmd, env, args, cwd)
575599
-- Escape all special pattern characters
576600
local escapedCwd = cwd:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1")
577-
cmd = cmd:gsub(escapedCwd, osys.iswin32 and ".\\" or "./")
601+
cmd = cmd:gsub(escapedCwd, (osys.iswin32 and is_windows_shell()) and ".\\" or "./")
602+
if osys.iswin32 and not is_windows_shell() then
603+
cwd = cwd:gsub("\\", "/")
604+
end
578605
cwd = utils.transform_path(cwd)
579606
local envTbl = {}
580607
local fmtStr = osys.iswin32 and "set %s=%s" or "%s=%s"
@@ -597,11 +624,6 @@ function _terminal.run(cmd, env_script, env, args, cwd, opts, on_exit, on_output
597624
-- Reposition the terminal buffer, before sending commands
598625
local final_win_id = _terminal.reposition(opts)
599626

600-
local chain_symb = (osys.iswin32 and "& " or "; ")
601-
if is_power_shell() then
602-
chain_symb = "; "
603-
end
604-
local exit_handler = chain_symb .. get_command_handling_on_exit()
605627
local final_cmd, final_env, final_args, build_dir = prepare_run(cmd, env, args, cwd)
606628
local full_cmd
607629
local call_update
@@ -617,20 +639,36 @@ function _terminal.run(cmd, env_script, env, args, cwd, opts, on_exit, on_output
617639
}
618640

619641
if not opts.use_shell_alias then
620-
full_cmd = (osys.iswin32 and 'cmd /C "' or "")
642+
local shell_prefix, cd_sep, shell_suffix, chain_symb = "", " && ", "", "; "
643+
if osys.iswin32 and is_windows_shell() then
644+
if is_pwsh() or is_power_shell() then
645+
shell_prefix = vim.o.shell .. ' -Command "'
646+
cd_sep = is_pwsh() and " && " or "; " -- 5.1 vs pwsh 7+
647+
else
648+
shell_prefix = 'cmd /V:ON /C "'
649+
cd_sep = " && "
650+
chain_symb = " & "
651+
end
652+
shell_suffix = '"'
653+
end
654+
655+
local exit_handler = chain_symb .. get_command_handling_on_exit()
656+
657+
full_cmd = shell_prefix
621658
.. "cd "
622659
.. build_dir
623-
.. " && "
660+
.. cd_sep
624661
.. (final_env .. (final_env ~= "" and " " or ""))
625662
.. final_cmd
626663
.. ((final_args ~= "" and " " or "") .. final_args)
627664
.. exit_handler
628-
.. (osys.iswin32 and '"' or "")
665+
.. shell_suffix
629666
else
630-
if osys.iswin32 then
667+
if osys.iswin32 and is_windows_shell() then
631668
error("using a shell alias is currently not suported for windows")
632669
end
633670

671+
local exit_handler = "; " .. get_command_handling_on_exit()
634672
local alias_name = "cmake_run_target"
635673
local update_function = "cmake_update_target"
636674

0 commit comments

Comments
 (0)