[vim] Fix argument escaping for Windows batch file

Fix #3620
This commit is contained in:
Junegunn Choi 2024-05-01 10:02:26 +09:00
parent a9811addaa
commit 835d2fb98c
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
2 changed files with 22 additions and 5 deletions

View File

@ -27,6 +27,7 @@ CHANGELOG
- `change-multi(0)` - disable multi-select mode
- `become` action is now supported on Windows
- Unlike in *nix, this does not use `execve(2)`. Instead it spawns a new process and waits for it to finish, so the exact behavior may differ.
- Fixed argument escaping for Windows cmd.exe
- Bug fixes and improvements
0.50.0

View File

@ -83,12 +83,28 @@ else
endfunction
endif
let s:cmd_control_chars = ['&', '|', '<', '>', '(', ')', '@', '^', '!']
function! s:shellesc_cmd(arg)
let escaped = substitute(a:arg, '[&|<>()@^]', '^&', 'g')
let escaped = substitute(escaped, '%', '%%', 'g')
let escaped = substitute(escaped, '"', '\\^&', 'g')
let escaped = substitute(escaped, '\(\\\+\)\(\\^\)', '\1\1\2', 'g')
return '^"'.substitute(escaped, '\(\\\+\)$', '\1\1', '').'^"'
let e = '"'
let slashes = 0
for c in split(a:arg, '\zs')
if c ==# '\'
let slashes += 1
elseif c ==# '"'
let e .= repeat('\', slashes + 1)
let slashes = 0
elseif c ==# '%'
let e .= '%'
elseif index(s:cmd_control_chars, c) >= 0
let e .= '^'
else
let slashes = 0
endif
let e .= c
endfor
let e .= repeat('\', slashes) .'"'
return e
endfunction
function! fzf#shellescape(arg, ...)