A Nushell picker that hosts input list inside a Zellij floating pane.
Pipe nushell structured data in, get the user's selection back as nushell structured data — without ever scrolling the host pane.
input list is a great fuzzy picker, but running it in the current pane churns through scrollback and disrupts the surrounding command. picky spawns a transient floating pane just for the picker, captures the selection, and returns the value to the caller as if input list had been called in-place.
Bonus: the --display flag is fully supported — including closures — even though the picker runs in a separate process.
| Tool | Purpose |
|---|---|
| Nushell | Host shell |
| Zellij | Provides the floating pane |
Must be invoked from inside a zellij session ($env.ZELLIJ set).
# clone this repository into one of your NU_LIB_DIRS
let dest = [($env.NU_LIB_DIRS | first) picky] | path join
git clone git@github.com:lassoColombo/picky.git $dest
# use the module
use picky
picky --helpuse picky
# Plain pick
[apple banana cherry] | picky
# Fuzzy pick over a table, displaying a single column
ls | picky --fuzzy --display name
# Closure-based display
ls | picky -f -d {|r| $"($r.name) — ($r.size)"}
# Multi-select; returns a list
[a b c d] | picky --multi --fuzzy
# Index mode; returns the picked indices instead of the values
[red green blue] | picky --index
# Compose into pipelines
ls | picky -f -d name | get name | save selected.txt| Mode | Returns |
|---|---|
| Single (default) | the picked item |
--multi |
a list of picked items |
--index |
the picked index (or list of indices with --multi) |
| User cancels (Esc / Ctrl-C / q) | null |
All flags of input list are forwarded verbatim:
| Flag | Short | Type | Description |
|---|---|---|---|
--multi |
-m |
switch | Allow multiple selections |
--fuzzy |
-f |
switch | Enable fuzzy search |
--index |
-i |
switch | Return indices instead of values |
--no-footer |
-n |
switch | Hide the footer |
--no-separator |
switch | Hide the search-box separator | |
--case-sensitive |
-s |
oneof<bool, string> |
true, false, or 'smart' |
--display |
-d |
oneof<cell-path, closure> |
Field path or closure for display text |
--no-table |
-t |
switch | Disable table rendering |
--per-column |
-c |
switch | Match each column independently |
The positional prompt is also forwarded.
See input list for full semantics.
There is no shared stdin/stdout between the caller and a zellij floating pane, so picky ferries data over .nuon temp files:
- Pipeline input is serialized to a temp
.nuonfile. - A small runner script is generated. Switches and value-flags are stitched in as code;
--displayis inlined as a cell-path (viato nuon) or as a closure (viaview source). zellij action new-pane --floating --close-on-exit -b -- nu <script>opens the pane and blocks the caller until it closes.- The runner writes the selection to a second
.nuonfile (or leaves it asnullwhen the user cancels). - The caller reads the result and cleans up all temp files in a
finallyblock.
- Closures that capture outer-scope variables won't work as
--display. The closure source is shipped viaview source, which emits the literal source only — captured bindings are not re-bound in the child process. - No preview pane.
input listhas no--previewequivalent. Use a--displayclosure to fold any extra context into the line itself. - Zellij-only. Outside a zellij session,
pickyerrors out.
use nutest
nutest run-tests --path .The test suite (test_picky.nu) exercises the script-generation helpers and round-trips the generated runner through a stubbed input list to verify it parses as valid Nushell.