junegunn/fzf
Key bindings and actions
--bind is the binding between an event (key, mouse, named) and a chained list of actions. The action set is large enough to make fzf programmable as a small TUI toolkit.
Anatomy of a bind
--bind '<event>:<action>[+<action>]*[,<event>:...]*'Examples:
--bind 'ctrl-r:reload(rg --files)'
--bind 'enter:become(vim {})'
--bind 'change:first'
--bind 'ctrl-p:change-preview-window(right|down|hidden)'
--bind 'tab:toggle+down'
--bind 'start:reload(fd .)+unbind(ctrl-c)'Multiple binds are separated by commas; multiple actions for one event are joined with +.
Events
| Class | Examples | Notes |
|---|---|---|
| Key chord | ctrl-a, alt-up, f5, enter, esc, tab, space |
Modifiers: ctrl, alt, shift. |
| Mouse | click-header, right-click, double-click, scroll-up, scroll-down, preview-mouse-* |
--no-mouse disables. |
| Named | start, load, change, result, focus, one, zero, multi, jump, jump-cancel, backward-eof, bracketed-paste-begin/end |
Fired by fzf's lifecycle, not the user. |
start fires before any input has been read; load after the first read finishes; change when the query changes; result when the match list is updated; focus when the cursor moves to a new item; one/zero when the match count drops to 1 or 0.
Actions
Action types are enumerated in src/options.go and stringified by the generated src/actiontype_string.go (200+ entries). They fall into a few families:
Navigation
up, down, page-up, page-down, half-page-up, half-page-down, first, last, top, pos(N), track, track-current, untrack-current.
Editing
backward-char, forward-char, kill-line, kill-word, backward-kill-line, clear-query, clear-screen, delete-char, delete-char/eof, beginning-of-line, end-of-line, unix-line-discipline, yank, put.
Selection
accept, accept-non-empty, accept-or-print-query, abort, cancel, close, select, select-all, deselect, deselect-all, toggle, toggle-all, toggle-down, toggle-up, clear-selection.
Layout
change-preview-window(...), change-prompt(...), change-pointer(...), change-header(...), change-header-lines(N), change-footer(...), change-input-label(...), change-list-label(...), change-border-label(...), change-preview-label(...), change-ghost(...), toggle-preview, toggle-preview-wrap, toggle-header, hide-header, hide-input, show-input, toggle-input, toggle-multi-line.
Search & input
change-query(...), change-multi, change-nth(...), change-with-nth(...), enable-search, disable-search, toggle-search, toggle-sort, toggle-track, toggle-track-current.
Run external commands
execute(...), execute-silent(...), become(...), reload(...), reload-sync(...), print(...), put(...).
Transform-* actions
transform-prompt(...), transform-query(...), transform-header(...), transform-footer(...), transform-search(...), transform-preview-window(...), transform-border-label(...), transform-list-label(...), transform-input-label(...), transform-preview-label(...), transform-ghost(...), transform-pointer(...), transform(...) (universal — body emits any number of fzf actions).
Bind manipulation
bind(...), unbind(...), rebind(...), toggle-bind(...).
Process exit
accept (exit code 0), abort (exit code ExitInterrupt), become(...) (exit code ExitBecome, then re-exec target).
The full list lives in src/actiontype_string.go; the man page (man/man1/fzf.1, "AVAILABLE ACTIONS") is the canonical user-facing reference.
Action chaining
Actions in a chain run in order. If one of them is accept, abort, or become, fzf finishes the rest of the chain that doesn't require a still-running UI, then exits.
--bind 'enter:print(picked: {})+accept'prints the line, then accepts.
Argument syntax
Most argument-taking actions accept either of:
action(arg)
action:argInside the parentheses, ( and ) must balance (escape with \(, \)). Inside :arg, the argument continues until the next bind separator (comma) or the end of the bind string.
transform-* family
transform-X runs a shell command, captures stdout, and uses it as the new value of X. The command can use the same placeholder language as --preview:
--bind 'change:transform-prompt(echo "{q}> ")'Every keystroke the prompt becomes the current query plus > .
The universal transform(...) is more powerful: its stdout is interpreted as a list of fzf actions and executed. This is how scripts can dynamically react to the current state.
become(...) and ExitBecome
become(<cmd>) writes <cmd> + env to a .become temp file, exits with ExitBecome (a special exit code defined in src/constants.go), and lets the wrapper layer (or main.go) re-exec the target. The result: fzf --bind 'enter:become(vim {})' leaves the user inside vim after fzf has cleaned up the screen.
The implementation lives in src/proxy.go (ExitBecome branch in runProxy) and src/util/util.go (Executor.Become, which calls syscall.Exec on POSIX).
Where it lives
| Concern | File |
|---|---|
| Bind / action / placeholder grammar | src/options.go |
| Action enum | src/options.go + generated src/actiontype_string.go |
| Action dispatch | src/terminal.go |
| Placeholder substitution | src/terminal.go |
| Become / Exit codes | src/constants.go, src/proxy.go, src/util/util.go |
| HTTP-driven action injection | src/server.go |
| Tests | src/options_test.go, test/test_core.rb, test/test_exec.rb, test/test_server.rb |
See systems/options and systems/terminal-ui for implementation details.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.