fzf#shellescape() not working with powershell, causing downstream issues
- [ ] 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).
The code has changed a lot since this, can you check if the current version works as expected now?
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.
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...
Fixed by https://github.com/junegunn/fzf.vim/pull/1582#issuecomment-2675925540