Commit Graph
163 Commits
Author SHA1 Message Date
Junegunn Choi 88fb21a61d Drop unrecognized escape sequences instead of typing them
- Frame CSI by parameter and final byte ranges, string sequences (OSC,
  DCS, APC) by ST or BEL terminator
- Consume framed sequence whole. Partial consumption left remainder to be
  read as input: CTRL-A as \e[97;5u typed "97;5u" into query
- BEL-terminated OSC reply was worse than junk. Payload typed, then BEL
  read as CTRL-G, aborting fzf. \e]0;title\a was enough
- Wait for string terminator in read loop, as already done for CSI
- Take second-chance read only while sequence unfinished. Re-reading after
  complete one blocked until next keystroke, holding back what followed
- Leave unterminated sequences alone. That is how ALT-[ and ALT-] arrive
- Skip SOS and PM. Nothing sends them, and waiting for a terminator that
  never comes would delay ALT-X and ALT-^
2026-09-26 17:39:47 +09:00
Junegunn Choi b224480a98 Do not erase the line the prompt was on (#4918)
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
- When the cursor is not at column 0, Init() makes space so fzf draws on
  the next line and the prompt line is left intact
- Close() undid that: it moved up onto the prompt line before ESC[J, so
  the erase wiped a line fzf never wrote on
- Shells repaint afterwards, so it showed as a flicker of the last prompt
  line. Reported on fish, also seen on bash and nushell. zsh erases the
  same line but repaints fast enough to hide it
- Erase our own area first, then step back and restore the column, so
  nothing on that line is touched, RPROMPT included

Fix #4913
2026-09-10 23:19:38 +09:00
Junegunn Choi 1578b7c3c3 Fix spurious exit while waiting for a key with --listen
- getch() charged EINTR against a 100 iteration limit meant for read
  attempts, and the count only reset once a byte was read
- So signals arriving during an idle prompt drained it, and running out
  returned getCharError, which became Event{Fatal} and exit status 2
- Only the cancellable path is affected, hence only --listen
- select() is not restarted by SA_RESTART, unlike the blocking read on
  the non-cancellable path, so it is the only one that sees EINTR
- waitReadable() already retries EINTR without a limit

Fix #4917
2026-09-10 17:56:15 +09:00
Junegunn Choi d46bfd005a Keep a minimum wait for a sequence in flight
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
ESCDELAY=0 makes the retry count zero, so the wait added in d0377ed had
no effect and the reply still leaked. Past the introducer these bytes
cannot be the ESC key, so waiting for them adds no Escape latency.

- Wait at least defaultEscDelay, honour a larger ESCDELAY
- Lone ESC still honours ESCDELAY=0, measured 3ms to exit either way

Fix #4899
2026-08-24 09:54:09 +09:00
Junegunn Choi d0377ed4dc Wait for rest of escape sequence before parsing (#4901)
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
Read loop dropped its escDelay retry budget after every successful byte,
so a sequence split across reads reached the parser as a fragment, parsed
as ALT-[ with the remainder left behind as query text.

- fzf queries DECRQM at startup since dab626b, so a terminal answering
  late leaked "?2004;2$y" into the query
- Same split leaked modified keys and mouse sequences: CTRL-UP left "5A",
  SGR mouse left "0;1;1M"
- Bound unchanged, a stall longer than escDelay still falls back to ALT

Fix #4899
2026-08-24 00:40:06 +09:00
Junegunn Choi ca4c1b80e3 Erase 'p' on Terminal.app
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
Terminal.app fails to properly handle DECRQM and leaves 'p' on the
screen.

Fix #4893
2026-08-11 23:42:09 +09:00
Junegunn Choi dab626bd9e Restore bracketed paste mode instead of forcing it off
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
Ask the terminal whether the mode is already on (DECRQM) and put it back
that way on exit. Forcing it off broke pasting in shells that run fzf
from a line editor widget, which enable the mode only when the editor
starts. Terminals that do not answer fall back to disabling it.

- Startup queries go out in one write, cursor position last. Every
  terminal answers DSR, so its reply bounds the wait: a paste reply
  still missing by then means the terminal does not know the query.
- Bound the first read with select(2). Terminals that never answer
  escape sequences, such as FreeBSD virtual terminals, blocked startup
  until a key was pressed, and that keystroke was then discarded.

Fix #4887
Fix #2860
Fix #976
2026-08-10 22:36:25 +09:00
Junegunn Choi 3c0de84dab Skip redundant SGR sequences in light renderer
Track the last emitted SGR sequence and skip no-op transitions.
Reduces rendering output by 10-23% depending on the scenario.
2026-07-17 10:34:42 +09:00
Junegunn Choi 374b01242d Wrap frames in synchronized update mode (2026)
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
Reduce flickering during rendering on supported terminals.
2026-07-16 23:20:29 +09:00
Junegunn Choi c0860259fa Use DECSC/DECRC instead of CSI s/u
Honored by more terminals, e.g. fixes cursor restoration with
--height --no-clear inside nvim terminal.
2026-07-16 23:00:39 +09:00
Junegunn Choi 1462f1358d Comment cleanup
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
2026-07-15 18:30:17 +09:00
Junegunn Choi 8e340dabbc Use CHA for absolute horizontal cursor movement
Related:
- #4858
- https://github.com/zellij-org/zellij/issues/5370
2026-07-15 18:23:08 +09:00
Jason Han 9e4f8e7b7a Fix horizontal mouse wheel being treated as vertical scroll
Close #4848
2026-06-28 22:15:03 +09:00
Junegunn Choi 263eb4732f Strip UTF-8-encoded C1 control characters from rendered items
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
The display sanitizer already stripped raw 8-bit C1 bytes (0x80-0x9F)
because they decode to RuneError as standalone bytes. Their valid UTF-8
encodings (0xC2 0x80 .. 0xC2 0x9F) decode to the same code points but
were passed through, allowing a filename or input line containing CSI
(U+009B), OSC (U+009D), or DCS (U+0090) to inject terminal control
sequences when rendered.
2026-05-05 09:56:59 +09:00
Junegunn Choi d247284bc3 Set inline separator caps per side 2026-04-20 00:47:16 +09:00
Junegunn Choi d754cfab87 Add --{header,header-lines,footer}-border=inline
New BorderShape that embeds the section inside the --list-border
frame, joined to the list content by a horizontal separator with
T-junctions where the list shape has side borders. Requires a list
border with both top and bottom segments; falls back to 'line'
otherwise. Stacks when multiple sections are inline.

Sections inherit --color list-border by default and are colored as a
uniform block via their own --color *-border and *-bg.

Incompatible with --header-first. --header-border=inline requires
--header-lines-border to be inline or unset.
2026-04-20 00:47:16 +09:00
Tymoteusz Makowski 1ad7c617b1 fix: add no-modifiers fallbacks
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Close #4776
2026-04-19 14:38:36 +09:00
Junegunn Choi c338df02c4 Fix --preview-window follow not working correctly with wrapping
Fix #3243
Fix #4258
2026-02-18 21:36:35 +09:00
Junegunn Choi b6411beaa1 Implement word wrapping in the preview window
Example:
  fzf --preview 'bat --style=plain --color=always {}' \
      --preview-window wrap-word \
      --bind space:toggle-preview-wrap-word

Close https://github.com/junegunn/fzf/discussions/3383
2026-02-18 13:35:02 +09:00
Junegunn Choi b56d614ba2 Add underline style variants and underline color support
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Support double, curly, dotted, and dashed underline styles via --color
(e.g. underline-curly) and ANSI passthrough (SGR 4:N, 58, 59) with --ansi.

Close #4633
Close #4678

Thanks to @shtse8 for the test cases.
2026-02-15 01:06:46 +09:00
Junegunn Choi 14564e4fc7 Avoid clearing the rest of the current line on start
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Generate Sponsors README / deploy (push) Has been cancelled
Fix #4652

Code was reorganized so that it doesn't delete the current line if the
cursor is not at the front. This should be acceptable in almost all
cases.

Thanks to @phanen for reporting the issue and suggesting the fix.
2026-01-22 12:23:29 +09:00
Junegunn Choi 3f94bcb5bf Cancel key reading when 'execute' triggered via a server request (#4653)
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Generate Sponsors README / deploy (push) Has been cancelled
Fix #4524
Close #4648
2026-01-09 00:29:40 +09:00
Marcel Meyer 14b5e1d88c Replace utils Min, Max with builtin min, max 2025-12-23 09:14:33 +09:00
Massimo Mund 148b0a94cd tui/light: consume full 7-byte CSI sequences to prevent leftover printing (#4528)
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
- Fix parsing in escSequence so 7-byte CSI forms (e.g. ESC [ 5 ; 10 ~) set *sz = 7 and the entire sequence is consumed.
- Prevents trailing bytes (like 10~) from remaining in the input buffer and being printed as stray characters.
2025-09-23 23:33:41 +09:00
Massimo Mund 9ed971cc90 Add keybindings for CTRL, ALT, SHIFT + UP, DOWN, RIGHT, LEFT, HOME, END, BACKSPACE, DELETE & more (#3996)
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
* Added tests for `LightRenderer`

* Added common SHIFT, ALT and ALT+SHIFT key sequences

* Added common CTRL key sequences

* Added common CTRL+ALT, CTRL+SHIFT, CTRL+ALT+SHIFT key sequences

* Added proper xterm META modifier handling

according to https://github.com/joejulian/xterm/blob/defc6dd5684a12dc8e56cb6973ef973e7a32caa3/input.c#L357-L375

* Fix `ctrl-backspace` and `ctrl-alt-backspace`

* Fix broken tcell tests on windows by swallowing Resize events

* Added tests for  FullscreenRenderer

* Removed own fork of tcell and updated tcell to 2.9.0

tcell 2.9.0 is needed for `Ctrl-Alt-*` and `Ctrl-Alt-Shift-*` shortcuts in Windows

* Replace conditional checks with switch statements to improve readability

* Replace long conditionals with constant slices to improve readability

* Bind `ctrl-bspace` (`ctrl-h`) to `backward-delete-char` by default

Since we now distinguish between Backspace and Ctrl-Backspace, Ctrl-Backspace should trigger the same action as Backspace by default. In that way nothing changes for the user but you can bind other actions to Ctrl-Backspace when desired.
2025-09-05 14:56:51 +09:00
Junegunn Choi 3b68dcdd81 Add footer
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Generate Sponsors README / deploy (push) Has been cancelled
Options:
  --footer=STR             String to print as footer
  --footer-border[=STYLE]  Draw border around the footer section
                           [rounded|sharp|bold|block|thinblock|double|horizontal|vertical|
                            top|bottom|left|right|line|none] (default: line)
  --footer-label=LABEL     Label to print on the footer border
  --footer-label-pos=COL   Position of the footer label
                           [POSITIVE_INTEGER: columns from left|
                            NEGATIVE_INTEGER: columns from right][:bottom]
                           (default: 0 or center)

The default border type for footer is 'line', which draws a single
separator between the footer and the list. It changes its position
depending on `--layout`, so you don't have to manually switch between
'top' and 'bottom'

The 'line' style is now supported by other border types as well.
`--list-border` is the only exception.
2025-06-10 23:02:23 +09:00
Junegunn Choi 1d761684c5 Add --tty-default=/dev/tty and --no-tty-default option (#4352)
Fix #4242.

Use --no-tty-default, if you want fzf to perform a TTY look-up instead of defaulting to /dev/tty.
2025-04-20 11:24:50 +09:00
Junegunn Choi 93cb3758b5 0.61.1
CodeQL / Analyze (go) (push) Has been cancelled
Test fzf on Linux / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2025-04-06 13:09:59 +09:00
Junegunn Choi d22e75dcdd Disable bracketed paste mode on exit
Related: #4338
2025-04-06 12:51:36 +09:00
Junegunn Choi 29cf28d845 Suppress 'change' event during bracketed paste mode
CodeQL / Analyze (go) (push) Waiting to run
Test fzf on Linux / build (push) Waiting to run
Test fzf on macOS / build (push) Waiting to run
Generate Sponsors README / deploy (push) Has been cancelled
Close #4316
2025-03-22 09:17:18 +09:00
Junegunn Choi 8916cbc6ab [windows] Prevent fzf from consuming user input while paused
CodeQL / Analyze (go) (push) Waiting to run
Test fzf on Linux / build (push) Waiting to run
Test fzf on macOS / build (push) Waiting to run
This partly fixes #4260.

fzf still can consume the first key stroke.
2025-03-03 14:04:16 +09:00
Junegunn Choi 1eafc4e5d9 Ignore NULL byte before CSI 6N response
CodeQL / Analyze (go) (push) Waiting to run
Test fzf on Linux / build (push) Waiting to run
Test fzf on macOS / build (push) Waiting to run
Close #2455
2025-02-16 21:18:01 +09:00
Junegunn Choi 378137d34a Simplify code
CodeQL / Analyze (go) (push) Waiting to run
Test fzf on Linux / build (push) Waiting to run
Test fzf on macOS / build (push) Waiting to run
2025-02-11 23:43:43 +09:00
Junegunn Choi 66ca16f836 Truncate wrap signs in extremely narrow preview window 2025-02-11 23:41:54 +09:00
Junegunn Choi 19ef8891e3 Print --wrap-sign in preview window
Close #4233
2025-02-11 00:01:50 +09:00
Junegunn Choi e84afe196a Add {show,hide,toggle}-input and expose $FZF_INPUT_STATE 2025-02-01 17:03:59 +09:00
Junegunn Choi 6c0ca4a64a Add --no-input to hide the input section (#4210)
CodeQL / Analyze (go) (push) Has been cancelled
Test fzf on Linux / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Close #2890
Close #1396
 
You can't type in queries in this mode, and the only way to trigger an
fzf search is to use `search(...)` action.

  # Click header to trigger search
  fzf --header '[src] [test]' --no-input --layout reverse \
      --header-border bottom --input-border \
      --bind 'click-header:transform-search:echo ${FZF_CLICK_HEADER_WORD:1:-1}'
2025-01-30 00:50:46 +09:00
Junegunn Choi e91f10ab16 Enhance click-header event
* Expose the name of the mouse action as $FZF_KEY
* Trigger click-header on mouse up
* Enhanced clickable header for `kill` completion
2025-01-27 01:10:08 +09:00
Junegunn Choi 04017c25bb Add 'bell' action to ring the terminal bell
CodeQL / Analyze (go) (push) Waiting to run
Test fzf on Linux / build (push) Waiting to run
Test fzf on macOS / build (push) Waiting to run
2025-01-25 11:22:32 +09:00
Junegunn Choi a4db8bd7b5 Make 'current-fg' inherit from 'fg' to simplify configuration
CodeQL / Analyze (go) (push) Waiting to run
Test fzf on Linux / build (push) Waiting to run
Test fzf on macOS / build (push) Waiting to run
If you do not want 'current-fg' to inherit attributes of 'fg', prefix it
with 'regular:' to reset them.

  # italic and underline
  fzf --color fg:italic,current-fg:underline

  # only underline
  fzf --color fg:italic,current-fg:regular:underline
2025-01-20 01:02:58 +09:00
Junegunn Choi a5beb08ed7 Border around the header section
Close #4159
2025-01-05 23:02:52 +09:00
Junegunn Choi ee3916be17 Border around the input section (prompt + info)
Close #4154
2025-01-02 16:25:00 +09:00
Junegunn Choi 9a2b7f559c Add --list-border for additional border around the list section
Close #4148
2024-12-31 17:05:14 +09:00
Junegunn Choi 805efc5bf1 Remove unused interface 2024-12-14 22:31:39 +09:00
Junegunn Choi e182d3db7a Fix line wrap toggle when switching between screens
Fix #4099
2024-12-02 22:25:23 +09:00
Junegunn Choi bacc8609ee Fix characters from previous preview not being cleared
Fix #4075
2024-11-03 15:07:17 +09:00
Junegunn Choi 387c6ef664 Support hyperlinks (OSC 8) in the main window
CodeQL / Analyze (go) (push) Has been cancelled
Test fzf on Linux / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Generate Sponsors README / deploy (push) Has been cancelled
Close #2557
2024-08-14 23:04:05 +09:00
Junegunn Choi d90a969c00 Add support for hyperlinks in preview window
CodeQL / Analyze (go) (push) Waiting to run
Test fzf on Linux / build (push) Waiting to run
Test fzf on macOS / build (push) Waiting to run
Close #2165
2024-08-14 08:51:34 +09:00
Junegunn Choi 2faffbd1b7 Fill background color in padding area
fzf --color bg:blue --border --padding 1,2
2024-07-01 21:39:09 +09:00
Junegunn Choi 3dee8778d0 execute: Open separate handles to /dev/tty (in, out, err)
# This will no longer cause 'Vim: Warning: Output is not to a terminal'
  fzf --bind 'enter:execute:vim {}' > /tmp/foo
2024-05-23 21:11:12 +09:00