xref: /vim-8.2.3635/src/testdir/test_shell.vim (revision 66315974)
1054794c2SYegappan Lakshmanan" Test for the shell related options ('shell', 'shellcmdflag', 'shellpipe',
2054794c2SYegappan Lakshmanan" 'shellquote', 'shellredir', 'shellxescape', and 'shellxquote')
3054794c2SYegappan Lakshmanan
4054794c2SYegappan Lakshmanansource check.vim
5054794c2SYegappan Lakshmanansource shared.vim
6054794c2SYegappan Lakshmanan
7054794c2SYegappan Lakshmananfunc Test_shell_options()
8ffec6dd1SYegappan Lakshmanan  " The expected value of 'shellcmdflag', 'shellpipe', 'shellquote',
9ffec6dd1SYegappan Lakshmanan  " 'shellredir', 'shellxescape', 'shellxquote' for the supported shells.
10054794c2SYegappan Lakshmanan  let shells = []
11054794c2SYegappan Lakshmanan  if has('unix')
12054794c2SYegappan Lakshmanan    let shells += [['sh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
13054794c2SYegappan Lakshmanan          \ ['ksh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
14054794c2SYegappan Lakshmanan          \ ['mksh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
15054794c2SYegappan Lakshmanan          \ ['zsh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
16054794c2SYegappan Lakshmanan          \ ['zsh-beta', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
17054794c2SYegappan Lakshmanan          \ ['bash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
18054794c2SYegappan Lakshmanan          \ ['fish', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
19054794c2SYegappan Lakshmanan          \ ['ash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
20054794c2SYegappan Lakshmanan          \ ['dash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
21054794c2SYegappan Lakshmanan          \ ['csh', '-c', '|& tee', '', '>&', '', ''],
22a3d1b29bSMike Williams          \ ['tcsh', '-c', '|& tee', '', '>&', '', ''],
23a3d1b29bSMike Williams          \ ['pwsh', '-c', '>%s 2>&1', '', '>%s 2>&1', '', '']]
24054794c2SYegappan Lakshmanan  endif
25054794c2SYegappan Lakshmanan  if has('win32')
26054794c2SYegappan Lakshmanan    let shells += [['cmd', '/c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', ''],
27054794c2SYegappan Lakshmanan          \ ['cmd.exe', '/c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '('],
2812795024SMike Williams          \ ['powershell.exe', '-Command', '2>&1 | Out-File -Encoding default',
2912795024SMike Williams          \           '', '2>&1 | Out-File -Encoding default', '"&|<>()@^', '"'],
3012795024SMike Williams          \ ['powershell', '-Command', '2>&1 | Out-File -Encoding default', '',
3112795024SMike Williams          \               '2>&1 | Out-File -Encoding default', '"&|<>()@^', '"'],
32a3d1b29bSMike Williams          \ ['pwsh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
33a3d1b29bSMike Williams          \ ['pwsh', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
34054794c2SYegappan Lakshmanan          \ ['sh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
35054794c2SYegappan Lakshmanan          \ ['ksh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
36054794c2SYegappan Lakshmanan          \ ['mksh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
37054794c2SYegappan Lakshmanan          \ ['pdksh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
38054794c2SYegappan Lakshmanan          \ ['zsh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
39054794c2SYegappan Lakshmanan          \ ['zsh-beta.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
40054794c2SYegappan Lakshmanan          \ ['bash.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
41054794c2SYegappan Lakshmanan          \ ['dash.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
42054794c2SYegappan Lakshmanan          \ ['csh.exe', '-c', '>&', '', '>&', '"&|<>()@^', '"'],
43054794c2SYegappan Lakshmanan          \ ['tcsh.exe', '-c', '>&', '', '>&', '"&|<>()@^', '"']]
44054794c2SYegappan Lakshmanan  endif
45054794c2SYegappan Lakshmanan
46ffec6dd1SYegappan Lakshmanan  " start a new Vim instance with 'shell' set to each of the supported shells
47ffec6dd1SYegappan Lakshmanan  " and check the default shell option settings
48054794c2SYegappan Lakshmanan  let after =<< trim END
49054794c2SYegappan Lakshmanan    let l = [&shell, &shellcmdflag, &shellpipe, &shellquote]
50054794c2SYegappan Lakshmanan    let l += [&shellredir, &shellxescape, &shellxquote]
51054794c2SYegappan Lakshmanan    call writefile([json_encode(l)], 'Xtestout')
52054794c2SYegappan Lakshmanan    qall!
53054794c2SYegappan Lakshmanan  END
54054794c2SYegappan Lakshmanan  for e in shells
55054794c2SYegappan Lakshmanan    if RunVim([], after, '--cmd "set shell=' .. e[0] .. '"')
56054794c2SYegappan Lakshmanan      call assert_equal(e, json_decode(readfile('Xtestout')[0]))
57054794c2SYegappan Lakshmanan    endif
58054794c2SYegappan Lakshmanan  endfor
59054794c2SYegappan Lakshmanan
60ffec6dd1SYegappan Lakshmanan  " Test shellescape() for each of the shells.
61054794c2SYegappan Lakshmanan  for e in shells
62054794c2SYegappan Lakshmanan    exe 'set shell=' .. e[0]
63054794c2SYegappan Lakshmanan    if e[0] =~# '.*csh$' || e[0] =~# '.*csh.exe$'
64*66315974SBram Moolenaar      let str1 = "'cmd \"arg1\" '\\''arg2'\\'' \\!%# \\'\\'' \\\\! \\% \\#'"
65*66315974SBram Moolenaar      let str2 = "'cmd \"arg1\" '\\''arg2'\\'' \\\\!\\%\\# \\'\\'' \\\\\\! \\\\% \\\\#'"
6612795024SMike Williams    elseif e[0] =~# '.*powershell$' || e[0] =~# '.*powershell.exe$'
67a3d1b29bSMike Williams          \ || e[0] =~# '.*pwsh$' || e[0] =~# '.*pwsh.exe$'
68*66315974SBram Moolenaar      let str1 = "'cmd \"arg1\" ''arg2'' !%# \\'' \\! \\% \\#'"
69*66315974SBram Moolenaar      let str2 = "'cmd \"arg1\" ''arg2'' \\!\\%\\# \\'' \\\\! \\\\% \\\\#'"
706e823511SJason Cox    elseif e[0] =~# '.*fish$' || e[0] =~# '.*fish.exe$'
71*66315974SBram Moolenaar      let str1 = "'cmd \"arg1\" '\\''arg2'\\'' !%# \\\\'\\'' \\\\! \\\\% \\\\#'"
72*66315974SBram Moolenaar      let str2 = "'cmd \"arg1\" '\\''arg2'\\'' \\!\\%\\# \\\\'\\'' \\\\\\! \\\\\\% \\\\\\#'"
73054794c2SYegappan Lakshmanan    else
74*66315974SBram Moolenaar      let str1 = "'cmd \"arg1\" '\\''arg2'\\'' !%# \\'\\'' \\! \\% \\#'"
75*66315974SBram Moolenaar      let str2 = "'cmd \"arg1\" '\\''arg2'\\'' \\!\\%\\# \\'\\'' \\\\! \\\\% \\\\#'"
76054794c2SYegappan Lakshmanan    endif
77*66315974SBram Moolenaar    call assert_equal(str1, shellescape("cmd \"arg1\" 'arg2' !%# \\' \\! \\% \\#"), e[0])
78*66315974SBram Moolenaar    call assert_equal(str2, shellescape("cmd \"arg1\" 'arg2' !%# \\' \\! \\% \\#", 1), e[0])
79ffec6dd1SYegappan Lakshmanan
80ffec6dd1SYegappan Lakshmanan    " Try running an external command with the shell.
81ffec6dd1SYegappan Lakshmanan    if executable(e[0])
82ffec6dd1SYegappan Lakshmanan      " set the shell options for the current 'shell'
83ffec6dd1SYegappan Lakshmanan      let [&shellcmdflag, &shellpipe, &shellquote, &shellredir,
84ffec6dd1SYegappan Lakshmanan            \ &shellxescape, &shellxquote] = e[1:6]
85ffec6dd1SYegappan Lakshmanan      new
86a3d1b29bSMike Williams      try
87ffec6dd1SYegappan Lakshmanan        r !echo hello
88ffec6dd1SYegappan Lakshmanan        call assert_equal('hello', substitute(getline(2), '\W', '', 'g'), e[0])
89a3d1b29bSMike Williams      catch
9011328bc7SYegappan Lakshmanan        call assert_report('Failed to run shell command, shell: ' .. e[0]
9111328bc7SYegappan Lakshmanan              \ .. ', caught ' .. v:exception)
92a3d1b29bSMike Williams      finally
93ffec6dd1SYegappan Lakshmanan        bwipe!
94a3d1b29bSMike Williams      endtry
95ffec6dd1SYegappan Lakshmanan    endif
96054794c2SYegappan Lakshmanan  endfor
97ffec6dd1SYegappan Lakshmanan  set shell& shellcmdflag& shellpipe& shellquote&
98ffec6dd1SYegappan Lakshmanan  set shellredir& shellxescape& shellxquote&
99054794c2SYegappan Lakshmanan  call delete('Xtestout')
100054794c2SYegappan Lakshmananendfunc
101054794c2SYegappan Lakshmanan
102054794c2SYegappan Lakshmanan" Test for the 'shell' option
103054794c2SYegappan Lakshmananfunc Test_shell()
104054794c2SYegappan Lakshmanan  CheckUnix
105054794c2SYegappan Lakshmanan  let save_shell = &shell
106054794c2SYegappan Lakshmanan  set shell=
107054794c2SYegappan Lakshmanan  let caught_e91 = 0
108054794c2SYegappan Lakshmanan  try
109054794c2SYegappan Lakshmanan    shell
110054794c2SYegappan Lakshmanan  catch /E91:/
111054794c2SYegappan Lakshmanan    let caught_e91 = 1
112054794c2SYegappan Lakshmanan  endtry
113054794c2SYegappan Lakshmanan  call assert_equal(1, caught_e91)
114054794c2SYegappan Lakshmanan  let &shell = save_shell
115054794c2SYegappan Lakshmananendfunc
116054794c2SYegappan Lakshmanan
117054794c2SYegappan Lakshmanan" Test for the 'shellquote' option
118054794c2SYegappan Lakshmananfunc Test_shellquote()
119054794c2SYegappan Lakshmanan  CheckUnix
120054794c2SYegappan Lakshmanan  set shellquote=#
121054794c2SYegappan Lakshmanan  set verbose=20
122054794c2SYegappan Lakshmanan  redir => v
123054794c2SYegappan Lakshmanan  silent! !echo Hello
124054794c2SYegappan Lakshmanan  redir END
125054794c2SYegappan Lakshmanan  set verbose&
126054794c2SYegappan Lakshmanan  set shellquote&
127054794c2SYegappan Lakshmanan  call assert_match(': "#echo Hello#"', v)
128054794c2SYegappan Lakshmananendfunc
129054794c2SYegappan Lakshmanan
130ffec6dd1SYegappan Lakshmanan" Test for the 'shellescape' option
131054794c2SYegappan Lakshmananfunc Test_shellescape()
132054794c2SYegappan Lakshmanan  let save_shell = &shell
133054794c2SYegappan Lakshmanan  set shell=bash
134054794c2SYegappan Lakshmanan  call assert_equal("'text'", shellescape('text'))
135054794c2SYegappan Lakshmanan  call assert_equal("'te\"xt'", 'te"xt'->shellescape())
136054794c2SYegappan Lakshmanan  call assert_equal("'te'\\''xt'", shellescape("te'xt"))
137054794c2SYegappan Lakshmanan
138054794c2SYegappan Lakshmanan  call assert_equal("'te%xt'", shellescape("te%xt"))
139054794c2SYegappan Lakshmanan  call assert_equal("'te\\%xt'", shellescape("te%xt", 1))
140054794c2SYegappan Lakshmanan  call assert_equal("'te#xt'", shellescape("te#xt"))
141054794c2SYegappan Lakshmanan  call assert_equal("'te\\#xt'", shellescape("te#xt", 1))
142054794c2SYegappan Lakshmanan  call assert_equal("'te!xt'", shellescape("te!xt"))
143054794c2SYegappan Lakshmanan  call assert_equal("'te\\!xt'", shellescape("te!xt", 1))
144054794c2SYegappan Lakshmanan
145054794c2SYegappan Lakshmanan  call assert_equal("'te\nxt'", shellescape("te\nxt"))
146054794c2SYegappan Lakshmanan  call assert_equal("'te\\\nxt'", shellescape("te\nxt", 1))
147054794c2SYegappan Lakshmanan  set shell=tcsh
148054794c2SYegappan Lakshmanan  call assert_equal("'te\\!xt'", shellescape("te!xt"))
149054794c2SYegappan Lakshmanan  call assert_equal("'te\\\\!xt'", shellescape("te!xt", 1))
150054794c2SYegappan Lakshmanan  call assert_equal("'te\\\nxt'", shellescape("te\nxt"))
151054794c2SYegappan Lakshmanan  call assert_equal("'te\\\\\nxt'", shellescape("te\nxt", 1))
152054794c2SYegappan Lakshmanan
153054794c2SYegappan Lakshmanan  let &shell = save_shell
154054794c2SYegappan Lakshmananendfunc
155054794c2SYegappan Lakshmanan
15612795024SMike Williams" Test for 'shellslash'
15712795024SMike Williamsfunc Test_shellslash()
15812795024SMike Williams  CheckOption shellslash
15912795024SMike Williams  let save_shellslash = &shellslash
16012795024SMike Williams  " The shell and cmdflag, and expected slash in tempname with shellslash set or
16112795024SMike Williams  " unset.  The assert checks the file separator before the leafname.
16212795024SMike Williams  " ".*\\\\[^\\\\]*$"
16312795024SMike Williams  let shells = [['cmd', '/c', '\\', '/'],
16412795024SMike Williams        \ ['powershell', '-Command', '\\', '/'],
165a3d1b29bSMike Williams        \ ['pwsh', '-Command', '\\', '/'],
166a3d1b29bSMike Williams        \ ['pwsh', '-c', '\\', '/'],
16712795024SMike Williams        \ ['sh', '-c', '/', '/']]
16812795024SMike Williams  for e in shells
16912795024SMike Williams    exe 'set shell=' .. e[0] .. ' | set shellcmdflag=' .. e[1]
17012795024SMike Williams    set noshellslash
17112795024SMike Williams    let file = tempname()
17212795024SMike Williams    call assert_match('^.\+' .. e[2] .. '[^' .. e[2] .. ']\+$', file, e[0] .. ' ' .. e[1] .. ' nossl')
17312795024SMike Williams    set shellslash
17412795024SMike Williams    let file = tempname()
17512795024SMike Williams    call assert_match('^.\+' .. e[3] .. '[^' .. e[3] .. ']\+$', file, e[0] .. ' ' .. e[1] .. ' ssl')
17612795024SMike Williams  endfor
17712795024SMike Williams  let &shellslash = save_shellslash
17812795024SMike Williamsendfunc
17912795024SMike Williams
180054794c2SYegappan Lakshmanan" Test for 'shellxquote'
181054794c2SYegappan Lakshmananfunc Test_shellxquote()
182054794c2SYegappan Lakshmanan  CheckUnix
183054794c2SYegappan Lakshmanan
184054794c2SYegappan Lakshmanan  let save_shell = &shell
185054794c2SYegappan Lakshmanan  let save_sxq = &shellxquote
186054794c2SYegappan Lakshmanan  let save_sxe = &shellxescape
187054794c2SYegappan Lakshmanan
188054794c2SYegappan Lakshmanan  call writefile(['#!/bin/sh', 'echo "Cmd: [$*]" > Xlog'], 'Xtestshell')
189054794c2SYegappan Lakshmanan  call setfperm('Xtestshell', "r-x------")
190054794c2SYegappan Lakshmanan  set shell=./Xtestshell
191054794c2SYegappan Lakshmanan
192054794c2SYegappan Lakshmanan  set shellxquote=\\"
193054794c2SYegappan Lakshmanan  call feedkeys(":!pwd\<CR>\<CR>", 'xt')
194054794c2SYegappan Lakshmanan  call assert_equal(['Cmd: [-c "pwd"]'], readfile('Xlog'))
195054794c2SYegappan Lakshmanan
196054794c2SYegappan Lakshmanan  set shellxquote=(
197054794c2SYegappan Lakshmanan  call feedkeys(":!pwd\<CR>\<CR>", 'xt')
198054794c2SYegappan Lakshmanan  call assert_equal(['Cmd: [-c (pwd)]'], readfile('Xlog'))
199054794c2SYegappan Lakshmanan
200054794c2SYegappan Lakshmanan  set shellxquote=\\"(
201054794c2SYegappan Lakshmanan  call feedkeys(":!pwd\<CR>\<CR>", 'xt')
202054794c2SYegappan Lakshmanan  call assert_equal(['Cmd: [-c "(pwd)"]'], readfile('Xlog'))
203054794c2SYegappan Lakshmanan
204054794c2SYegappan Lakshmanan  set shellxescape=\"&<<()@^
205054794c2SYegappan Lakshmanan  set shellxquote=(
206054794c2SYegappan Lakshmanan  call feedkeys(":!pwd\"&<<{}@^\<CR>\<CR>", 'xt')
207054794c2SYegappan Lakshmanan  call assert_equal(['Cmd: [-c (pwd^"^&^<^<{}^@^^)]'], readfile('Xlog'))
208054794c2SYegappan Lakshmanan
209054794c2SYegappan Lakshmanan  let &shell = save_shell
210054794c2SYegappan Lakshmanan  let &shellxquote = save_sxq
211054794c2SYegappan Lakshmanan  let &shellxescape = save_sxe
212054794c2SYegappan Lakshmanan  call delete('Xtestshell')
213054794c2SYegappan Lakshmanan  call delete('Xlog')
214054794c2SYegappan Lakshmananendfunc
215054794c2SYegappan Lakshmanan
216ffec6dd1SYegappan Lakshmanan" Test for using the shell set in the $SHELL environment variable
217ffec6dd1SYegappan Lakshmananfunc Test_set_shell()
218ffec6dd1SYegappan Lakshmanan  let after =<< trim [CODE]
219ffec6dd1SYegappan Lakshmanan    call writefile([&shell], "Xtestout")
220ffec6dd1SYegappan Lakshmanan    quit!
221ffec6dd1SYegappan Lakshmanan  [CODE]
222ffec6dd1SYegappan Lakshmanan
223ffec6dd1SYegappan Lakshmanan  if has('win32')
224ffec6dd1SYegappan Lakshmanan    let $SHELL = 'C:\with space\cmd.exe'
225ffec6dd1SYegappan Lakshmanan    let expected = '"C:\with space\cmd.exe"'
226ffec6dd1SYegappan Lakshmanan  else
227ffec6dd1SYegappan Lakshmanan    let $SHELL = '/bin/with space/sh'
228ffec6dd1SYegappan Lakshmanan    let expected = '/bin/with\ space/sh'
229ffec6dd1SYegappan Lakshmanan  endif
230ffec6dd1SYegappan Lakshmanan
231ffec6dd1SYegappan Lakshmanan  if RunVimPiped([], after, '', '')
232ffec6dd1SYegappan Lakshmanan    let lines = readfile('Xtestout')
233ffec6dd1SYegappan Lakshmanan    call assert_equal(expected, lines[0])
234ffec6dd1SYegappan Lakshmanan  endif
235ffec6dd1SYegappan Lakshmanan  call delete('Xtestout')
236ffec6dd1SYegappan Lakshmananendfunc
237ffec6dd1SYegappan Lakshmanan
238054794c2SYegappan Lakshmanan" vim: shiftwidth=2 sts=2 expandtab
239