junegunn / fzf

:cherry_blossom: A command-line fuzzy finder
https://junegunn.github.io/fzf/
MIT License
63.79k stars 2.37k forks source link

Rg preview pane shows error in preview.sh in Windows 11 and Powershell #3571

Open mindentropy opened 8 months ago

mindentropy commented 8 months ago

Info

Problem / Steps to reproduce

  1. Open Rg in Gvim
  2. Search for a word
  3. Preview pane shows /bin/bash: line1: C:/Users/mindentropy/vimfiles/plugged/fzf.vim/bin/preview.sh

I check preview.sh and it has #!/usr/bin/env bash but I am not sure whether it is picking up bash. Is Rg supported on Windows 11?

DanSM-5 commented 1 month ago

I think the issue is related to https://github.com/junegunn/fzf.vim/issues/1543 in which it finds bash but it expands the path using cmd and gets a path separated with backlashes \ which bash (or vim) may not like.

I've built my own Rg command and this is how I built the preview

  " find bash from git for windows
  let g:bash = substitute(system('where.exe bash | awk "/[Gg]it/ {print}" | tr -d "\r\n"'), '\n', '', '')
  " Transform bash path to use '/'
  let bash_path = shellescape(substitute(g:bash, '\\', '/', 'g'))
  " Path to preview script. The preview.sh file is the same as fzf.vim/bin/preview.sh with slightly modifications from my part.
  " The MSYS style path '/c' is irrelevant here. Window style path works the same.
  let preview_path = substitute('/c' . $HOMEPATH . '\scripts\utils\preview.sh', '\\', '/', 'g')
  let command_preview = bash_path . ' ' . preview_path . ' {}'

The preview command will look like this when executed by fzf.vim

^"--preview^" ^"\^"C:/Program Files/Git/usr/bin/bash.exe\^" /c/Users/user/scripts/utils/preview.sh {}^"

The fzf#vim#with_preview() generates the preview as follows (before escaping)

'--preview', 'C:\PROGRA~1\Git\usr\bin\bash.exe C:/Users/user/.cache/vimfiles/fzf.vim/bin/preview.sh {}'

The shorted path to bash is generated by passing the path to split(system('for %A in ("'. a:path .'") do @echo %~sA'), "\n")[0] which fzf.vim does internally and it always returns a backlashed path. If you change it to forward slash, it works.

An simple workaround is to manually add the preview arguments rather than calling fzf#vim#with_preview. What it does is to add the --preview argument and a toggle preview binding.

    " instead of:
    " let spec = fzf#vim#with_preview(spec)
    " change to:
    let spec.options = spec.options + [ '--preview', 'C:/PROGRA~1/Git/usr/bin/bash.exe C:/Users/user/.cache/vimfiles/fzf.vim/bin/preview.sh {}', '--bind', 'ctrl-/:toggle-preview' ]
    call fzf#vim#grep(initial_command, spec, a:fullscreen)

You may need to adjust the path to vim or parse the return of fzf#vim#with_preview. I didn't as I'm not very familiar with vim script.