@@ -520,8 +520,20 @@ local is_fish_shell = function()
520520 return string.find (shell , " fish" )
521521end
522522
523+ local is_cmd = function ()
524+ return string.find (vim .o .shell , " cmd" ) ~= nil
525+ end
526+
523527local 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 ())
525537end
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
551573end
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
562586end
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