[vim] FZF command to handle Windows paths with spaces

- Use noshellslash for strict path expansion in fzf#run and s:cmd
  (shellescape depends on shellslash)
- Double-quote the fzf command for cmd.exe
- Add fzf#shellescape to encapsulate the logic
- Close #786
This commit is contained in:
Jan Edmund Lazo 2016-12-31 23:11:06 -05:00 committed by Junegunn Choi
parent 42a2371d26
commit 6c0fd7f9ca
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627

View File

@ -237,6 +237,19 @@ function! fzf#wrap(...)
return opts return opts
endfunction endfunction
function! fzf#shellescape(path)
if has('win32') || has('win64')
let shellslash = &shellslash
try
set noshellslash
return shellescape(a:path)
finally
let &shellslash = shellslash
endtry
endif
return shellescape(a:path)
endfunction
function! fzf#run(...) abort function! fzf#run(...) abort
try try
let oshell = &shell let oshell = &shell
@ -244,7 +257,7 @@ try
if has('win32') || has('win64') if has('win32') || has('win64')
set shell=cmd.exe set shell=cmd.exe
set shellslash set noshellslash
else else
set shell=sh set shell=sh
endif endif
@ -398,6 +411,8 @@ function! s:execute(dict, command, temps) abort
let fmt = type(Launcher) == 2 ? call(Launcher, []) : Launcher let fmt = type(Launcher) == 2 ? call(Launcher, []) : Launcher
if has('unix') if has('unix')
let escaped = "'".substitute(escaped, "'", "'\"'\"'", 'g')."'" let escaped = "'".substitute(escaped, "'", "'\"'\"'", 'g')."'"
elseif has('win32') || has('win64')
let escaped = '"'.(escaped).'"'
endif endif
let command = printf(fmt, escaped) let command = printf(fmt, escaped)
else else
@ -615,10 +630,10 @@ function! s:cmd(bang, ...) abort
let args = copy(a:000) let args = copy(a:000)
let opts = { 'options': '--multi ' } let opts = { 'options': '--multi ' }
if len(args) && isdirectory(expand(args[-1])) if len(args) && isdirectory(expand(args[-1]))
let opts.dir = substitute(substitute(remove(args, -1), '\\\(["'']\)', '\1', 'g'), '/*$', '/', '') let opts.dir = substitute(substitute(remove(args, -1), '\\\(["'']\)', '\1', 'g'), '[/\\]*$', '/', '')
let opts.options .= ' --prompt '.shellescape(opts.dir) let opts.options .= ' --prompt '.fzf#shellescape(opts.dir)
else else
let opts.options .= ' --prompt '.shellescape(s:shortpath()) let opts.options .= ' --prompt '.fzf#shellescape(s:shortpath())
endif endif
let opts.options .= ' '.join(args) let opts.options .= ' '.join(args)
call fzf#run(fzf#wrap('FZF', opts, a:bang)) call fzf#run(fzf#wrap('FZF', opts, a:bang))