Skip to content
Eric Kochen edited this page May 28, 2026 · 4 revisions

Jump

Jump is purple's universal fuzzy search bar. Press : from any screen to find any host, tunnel, container, snippet or action across your entire SSH config in one keystroke. Recent picks persist across sessions and lead the empty-state list. Field prefixes scope the query to a single SSH directive.

Comparable to Linear's Cmd+K or Raycast, but in your terminal.

What Jump searches

Five sources, one ranked list:

Source What gets searched
Hosts Alias, hostname, tags, provider, SSH User, IdentityFile, ProxyJump, Vault SSH role
Tunnels Host alias, bind port, destination
Containers Container name, image, host alias (cached, no live SSH on open)
Snippets Snippet name, command preview
Actions All 50 keyboard-reachable actions across the TUI, with hidden aliases

Results are ranked with nucleo (the Helix editor's fuzzy matcher). Sections appear in a fixed order (Hosts, Tunnels, Containers, Snippets, Actions) so muscle memory survives.

Why it matters

A typical purple user has 50 to 500 hosts spread across multiple cloud providers, plus dozens of named tunnels, containers and snippets. Three keys (/, : and the navigation tabs) used to map to three different mental models. Jump collapses that into one bar with one trigger.

Concrete example. You configured User eric for many servers. The hostname doesn't contain "eric" anywhere. Type eric in Jump and every server you log in as eric appears with a dim via eric hint next to it.

Field-prefix syntax

Scope a query to a single SSH directive. The unscoped fuzzy search remains the default; prefixes are opt-in precision.

Prefix Searches Example
user: SSH User directive user:deploy finds every host configured for the deploy user
host: Hostname only (skips alias) host:10.0 finds every host with 10.0 in the hostname
proxy: ProxyJump chains proxy:bastion-eu finds every host that bounces through bastion-eu
vault: Vault SSH role vault:prod-admin finds every host signed with the prod-admin role
tag: User tags only tag:web finds every host tagged "web"

Field-prefix syntax mirrors the existing tag: precedent in purple's host search.

Match-source hints

When Jump matches on a field that is not part of the visible row, a dim hint appears inline so the match makes sense. Examples:

  • Match on User: fast1 eric 128.199.60.111 via eric
  • Match on ProxyJump: web-01 web.prod 1.2.3.4 via bastion-eu
  • Match on vault_ssh: db-01 db.internal 10.0.0.5 vault: prod-admin

Without these hints, a query like eric would surface hosts the user could not visually explain.

Empty state and Recent

Opening Jump with an empty query shows two sections:

  1. Recent: your last picks (any kind), persisted to ~/.purple/recents.json. Most recent first. Capped at 50 entries.
  2. Actions: top 6 actions sampled across categories so the first impression covers Hosts, Tunnels, Containers, Files, Vault, Keys. Header reads Actions 6 of N where N is the live total. Scroll past the cap by typing or pressing the down arrow.

The first row is not selected by default. The eye lands on the input field. Pressing the down arrow reveals the cursor on row 0 and continues from there.

Keyboard

Key Action
: Open Jump from the Hosts, Tunnels, Containers or Keys tab
Type any character Filter
/ Move selection. First press reveals the cursor on row 0
Tab Jump to the next section header
Enter Open the selected hit. Hosts switch tabs and connect, tunnels jump to the row in the Tunnels tab, containers switch to the Containers tab and place the cursor on the matching row, snippets open the snippet picker, actions execute
Backspace on empty query Close Jump
Esc Close Jump

How dispatch works

Selecting a hit and pressing Enter does different things depending on the kind:

Kind Dispatch
Host Switch to Hosts tab, select the host, trigger the connect flow
Tunnel Switch to Tunnels tab, place the cursor on the matching tunnel row, then fire Enter so the tunnel starts or stops in the same gesture
Container Switch to the Containers tab, place the cursor on the matching container row, then fire Enter so the shell opens in the same gesture. Falls back to the host divider when the group is folded (no auto-Enter on the divider), then to the first visible row when the cache no longer carries the container
Snippet Open the Snippet picker on the currently selected host (or warn if no host is selected)
Action Synthesise the action's keypress (including modifiers like Ctrl-a or Ctrl-k) for the right handler, switching tab first when the action's target is on a different tab

The same action can exist on multiple tabs with different meanings (e.g. a is Hosts: Add host on Hosts, Tunnels: Add tunnel on Tunnels and Containers: Add host on Containers). Jump shows them all. A small mode-match boost surfaces the contextually-relevant one when you type a query that matches several of them, so typing sort on the Tunnels tab prefers Tunnels: Sort over Hosts: Sort.

Privacy

Jump's recent log lives at ~/.purple/recents.json. It contains aliases, snippet names and tunnel ports. It does not contain hostnames, IP addresses, IdentityFile paths or any credential. The file is written via the same atomic-write helper as the rest of purple's persistent state and is gated behind demo mode (no writes when --demo is active). Schema is versioned for forward compatibility.

Comparable products

Product Where it runs Cross-source search
Linear Cmd+K Web Issues, projects, members, commands
Raycast macOS Apps, snippets, scripts, extensions
Spotlight macOS Files, apps, web
Jump (purple) Terminal TUI Hosts, tunnels, containers, snippets, actions
fzf Terminal Single source per invocation
Telescope (Neovim) Neovim Single source per picker

The closest TUI precedent for one bar over many sources is Zellij's session manager, but it doesn't index host/SSH-config data the way Jump does.

FAQ

Does Jump connect over SSH when I open it? No. Containers are searched against the local cache only. Hosts and tunnels read from the parsed SSH config in memory. Opening Jump triggers no network activity.

Where do recents go? ~/.purple/recents.json, atomic write, max 50 entries. Demo mode skips persistence entirely.

Can I disable Recent? The file is harmless to delete (purple regenerates an empty one on next open). A preference flag is not currently exposed.

Does Jump work from inside a form (e.g. while editing a host)? No. : is a literal character inside form fields. Jump opens from the Hosts and Tunnels overview screens.

How is Jump different from purple's / filter? / filters the visible list of the current tab in place (no jump). Jump opens an overlay, searches across all sources, and switches tab as needed. Two complementary keys.

Why six actions in the empty state, not all 50? A wall of 50 rows competes with the input field for attention. The top 6 sample one action per priority category (Hosts, Tunnels, Containers, Files, Vault, Keys). The full list is one keystroke away. The header reads Actions 6 of 50 so the truncation is explicit.

What's the score floor on actions? Action-source hits need to clear a higher fuzzy-match score (~30 in nucleo's scale) than data-source hits. Without this, a query like eric would drag in Containers: List containers because e/r/i/c happen to scatter across the label without semantic intent.

See also

Clone this wiki locally