doc(options): Fix recommended PowerShell config (#14349)

Ensure that
  * Shell uses UTF8 input/output mode
  * Stderr output is captured, in UTF8
  * Program exit codes are correctly captured

Update functional test harness and add tests
for :make command.

Closes #13713
This commit is contained in:
Dimitri Tcaciuc
2021-07-02 05:15:40 -07:00
committed by GitHub
parent 7d8202087b
commit 8b07653902
4 changed files with 85 additions and 7 deletions

View File

@@ -5238,11 +5238,12 @@ A jump table for the options with a short description can be found at |Q_op|.
Note that such processing is done after |:set| did its own round of
unescaping, so to keep yourself sane use |:let-&| like shown above.
*shell-powershell*
To use powershell: >
To use PowerShell: >
let &shell = has('win32') ? 'powershell' : 'pwsh'
set shellquote= shellpipe=\| shellxquote=
set shellcmdflag=-NoLogo\ -NoProfile\ -ExecutionPolicy\ RemoteSigned\ -Command
set shellredir=\|\ Out-File\ -Encoding\ UTF8
let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command [Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;'
let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode'
let &shellpipe = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode'
set shellquote= shellxquote=
< This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.

View File

@@ -174,6 +174,21 @@ describe('system()', function()
end)
end
it('works with powershell w/ UTF-8 text (#13713)', function()
if not helpers.has_powershell() then
pending("not tested; powershell was not found", function() end)
return
end
-- Should work with recommended config used in helper
helpers.set_shell_powershell()
eq('ああ\n', eval([[system('Write-Output "ああ"')]]))
-- Sanity test w/ default encoding
-- * on Windows, expected to default to Western European enc
-- * on Linux, expected to default to UTF8
command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']])
eq(iswin() and '??\n' or 'ああ\n', eval([[system('Write-Output "ああ"')]]))
end)
it('`echo` and waits for its return', function()
feed(':call system("echo")<cr>')
screen:expect([[
@@ -554,4 +569,20 @@ describe('systemlist()', function()
assert(out[1]:sub(0, 5) == 'pid: ', out)
os_kill(out[1]:match("%d+"))
end)
it('works with powershell w/ UTF-8 text (#13713)', function()
if not helpers.has_powershell() then
pending("not tested; powershell was not found", function() end)
return
end
-- Should work with recommended config used in helper
helpers.set_shell_powershell()
eq({iswin() and '\r' or ''}, eval([[systemlist('Write-Output あ')]]))
-- Sanity test w/ default encoding
-- * on Windows, expected to default to Western European enc
-- * on Linux, expected to default to UTF8
command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']])
eq({iswin() and '?\r' or ''}, eval([[systemlist('Write-Output あ')]]))
end)
end)

View File

@@ -0,0 +1,44 @@
local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eval = helpers.eval
local has_powershell = helpers.has_powershell
local matches = helpers.matches
local nvim = helpers.nvim
local nvim_dir = helpers.nvim_dir
describe(':make', function()
clear()
before_each(function ()
clear()
end)
describe('with powershell', function()
if not has_powershell() then
pending("not tested; powershell was not found", function() end)
return
end
before_each(function ()
helpers.set_shell_powershell()
end)
it('captures stderr & non zero exit code #14349', function ()
nvim('set_option', 'makeprg', nvim_dir..'/shell-test foo')
local out = eval('execute("make")')
-- Make program exit code correctly captured
matches('\nshell returned 3', out)
-- Error message is captured in the file and printed in the footer
matches('\n.*%: Unknown first argument%: foo', out)
end)
it('captures stderr & zero exit code #14349', function ()
nvim('set_option', 'makeprg', nvim_dir..'/shell-test')
local out = eval('execute("make")')
-- Ensure there are no "shell returned X" messages between
-- command and last line (indicating zero exit)
matches('LastExitCode%s+[(]', out)
matches('\n.*%: ready [$]', out)
end)
end)
end)

View File

@@ -513,13 +513,15 @@ end
function module.set_shell_powershell()
local shell = iswin() and 'powershell' or 'pwsh'
assert(module.has_powershell())
local cmd = 'Remove-Item -Force '..table.concat(iswin()
local set_encoding = '[Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;'
local cmd = set_encoding..'Remove-Item -Force '..table.concat(iswin()
and {'alias:cat', 'alias:echo', 'alias:sleep'}
or {'alias:echo'}, ',')..';'
module.source([[
let &shell = ']]..shell..[['
set shellquote= shellpipe=\| shellxquote=
let &shellredir = '| Out-File -Encoding UTF8'
set shellquote= shellxquote=
let &shellpipe = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode'
let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode'
let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ]]..cmd..[['
]])
end