fzf icon indicating copy to clipboard operation
fzf copied to clipboard

fzf#shellescape() not working with powershell, causing downstream issues

Open evilnose opened this issue 2 years ago • 1 comments

  • [ ] I have read through the manual page (man fzf)
  • [x ] I have the latest version of fzf
  • [x ] I have searched through the existing issues

Info

  • OS
    • [ ] Linux
    • [ ] Mac OS X
    • [x] Windows
    • [ ] Etc.
  • Shell
    • [ ] bash
    • [ ] zsh
    • [ ] fish
    • [x] PowerShell

Problem / Steps to reproduce

A previously related issue #2888 saw fzf#shellescape() not working correctly for PowerShell. That specific case was fixed by replacing the call with just shellescape(). However, all other places that are still using fzf#shellescape() still don't work for PowerShell.

For example, running :GFiles or :Commits on PowerShell will fail with Not in git repository, because get_git_root(), which uses fzf#shellescape(), fails.

The root cause is the ^ escape added in shellesc_cmd() (link) which is incompatble with powershell. I think we should fully resolve this as proposed by the original reporter, by using " to quote the escaped string instead of ^" (link).

evilnose avatar Feb 27 '23 02:02 evilnose

The code has changed a lot since this, can you check if the current version works as expected now?

junegunn avatar Sep 01 '24 01:09 junegunn

I'm on the latest version 0.60.1 and this issue is still there. I added echoerr fzf#shellescape(dir) inside the function s:get_git_root and I saw that for my repository under C:\myRepo, the error message displayed as ^"C:\myRepo^" which causes GFiles to display Not in git repo. If I remove the call to fzf#shellescape and just pass dir:

let root = systemlist('git -C ' . dir . ' rev-parse --show-toplevel')[0]

then the GFiles command works as expected.

There is still something wrong. I use Neovim on windows. Everything worked correctly until I added this in my Vimrc:

let &shell = executable('pwsh') ? 'pwsh' : 'powershell'
let &shellcmdflag = '-NoLogo -ExecutionPolicy RemoteSigned -Command [Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.UTF8Encoding]::new();$PSDefaultParameterValues[''Out-File:Encoding'']=''utf8'';Remove-Alias -Force -ErrorAction SilentlyContinue tee;'
let &shellredir = '2>&1 | %%{ "$_" } | Out-File %s; exit $LastExitCode'
let &shellpipe  = '2>&1 | %%{ "$_" } | tee %s; exit $LastExitCode'
set shellquote= shellxquote=

which is the recommended Neovim config for setting pwsh as the shell for bang commands.

sim590 avatar Feb 21 '25 01:02 sim590

This is clearly due to the fact that the function s:shellesc_cmd executes substitute(e, '[&|<>()^!"]', '^&', 'g') which doesn't make sense for Powershell. The third argument of substitution should rather be `& in case that &shell is pwsh or powershell (except that I don't know if the value of &shell could also be pwsh in case the user uses Powershell <=5).

EDIT: the config I copy/pasted above in my last comment answers my question in parentheses...

sim590 avatar Feb 21 '25 02:02 sim590

Fixed by https://github.com/junegunn/fzf.vim/pull/1582#issuecomment-2675925540

junegunn avatar Feb 22 '25 01:02 junegunn