Skip to main content

ExCommandSpec

Struct ExCommandSpec 

Source
pub struct ExCommandSpec {
    pub latency_class: LatencyClass,
    pub accepts_bang: bool,
    pub accepts_range: bool,
    pub parse_args: Arc<dyn Fn(&str, bool) -> GrammarResult<Args> + Send + Sync>,
    pub apply: Arc<dyn Fn(&ExCommandContext) -> GrammarResult<Effect> + Send + Sync>,
    pub args_schema: Vec<ArgSpec>,
    pub surface_form: SurfaceForm,
}
Expand description

A registered ex-command: how the : line parses it and what it returns.

Registered through CommandRegistry::register_ex_command (or CommandRegistry::register_plugin_ex_command). The : front-end (in lattice-host) resolves the typed word to a registry name, rejects a ! the spec does not accept, calls Self::parse_args on the rest of the line, and dispatches the resulting invocation. apply receives an ExCommandContext and returns an Effect — it never performs I/O itself.

§Examples

use std::sync::Arc;
use lattice_core::{BufferId, Document};
use lattice_grammar::{
    Args, CancellationToken, CommandInvocation, CommandRegistry, EchoLevel, Effect,
    ExCommandSpec, LatencyClass, SurfaceForm, execute,
};
use lattice_protocol::position::Position;

let mut registry = CommandRegistry::new();
let id = registry.register_ex_command(
    "ex:greet",
    "Echo a greeting (`:greet [name]`).",
    ExCommandSpec {
        latency_class: LatencyClass::Reflex,
        accepts_bang: false,
        accepts_range: false,
        parse_args: Arc::new(|rest, _bang| {
            Ok(match rest.trim() {
                "" => Args::None,
                name => Args::String(name.to_string()),
            })
        }),
        apply: Arc::new(|ctx| {
            let who = match &ctx.args {
                Args::String(s) => s.as_str(),
                _ => "world",
            };
            Ok(Effect::Echo { level: EchoLevel::Info, text: format!("hello, {who}") })
        }),
        args_schema: vec![],
        surface_form: SurfaceForm::Keyword,
    },
);

let spec = registry.ex_command_spec(id.0).unwrap();
let args = (spec.parse_args)(" lattice", false).unwrap();
let mut doc = Document::from_text("");
let effect = execute(
    &registry,
    &mut doc,
    BufferId(0),
    Position::ZERO,
    CommandInvocation::of(id.0).with_args(args),
    &CancellationToken::never(),
)
.unwrap();
assert!(matches!(effect, Effect::Echo { text, .. } if text == "hello, lattice"));

Fields§

§latency_class: LatencyClass

Latency class declaration (DESIGN.md §5.2.5). Most ex-commands stay crate::command::LatencyClass::Reflex (the default) – they’re cheap state mutations. File I/O (:write, :edit) and help-buffer builders (:describe-*, :apropos, :keymap) declare crate::command::LatencyClass::Display so future cancellation / deadline machinery treats them with the right budget.

§accepts_bang: bool

Whether the parser should accept a trailing ! after the command word. If false, :cmd! parses as an unknown command.

§accepts_range: bool

Whether the parser should accept an ex-style line range (1,5cmd, 'a,'bcmd, …). v1 only honours Whole and CurrentLine; this flag is the migration knob for richer range parsing.

§parse_args: Arc<dyn Fn(&str, bool) -> GrammarResult<Args> + Send + Sync>

Parses everything after the command word (and !) into Args. Receives the bang bit so ! can change the grammar.

§apply: Arc<dyn Fn(&ExCommandContext) -> GrammarResult<Effect> + Send + Sync>

The evaluator: packages the invocation into an Effect.

§args_schema: Vec<ArgSpec>

Per-positional-argument metadata (DESIGN.md §B.1). Drives palette forms, missing-arg prompts, completion, validation, and :describe-command output. Empty for commands taking no structured args (:q, :noh).

§surface_form: SurfaceForm

User-facing surface form. Drives whether completion / palette list this command. Defaults to SurfaceForm::Keyword.

Trait Implementations§

Source§

impl Clone for ExCommandSpec

Source§

fn clone(&self) -> ExCommandSpec

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ExCommandSpec

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more