Skip to content

Commit

Permalink
Fix: Windows preview window logic, including git diff preview (#1452)
Browse files Browse the repository at this point in the history
Co-authored-by: Junegunn Choi <[email protected]>
  • Loading branch information
psyngw and junegunn authored Jan 16, 2023
1 parent 9c37e68 commit bdf48c2
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 26 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 130,12 @@ let g:fzf_preview_window = ['hidden,right,50%,<70(up,40%)', 'ctrl-/']
" Empty value to disable preview window altogether
let g:fzf_preview_window = []
" fzf.vim needs bash to display the preview window.
" On Windows, fzf.vim will first see if bash is in $PATH, then if
" Git bash (C:\Program Files\Git\bin\bash.exe) is available.
" If you want it to use a different bash, set this variable.
" let g:fzf_preview_bash = 'C:\Git\bin\bash.exe'
```

### Command-local options
Expand Down
92 changes: 67 additions & 25 deletions autoload/fzf/vim.vim
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 28,66 @@ set cpo&vim
" Common
" ------------------------------------------------------------------

let s:winpath = {}
function! s:winpath(path)
if has_key(s:winpath, a:path)
return s:winpath[a:path]
endif

let winpath = split(system('for %A in ("'.a:path.'") do @echo %~sA'), "\n")[0]
let s:winpath[a:path] = winpath

return winpath
endfunction

let s:warned = 0
function! s:bash()
if exists('s:bash')
return s:bash
endif

let custom_bash = get(g:, 'fzf_preview_bash', '')
let git_bash = 'C:\Program Files\Git\bin\bash.exe'
let candidates = filter(s:is_win ? [custom_bash, 'bash', git_bash] : [custom_bash, 'bash'], 'len(v:val)')

let found = filter(map(copy(candidates), 'exepath(v:val)'), 'len(v:val)')
if empty(found)
if !s:warned
call s:warn(printf('Preview window not supported (%s not found)', join(candidates, ', ')))
let s:warned = 1
endif
let s:bash = ''
return s:bash
endif

let s:bash = found[0]

" Make 8.3 filename via cmd.exe
if s:is_win
let s:bash = s:winpath(s:bash)
endif

return s:bash
endfunction

function! s:escape_for_bash(path)
if !s:is_win
return fzf#shellescape(a:path)
endif

if !exists('s:is_linux_like_bash')
call system(s:bash . ' -c "ls /mnt/[A-Za-z]"')
let s:is_linux_like_bash = v:shell_error == 0
endif

let path = substitute(a:path, '\', '/', 'g')
if s:is_linux_like_bash
let path = substitute(path, '^\([A-Z]\):', '/mnt/\L\1', '')
endif

return escape(path, ' ')
endfunction

let s:min_version = '0.23.0'
let s:is_win = has('win32') || has('win64')
let s:is_wsl_bash = s:is_win && (exepath('bash') =~? 'Windows[/\\]system32[/\\]bash.exe$')
Expand All @@ -37,19 97,8 @@ let s:bin = {
\ 'preview': s:bin_dir.'preview.sh',
\ 'tags': s:bin_dir.'tags.pl' }
let s:TYPE = {'dict': type({}), 'funcref': type(function('call')), 'string': type(''), 'list': type([])}
if s:is_win
if has('nvim')
let s:bin.preview = split(system('for %A in ("'.s:bin.preview.'") do @echo %~sA'), "\n")[0]
else
let preview_path = s:is_wsl_bash
\ ? substitute(s:bin.preview, '^\([A-Z]\):', '/mnt/\L\1', '')
\ : fnamemodify(s:bin.preview, ':8')
let s:bin.preview = substitute(preview_path, '\', '/', 'g')
endif
endif

let s:wide = 120
let s:warned = 0
let s:checked = 0

function! s:check_requirements()
Expand Down Expand Up @@ -108,11 157,7 @@ function! fzf#vim#with_preview(...)
call remove(args, 0)
endif

if !executable('bash')
if !s:warned
call s:warn('Preview window not supported (bash not found in PATH)')
let s:warned = 1
endif
if !executable(s:bash())
return spec
endif

Expand Down Expand Up @@ -149,12 194,8 @@ function! fzf#vim#with_preview(...)
if s:is_wsl_bash && $WSLENV !~# '[:]\?MSWINHOME\(\/[^:]*\)\?\(:\|$\)'
let $WSLENV = 'MSWINHOME/u:'.$WSLENV
endif
let preview_cmd = 'bash '.(s:is_wsl_bash
\ ? s:bin.preview
\ : escape(s:bin.preview, '\'))
else
let preview_cmd = 'bash ' . fzf#shellescape(s:bin.preview)
endif
let preview_cmd = s:bash() . ' ' . s:escape_for_bash(s:bin.preview)
if len(placeholder)
let preview = ['--preview', preview_cmd.' '.placeholder]
end
Expand Down Expand Up @@ -649,12 690,13 @@ function! fzf#vim#gitfiles(args, ...)
" We're trying to access the common sink function that fzf#wrap injects to
" the options dictionary.
let bar = s:is_win ? '^|' : '|'
let diff_prefix = 'git -C ' . s:escape_for_bash(root) . ' '
let preview = printf(
\ 'bash -c "if [[ {1} =~ M ]]; then %s; else %s {-1}; fi"',
\ s:bash() . ' -c "if [[ {1} =~ M ]]; then %s; else %s {-1}; fi"',
\ executable('delta')
\ ? prefix . 'diff -- {-1} ' . bar . ' delta --width $FZF_PREVIEW_COLUMNS --file-style=omit ' . bar . ' sed 1d'
\ : prefix . 'diff --color=always -- {-1} ' . bar . ' sed 1,4d',
\ s:bin.preview)
\ ? diff_prefix . 'diff -- {-1} ' . bar . ' delta --width $FZF_PREVIEW_COLUMNS --file-style=omit ' . bar . ' sed 1d'
\ : diff_prefix . 'diff --color=always -- {-1} ' . bar . ' sed 1,4d',
\ s:escape_for_bash(s:bin.preview))
let wrapped = fzf#wrap({
\ 'source': prefix . '-c color.status=always status --short --untracked-files=all',
\ 'dir': root,
Expand Down
8 changes: 7 additions & 1 deletion doc/fzf-vim.txt
Original file line number Diff line number Diff line change
@@ -1,4 1,4 @@
fzf-vim.txt fzf-vim Last change: January 8 2023
fzf-vim.txt fzf-vim Last change: January 15 2023
FZF-VIM - TABLE OF CONTENTS *fzf-vim* *fzf-vim-toc*
==============================================================================

Expand Down Expand Up @@ -195,6 195,12 @@ behavior with `g:fzf_preview_window`. Here are some examples:
" Empty value to disable preview window altogether
let g:fzf_preview_window = []
" fzf.vim needs bash to display the preview window.
" On Windows, fzf.vim will first see if bash is in $PATH, then if
" Git bash (C:\Program Files\Git\bin\bash.exe) is available.
" If you want it to use a different bash, set this variable.
" let g:fzf_preview_bash = 'C:\Git\bin\bash.exe'
<

< Command-local options >_____________________________________________________~
Expand Down

0 comments on commit bdf48c2

Please sign in to comment.