Merge branch 'master' into devel

This commit is contained in:
Junegunn Choi 2017-06-03 19:42:26 +09:00
commit f4731c0514
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
3 changed files with 56 additions and 21 deletions

View File

@ -374,8 +374,8 @@ On bash, fuzzy completion is enabled only for a predefined set of commands
commands as well like follows. commands as well like follows.
```sh ```sh
# There are also _fzf_path_completion and _fzf_dir_completion complete -F _fzf_path_completion -o default -o bashdefault ag
complete -F _fzf_file_completion -o default -o bashdefault doge complete -F _fzf_dir_completion -o default -o bashdefault tree
``` ```
Vim plugin Vim plugin

View File

@ -45,19 +45,39 @@ if s:is_win
endtry endtry
endfunction endfunction
function! s:fzf_shellescape(path) " Use utf-8 for fzf.vim commands
return substitute(s:fzf_call('shellescape', a:path), '[^\\]\zs\\"$', '\\\\"', '') " Return array of shell commands for cmd.exe
function! s:wrap_cmds(cmds)
return ['@echo off', 'for /f "tokens=4" %%a in (''chcp'') do set origchcp=%%a', 'chcp 65001 > nul'] +
\ (type(a:cmds) == type([]) ? a:cmds : [a:cmds]) +
\ ['chcp %origchcp% > nul']
endfunction endfunction
else else
function! s:fzf_call(fn, ...) function! s:fzf_call(fn, ...)
return call(a:fn, a:000) return call(a:fn, a:000)
endfunction endfunction
function! s:fzf_shellescape(path) function! s:wrap_cmds(cmds)
return shellescape(a:path) return a:cmds
endfunction endfunction
endif endif
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', 'g')
return '^"'.substitute(escaped, '[^\\]\zs\\$', '\\\\', '').'^"'
endfunction
function! fzf#shellescape(arg, ...)
let shell = get(a:000, 0, &shell)
if shell =~# 'cmd.exe$'
return s:shellesc_cmd(a:arg)
endif
return s:fzf_call('shellescape', a:arg)
endfunction
function! s:fzf_getcwd() function! s:fzf_getcwd()
return s:fzf_call('getcwd') return s:fzf_call('getcwd')
endfunction endfunction
@ -108,7 +128,7 @@ function! s:fzf_exec()
throw 'fzf executable not found' throw 'fzf executable not found'
endif endif
endif endif
return s:is_win ? s:exec : s:shellesc(s:exec) return fzf#shellescape(s:exec)
endfunction endfunction
function! s:tmux_enabled() function! s:tmux_enabled()
@ -128,10 +148,6 @@ function! s:tmux_enabled()
return s:tmux return s:tmux
endfunction endfunction
function! s:shellesc(arg)
return '"'.substitute(a:arg, '"', '\\"', 'g').'"'
endfunction
function! s:escape(path) function! s:escape(path)
let escaped_chars = '$%#''"' let escaped_chars = '$%#''"'
@ -250,7 +266,7 @@ endfunction
function! s:evaluate_opts(options) function! s:evaluate_opts(options)
return type(a:options) == type([]) ? return type(a:options) == type([]) ?
\ join(map(copy(a:options), 's:fzf_shellescape(v:val)')) : a:options \ join(map(copy(a:options), 'fzf#shellescape(v:val)')) : a:options
endfunction endfunction
" [name string,] [opts dict,] [fullscreen boolean] " [name string,] [opts dict,] [fullscreen boolean]
@ -297,7 +313,7 @@ function! fzf#wrap(...)
if !isdirectory(dir) if !isdirectory(dir)
call mkdir(dir, 'p') call mkdir(dir, 'p')
endif endif
let history = s:is_win ? s:fzf_shellescape(dir.'\'.name) : s:escape(dir.'/'.name) let history = fzf#shellescape(dir.'/'.name)
let opts.options = join(['--history', history, opts.options]) let opts.options = join(['--history', history, opts.options])
endif endif
@ -348,8 +364,8 @@ try
if !has_key(dict, 'source') && !empty($FZF_DEFAULT_COMMAND) if !has_key(dict, 'source') && !empty($FZF_DEFAULT_COMMAND)
let temps.source = s:fzf_tempname().(s:is_win ? '.bat' : '') let temps.source = s:fzf_tempname().(s:is_win ? '.bat' : '')
call writefile((s:is_win ? ['@echo off'] : []) + split($FZF_DEFAULT_COMMAND, "\n"), temps.source) call writefile(s:wrap_cmds(split($FZF_DEFAULT_COMMAND, "\n")), temps.source)
let dict.source = (empty($SHELL) ? &shell : $SHELL) . (s:is_win ? ' /c ' : ' ') . s:shellesc(temps.source) let dict.source = (empty($SHELL) ? &shell : $SHELL) . (s:is_win ? ' /c ' : ' ') . fzf#shellescape(temps.source)
endif endif
if has_key(dict, 'source') if has_key(dict, 'source')
@ -360,7 +376,7 @@ try
elseif type == 3 elseif type == 3
let temps.input = s:fzf_tempname() let temps.input = s:fzf_tempname()
call writefile(source, temps.input) call writefile(source, temps.input)
let prefix = (s:is_win ? 'type ' : 'cat ').s:shellesc(temps.input).'|' let prefix = (s:is_win ? 'type ' : 'cat ').fzf#shellescape(temps.input).'|'
else else
throw 'Invalid source type' throw 'Invalid source type'
endif endif
@ -424,7 +440,7 @@ function! s:fzf_tmux(dict)
endif endif
endfor endfor
return printf('LINES=%d COLUMNS=%d %s %s %s --', return printf('LINES=%d COLUMNS=%d %s %s %s --',
\ &lines, &columns, s:shellesc(s:fzf_tmux), size, (has_key(a:dict, 'source') ? '' : '-')) \ &lines, &columns, fzf#shellescape(s:fzf_tmux), size, (has_key(a:dict, 'source') ? '' : '-'))
endfunction endfunction
function! s:splittable(dict) function! s:splittable(dict)
@ -493,7 +509,7 @@ function! s:execute(dict, command, use_height, temps) abort
if has('unix') && !a:use_height if has('unix') && !a:use_height
silent! !clear 2> /dev/null silent! !clear 2> /dev/null
endif endif
let escaped = escape(substitute(a:command, '\n', '\\n', 'g'), '%#!') let escaped = (a:use_height || s:is_win) ? a:command : escape(substitute(a:command, '\n', '\\n', 'g'), '%#!')
if has('gui_running') if has('gui_running')
let Launcher = get(a:dict, 'launcher', get(g:, 'Fzf_launcher', get(g:, 'fzf_launcher', s:launcher))) let Launcher = get(a:dict, 'launcher', get(g:, 'Fzf_launcher', get(g:, 'fzf_launcher', s:launcher)))
let fmt = type(Launcher) == 2 ? call(Launcher, []) : Launcher let fmt = type(Launcher) == 2 ? call(Launcher, []) : Launcher
@ -502,12 +518,13 @@ function! s:execute(dict, command, use_height, temps) abort
endif endif
let command = printf(fmt, escaped) let command = printf(fmt, escaped)
else else
let command = a:use_height ? a:command : escaped let command = escaped
endif endif
if s:is_win if s:is_win
let batchfile = s:fzf_tempname().'.bat' let batchfile = s:fzf_tempname().'.bat'
call writefile(['@echo off', command], batchfile) call writefile(s:wrap_cmds(command), batchfile)
let command = batchfile let command = batchfile
let a:temps.batchfile = batchfile
if has('nvim') if has('nvim')
let s:dict = a:dict let s:dict = a:dict
let s:temps = a:temps let s:temps = a:temps
@ -536,7 +553,7 @@ function! s:execute_tmux(dict, command, temps) abort
let command = a:command let command = a:command
if s:pushd(a:dict) if s:pushd(a:dict)
" -c '#{pane_current_path}' is only available on tmux 1.9 or above " -c '#{pane_current_path}' is only available on tmux 1.9 or above
let command = 'cd '.s:escape(a:dict.dir).' && '.command let command = join(['cd', fzf#shellescape(a:dict.dir), '&&', command])
endif endif
call system(command) call system(command)

View File

@ -147,6 +147,24 @@ Execute (fzf#wrap):
let opts = fzf#wrap({}) let opts = fzf#wrap({})
Assert opts.options =~ '^--color=fg:' Assert opts.options =~ '^--color=fg:'
Execute (fzf#shellescape with sh):
AssertEqual '''''', fzf#shellescape('', 'sh')
AssertEqual '''""''', fzf#shellescape('""', 'sh')
AssertEqual '''foobar>''', fzf#shellescape('foobar>', 'sh')
AssertEqual '''\"''', fzf#shellescape('\"', 'sh')
AssertEqual '''echo ''\''''a''\'''' && echo ''\''''b''\''''''', fzf#shellescape('echo ''a'' && echo ''b''', 'sh')
Execute (fzf#shellescape with cmd.exe):
AssertEqual '^"^"', fzf#shellescape('', 'cmd.exe')
AssertEqual '^"\^"\^"^"', fzf#shellescape('""', 'cmd.exe')
AssertEqual '^"foobar^>^"', fzf#shellescape('foobar>', 'cmd.exe')
AssertEqual '^"\\\^"\\^"', fzf#shellescape('\\\\\\\\"\', 'cmd.exe')
AssertEqual '^"echo ''a'' ^&^& echo ''b''^"', fzf#shellescape('echo ''a'' && echo ''b''', 'cmd.exe')
AssertEqual '^"C:\Program Files ^(x86^)\\^"', fzf#shellescape('C:\Program Files (x86)\', 'cmd.exe')
AssertEqual '^"C:/Program Files ^(x86^)/^"', fzf#shellescape('C:/Program Files (x86)/', 'cmd.exe')
" AssertEqual '^"%%USERPROFILE%%^", fzf#shellescape('%USERPROFILE%', 'cmd.exe')
Execute (Cleanup): Execute (Cleanup):
unlet g:dir unlet g:dir
Restore Restore