pub struct PickerSourceSpec {
pub id: Cow<'static, str>,
pub doc: Cow<'static, str>,
pub args_schema: Vec<ArgSpec>,
pub args_hint: Cow<'static, str>,
pub live: bool,
pub create_label: Option<Cow<'static, str>>,
pub rooted: bool,
pub delete_command: Option<Cow<'static, str>>,
pub help_topic: Option<Cow<'static, str>>,
}Expand description
Static metadata describing one picker source.
id is the stable name the user types after :picker
(e.g. files, lsp-references). doc is one line shown
in :describe-picker and next to the id in cmdline
completion. args_schema describes positional args after
the source id — same ArgSpec machinery the rest of the
grammar uses, so :picker grep <pat> <Tab> completes
through the existing gen:* source plumbing.
Fields§
§id: Cow<'static, str>PL8.F: Cow<'static, str> — builtins pass zero-cost Cow::Borrowed
literals; a plugin source (crossing WIT) passes Cow::Owned that frees
on PickerRegistry::unregister, replacing the old Box::leak intern.
doc: Cow<'static, str>§args_schema: Vec<ArgSpec>§args_hint: Cow<'static, str>Parameter-hint line shown while the user is typing args
after the source id. Empty string = no hint (the
cmdline falls back to per-arg ArgSpec::doc).
live: boolTrue if this source re-executes its data fetch on every
(debounced) query change instead of returning a fixed
candidate set the picker fuzzy-filters. Live sources
own their own filtering – the grep binary IS the
filter – so the picker bypasses its built-in fuzzy
refilter for them. Sources opting in must also
implement PickerSourceGenerator::on_query_changed.
create_label: Option<Cow<'static, str>>OR.5: when set, the picker offers one synthetic create row whenever
the query is non-empty — the offer to make the thing the user was
looking for and did not find. %s in the label is replaced by the
query.
The row is pinned last and never ranked (see Picker::push_create_row),
and accepting it routes RoutingPayload::Create { query } back to this
source’s accept, which decides what creation means. The picker never
knows: org-roam mints a node, another source might make a file. None —
every source but roam’s — behaves exactly as before.
rooted: boolPP.2: this source’s results are scoped to a project / workspace root, so the picker prompt names the root it is operating on.
A declaration, not an inference. The host resolves a root for every
picker open (build_picker_context always fills workspace_root), so
it could show one everywhere — and a path on buffers, commands or
marks, whose results span every project you have open, is noise on a
surface that has one line to be read. Only the source knows whether the
root is part of what the list MEANS.
Set it when the answer to “would these results be different in another
project?” is yes: files, grep, every magit source (scoped to the
buffer’s repository). Leave it off when the list is global
(buffers, recent, projects), buffer-local (lines, outline) or
registry-wide (commands, snippets, colorscheme).
dir-pick deliberately declines it despite being path-shaped: its
QUERY is the directory it is listing, so the prompt already says where
it is and a root beside that would be a second, staler answer.
delete_command: Option<Cow<'static, str>>PD.1: <C-d> — the ex-command that REMOVES the selected row from
whatever backs this list. None (every source but projects today)
leaves <C-d> doing nothing at all.
The source owns the verb; the host owns only the key. <C-s> /
<C-v> / <C-t> are host concerns — the host knows how to open a
thing in a split without asking anyone. Deletion is not: only the
source knows that removing a row from projects means forgetting a
root, and that removing one from a future snippets would mean
something else entirely. Naming a command is how a source says so,
and it is the same routing its rows already take
(PickerAcceptOutcome::InvokeCommand), so a plugin declaring this
needs no new seam and no new capability.
The command is invoked with the selected row’s routing ARGUMENT — the
root, for a project row. A row whose routing carries no stable argument
gets a no-op rather than a command with an empty one; see
Editor::row_delete_argument for exactly which routings qualify.
Deleting is not destructive to the filesystem and must not be.
projects forgets a path; oil and the file tree are where deleting a
directory lives. A source whose delete verb touched disk would make
<C-d> mean two very different things depending on which picker had
focus, which is exactly the inconsistency this repo’s key rules exist
to prevent.
help_topic: Option<Cow<'static, str>>PH.1: the :help topic <C-h> opens while this source’s picker has
focus. None falls through to the picker-<id> convention and then to
the general picker page (see Editor::do_picker_help).
A declaration, so several sources can share one page — the magit
sources are one family with one set of keys, and a page per source
would be six copies of the same table. The convention is the peer a
plugin can meet without this field crossing WIT: register a topic
named picker-<id> through the help seam — the host namespaces it to
<plugin>.picker-<id> — and it is found through
PickerSourceGenerator::owner_plugin.
Implementations§
Source§impl PickerSourceSpec
impl PickerSourceSpec
Sourcepub fn no_args(
id: impl Into<Cow<'static, str>>,
doc: impl Into<Cow<'static, str>>,
) -> Self
pub fn no_args( id: impl Into<Cow<'static, str>>, doc: impl Into<Cow<'static, str>>, ) -> Self
Sugar for declaring a no-arg picker source (files,
recent, buffers, etc.).
Sourcepub fn with_help_topic(self, topic: impl Into<Cow<'static, str>>) -> Self
pub fn with_help_topic(self, topic: impl Into<Cow<'static, str>>) -> Self
Builder-style: PH.1’s help_topic — the page
<C-h> opens.
Sourcepub fn with_create_label(self, label: impl Into<Cow<'static, str>>) -> Self
pub fn with_create_label(self, label: impl Into<Cow<'static, str>>) -> Self
Builder-style: offer a create row whenever the query is non-empty.
%s in label is replaced by the query.
Sourcepub fn with_live(self, live: bool) -> Self
pub fn with_live(self, live: bool) -> Self
Builder-style: mark this source as live (:picker grep
today; future live LSP workspace-symbols, etc.). The
picker will bypass its fuzzy refilter for live sources
and the host will call
PickerSourceGenerator::on_query_changed on each
debounced keystroke.
Sourcepub fn with_rooted(self, rooted: bool) -> Self
pub fn with_rooted(self, rooted: bool) -> Self
Builder-style: PP.2’s rooted — the prompt names the
root these results are scoped to.
Sourcepub fn with_delete_command(self, command: impl Into<Cow<'static, str>>) -> Self
pub fn with_delete_command(self, command: impl Into<Cow<'static, str>>) -> Self
Builder-style: PD.1’s delete_command — the
ex-command <C-d> runs on the selected row.
Trait Implementations§
Source§impl Clone for PickerSourceSpec
impl Clone for PickerSourceSpec
Source§fn clone(&self) -> PickerSourceSpec
fn clone(&self) -> PickerSourceSpec
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more