Skip to content

Commit 835d2fb

Browse files
committed
[vim] Fix argument escaping for Windows batch file
Fix #3620
1 parent a9811ad commit 835d2fb

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ CHANGELOG
2727
- `change-multi(0)` - disable multi-select mode
2828
- `become` action is now supported on Windows
2929
- 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.
30+
- Fixed argument escaping for Windows cmd.exe
3031
- Bug fixes and improvements
3132

3233
0.50.0

plugin/fzf.vim

+21-5
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,28 @@ else
8383
endfunction
8484
endif
8585

86+
let s:cmd_control_chars = ['&', '|', '<', '>', '(', ')', '@', '^', '!']
87+
8688
function! s:shellesc_cmd(arg)
87-
let escaped = substitute(a:arg, '[&|<>()@^]', '^&', 'g')
88-
let escaped = substitute(escaped, '%', '%%', 'g')
89-
let escaped = substitute(escaped, '"', '\\^&', 'g')
90-
let escaped = substitute(escaped, '\(\\\+\)\(\\^\)', '\1\1\2', 'g')
91-
return '^"'.substitute(escaped, '\(\\\+\)$', '\1\1', '').'^"'
89+
let e = '"'
90+
let slashes = 0
91+
for c in split(a:arg, '\zs')
92+
if c ==# '\'
93+
let slashes += 1
94+
elseif c ==# '"'
95+
let e .= repeat('\', slashes + 1)
96+
let slashes = 0
97+
elseif c ==# '%'
98+
let e .= '%'
99+
elseif index(s:cmd_control_chars, c) >= 0
100+
let e .= '^'
101+
else
102+
let slashes = 0
103+
endif
104+
let e .= c
105+
endfor
106+
let e .= repeat('\', slashes) .'"'
107+
return e
92108
endfunction
93109

94110
function! fzf#shellescape(arg, ...)

0 commit comments

Comments
 (0)