tmux-fuzzy-motion
v0.0.9
Published
Fuzzy hint motion for tmux copy-mode
Readme
tmux-fuzzy-motion
tmux-fuzzy-motion is a CLI for quick cursor jumps in tmux panes.
It scans the current viewport, extracts jump targets, filters them with fuzzy
search, and lets you jump with uppercase hints. Roman queries can also match
Japanese text through Migemo.
Features
- Works inside
tmux copy-mode startcan also be launched outside copy-mode and enters copy-mode automaticallystart --scope allcan target every visible pane in the current window- Extracts URLs, paths, filenames, symbols, and general words from the current viewport
- Supports fuzzy matching with
fzf - Supports Migemo matching for alphabetic queries via
jsmigemo - Preserves pane colors while drawing the overlay
- Reuses an external daemon process so matcher and Migemo startup stay warm
- Uses single-key uppercase hints for fast selection
- Opens the UI in a tmux popup instead of creating a persistent scratch window
Requirements
- Node.js 22 or later
- tmux 3.2 or later
Install
npm install -g tmux-fuzzy-motion@latestIf you prefer pnpm:
pnpm add -g tmux-fuzzy-motion@latestVerify the installation:
tmux-fuzzy-motion doctorYou can also run it without a global install:
npx tmux-fuzzy-motion@latest doctortmux Configuration
Add these bindings to your tmux.conf:
bind-key -T copy-mode-vi s run-shell 'tmux-fuzzy-motion start #{pane_id} #{client_tty}'
bind-key -T copy-mode s run-shell 'tmux-fuzzy-motion start #{pane_id} #{client_tty}'If you also want to launch it outside copy-mode, add a binding in the root table as well:
bind-key s run-shell 'tmux-fuzzy-motion start #{pane_id} #{client_tty}'If you want to search across every visible pane in the current window, add a
binding with --scope all.
bind-key S run-shell 'tmux-fuzzy-motion start --scope all #{pane_id} #{client_tty}'If you want tmux to open the popup directly without going through the start
subcommand, use this instead:
bind-key -T copy-mode-vi s run-shell -C "display-popup -E -B -x '##{popup_pane_left}' -y '##{popup_pane_top}' -w '#{pane_width}' -h '#{pane_height}' 'tmux-fuzzy-motion popup-live #{pane_id}'"
bind-key -T copy-mode s run-shell -C "display-popup -E -B -x '##{popup_pane_left}' -y '##{popup_pane_top}' -w '#{pane_width}' -h '#{pane_height}' 'tmux-fuzzy-motion popup-live #{pane_id}'"[!NOTE] If you see an error like
'tmux-fuzzy-motion start %25 /dev/ttys000' returned 127at step 2 below, you need to addtmux-fuzzy-motionto the PATH in the run-shell environment:set-environment -g PATH "/path/to/node/bin:$PATH"
Reload tmux after editing the config:
tmux source-file ~/.tmux.confUsage
- Press the key bound to
tmux-fuzzy-motion start. --scope current(the default) targets only the current pane and enters copy-mode first if needed.--scope alltargets every visible pane in the current window by composing them into a single popup.- Type a query in lowercase or symbols.
- Narrow the candidates with fuzzy matching.
- For alphabetic queries, Migemo also expands roman input to Japanese matches.
- Press an uppercase hint to jump immediately.
- In
--scope all, the selected pane becomes active and enters copy-mode if needed before the cursor moves. - Press
EscorCtrl-[to cancel.
Input Keys
A-Z: select a visible hint immediatelyEnter: select the first visible matchEsc,Ctrl-[,Ctrl-g: cancelBackspace,Ctrl-h: delete one characterCtrl-w: delete the previous wordCtrl-u: clear the whole query
Commands
tmux-fuzzy-motion start [--scope current|all] <pane-id> <client-tty>
tmux-fuzzy-motion popup-live <pane-id>
tmux-fuzzy-motion doctorpopup and daemon are internal subcommands. popup-live is intended for
direct display-popup bindings.
--scope:
current: target only the current pane. This is the default.all: target every visible pane in the current window.
Doctor
Use doctor to verify the local environment:
tmux-fuzzy-motion doctorIt checks:
- Node.js version
- tmux version
- Migemo dictionary loading
Development
For local development from this repository:
pnpm installYou will need pnpm for the development workflow above.
Build once:
pnpm buildWatch mode:
pnpm run devRun the full local check:
pnpm checkLimitations
- Targets are limited to the current viewport of each pane
--scope alltargets only visible panes in the current window- Zoomed windows with
--scope allonly target the pane that is visible - Query input is ASCII-oriented
- Exact behavior for combining characters is not fully guaranteed
- Requires
display-popup, so tmux 3.2 or later is mandatory - The query is drawn on the popup's bottom row, aligned to the right edge
