FZF appears to swallow key presses when used with `less` on Git Bash with ZSH on Windows
Checklist
- [x] I have read through the manual page (
man fzf) - [x] I have searched through the existing issues
- [x] For bug reports, I have checked if the bug is reproducible in the latest version of fzf
Output of fzf --version
0.60.0 (3347d61)
OS
- [ ] Linux
- [ ] macOS
- [x] Windows
- [ ] Etc.
Shell
- [x] bash
- [x] zsh
- [ ] fish
Problem / Steps to reproduce
Steps
- Open a terminal using either Git Bash or ZSH within Git Bash.
- Enter
echo "<file>" | fzf --bind="enter:execute(less {})"where<file>is any regular file. - The
fzfprompt appears with the given file. Press enter to select it.
- The
lessprompt opens. Now try to press any key (j, k, etc) and see that nothing happens. Pressing Esc,<C-d>,<C-x>or<C-c>also have no effect. The only way to return to ZSH is to manually kill thelessprocess.
Notes
- If only regular keys are pressed (i.e. keys without any modifiers) and the
lessprocess is killed, the pressed keys will appear infzf's prompt, which seems to indicate thatfzfis somehow swallowing the key presses that should've gone toless. In the example below, I pressedklbefore killing thelessprocess. See that the pressed keys appear infzf's prompt.
- The issue is exclusive to Windows, Linux does not present this problem.
- The issue is reproducible in either Git Bash or Git Bash + ZSH.
The issue was first noticed in forgit and reported at wfxr/forgit#423. After diagnosing, it was determined that the problem is with fzf itself.
@junegunn I'm not overly familiar with debugging shell code, but I'm willing to help debug this if you have any ideas of what could be going on.
I have no idea. One thing I'd like to check is if fzf is using winpty on your environment.
https://github.com/junegunn/fzf/blob/3ba82b6d87348b119f9a7fd168ad8a597a18b4b2/src/winpty_windows.go#L14-L44
- What is the value of
$TERM_PROGRAM_VERSION? - And
$TERM_PROGRAM? - Does setting
MSYS=enable_pconmake any difference?
For both Git bash with ZSH and vanilla Git bash:
- Output of
$TERM_PROGRAM_VERSION: none. The variable isn't set - Output of
$TERM_PROGRAM: none. The variable isn't set - Using
export MSYS=enable_pcondoesn't change the behaviour.
I started a Windows Server 2025 instance on EC2, installed the latest Git bash, downloaded fzf 0.60.2, and tested it.
So here's what I've found.
seq 1000 > test
# less opens and closes immediately
echo test | ./fzf --bind 'enter:execute:less {}'
# But with the redirection, less works
# * NOTE: On non-Windows systems, this is not required
# https://github.com/junegunn/fzf/commit/3dee8778d073199e0fe1e186e54f7eabc2fdef43
echo test | ./fzf --bind 'enter:execute:less {} > /dev/tty'
# However, when using a non-fullscreen renderer, less becomes unresponsive as reported
echo test | ./fzf --bind 'enter:execute:less {} > /dev/tty' --height 50%
So the issue has to do with the LightRenderer implementation for Windows.
https://github.com/junegunn/fzf/blob/master/src/tui/light_windows.go
This seems to be the culprit.
https://github.com/junegunn/fzf/blob/21ce70054f4f65efafcd056d1101f1040187c8d4/src/tui/light_windows.go#L70-L84
Can you test 8916cbc6ab198abdfa1e5cb24602c13730cb1987?
Attaching the amd64 binary. fzf.exe.zip
It still has a problem of consuming a key for execute program, but it's not trivial to properly fix it.
This pretty much solves it. The first key press is still being swallowed, but subsequent key presses work as expected. With the repro I gave for this issue, if I want to exit less I need to press q twice. That said, this is significantly better than before as I can use commands invoked through fzf! Thanks for the quick turnaround!
Thanks for the confirmation. I'll release a new patch version with the (partial) fix and keep this open until we find the perfect solution.
Some pointers:
- https://github.com/muesli/cancelreader/blob/main/cancelreader_windows.go