Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

nx.picker

nx.picker.source(spec)

nx.picker.source { name, items = function(ctx), dynamic, confirm, preview }: register a source. items(ctx) streams candidates: it calls ctx.push(item) per result (an item is a table with a text display field, plus any data confirm or the preview needs — e.g. path / row / col) and signals completion by returning — a synchronous source just returns when its loop ends, an asynchronous one is wrapped in nx.async and returns the promise (the engine awaits it; nx is promise-only, so there is no done callback). A streaming source consumes a nx.run_stream with nx.await_each, and reaps its job on close via ctx.on_cancel. dynamic = true re-runs items on every prompt edit (live grep — the matcher is bypassed), reading the live prompt from ctx.query and the working directory from ctx.cwd; the default is a static source matched locally in Rust as you type. confirm(item) acts on the chosen item. Optional preview adds a side pane for the highlighted item: "file" shows the head of item.path, "location" shows item.path positioned at item.row / item.col (1-based). Omitted ⇒ no preview pane; per-open overridable via nx.picker.open(name, { preview = … }). Optional width / height fix the box size — a cell count (number) or a CSS-style viewport fraction string (“80vw” / “60vh” / “50%”); omitted ⇒ the default (~80vw x 60vh). The picker is never content-sized. Optional align (“top-left”…“center”…“bottom-right”, default centered) + margin (a gap from the editor edges: a number — the vertical gap, horizontal sides 2x to look even — or {vertical, horizontal} / {top, right, bottom, left} / {top=, …}) place the box like a float. Optional prompt_pos = “top” (default) or “bottom” places the input above or below the results list.

For a dynamic source (which spawns per query), debounce (ms) sets the trailing delay before a query edit re-runs the source — so a fast typist spawns one search per pause, not one per keystroke, and a new keystroke cancels the in-flight search. It defaults to the global nx.picker.debounce (250), and is also overridable per open via nx.picker.open(name, { debounce = N }); 0 disables it. While that search runs, the PREVIOUS results stay on screen (the list never flashes empty); they are swapped out only when the new search’s first result arrives, or cleared if it matched nothing. The widget windows its rendering and matches incrementally, so a source can stream 100k+ candidates and stay fast; max_results (default 100000) is only a runaway-source safety bound.

resumable = false opts the source out of nx.picker.resume() (<leader>fr): opening it never overwrites the resume slot, so a transient internal picker (the cmdline file completer) can’t shadow the last user-facing one. Defaults to true.

Defined in picker.lua.

nx.picker.open(name, opts)

nx.picker.open(name[, opts]): open the picker for the registered source name. Each opts field overrides the matching field on the source (which in turn overrides the picker default):

  • width / height — a FIXED box size: a cell count (e.g. 100) or a CSS-style viewport fraction string (“80vw” / “60vh” / “50%”). The picker is never content-sized (a content-hugging box looks ragged).
  • align + margin — placement, like a float (see nx.picker.source).
  • preview — “file” / “location” / nil (no pane).
  • prompt_pos — “top” (default) / “bottom”.
  • query — initial prompt text: the picker opens already filtered against it (the gen-0 run uses it instead of “”), caret at its end. Default “”.
  • title — a title centered on the box’s top border (e.g. “Find Files”); nil ⇒ no title. The shipped sources set their own (“Find Files”/“Live Grep”/…).
  • multiselect — whether <Tab> marks rows for a batch action (default true); false is a single-choice picker (no marking).
  • debounce — ms before a dynamic source re-runs on a query edit; 0 off.
  • layer — where a confirmed item opens: “main” crosses back to the main editor area first (so a file picked while focused in a dock lands in the editor, not the sidebar), “active” opens in the focused layer. Defaults to “active”; the shipped files/live_grep sources set “main”, buffers stays “active”.

Defined in picker.lua.

nx.picker.resume()

nx.picker.resume(): reopen the most-recently-closed picker (telescope’s resume), restored to exactly where the user left off — the displayed rows, prompt text, highlighted row, and multi-select marks. The server replays a frozen snapshot it captured at close (bounded to a window around the cursor), so a live-grep picker comes back with its actual previous results, not a fresh (differently-ordered) search. Re-installs nx._picker so confirm works and a later query edit re-runs the source. No-op (a gentle notice) before any resumable picker has closed.

Defined in picker.lua.

nx.picker.edit(item, mode, layer)

nx.picker.edit(item): the common confirm action — open item.path, and if the item carries a 1-based row (and optional 1-based col, as live_grep / LSP location items do), jump the cursor there.

A located jump (item.row set) goes through the nx._jump_to bridge, NOT :edit: a jump must navigate, never reload. :edit-ing the location would (a) error with E37 when the target is the current modified buffer (the LSP hands back an absolute path, but the open buffer may be relatively named) and (b) strand a duplicate buffer when that absolute path doesn’t string-match the relative one. nx._jump_to reuses the open buffer cwd-aware and skips the modified guard, so selecting a symbol in the file you’re editing just moves the cursor. A location-less item (the files source) is a plain open instead. mode is the confirm gesture: “tab”/“split”/“vsplit” (<C-t>/<C-x>/<C-v>) open in a NEW tab / split regardless of 'switchbuf' (an explicit gesture); “current” (or nil) honors 'switchbuf'.

layer is the confirm target the picker resolved (“main”/“active”), forwarded to confirm and on to here. “main” crosses back to the main editor layer before opening, so a file picked while focused in a dock lands in the editor rather than the sidebar; “active” (or nil) opens in the focused layer.

Defined in picker.lua.