Skip to main content

BufferStore

Trait BufferStore 

Source
pub trait BufferStore: Send + Sync {
    // Required methods
    fn find_by_name(&self, name: &str) -> Option<BufferId>;
    fn handle_for(&self, id: BufferId) -> Option<Arc<dyn Document>>;
    fn name_for(&self, id: BufferId) -> Option<String>;
    fn insert_document_buffer(
        &self,
        id: BufferId,
        kind: BufferKind,
        handle: Arc<dyn Document>,
        flags: BufferFlags,
        name: Option<String>,
    );

    // Provided methods
    fn path_for(&self, _id: BufferId) -> Option<PathBuf> { ... }
    fn contains_buffer(&self, id: BufferId) -> bool { ... }
}
Expand description

Host-implemented trait. The renderer crate provides an impl that wraps the App’s buffer registry + mode-activation state.

Methods take &self and must be safe to call from any thread (the impl is responsible for synchronisation).

Required Methods§

Source

fn find_by_name(&self, name: &str) -> Option<BufferId>

Look up the buffer id whose name matches exactly. Returns None when no buffer with that synthetic name is registered yet.

Source

fn handle_for(&self, id: BufferId) -> Option<Arc<dyn Document>>

Get a clone of the Arc<dyn Document> for id, suitable for holding across thread boundaries. M.0: the return type is the polymorphic shape so the same surface serves both regular-document handles and (M.1+) multibuffer handles uniformly. The handle is the only way for a mode-owned background task to write into the buffer (handle.apply_edit_batch(...)).

None when id is not a Document in the registry.

Source

fn name_for(&self, id: BufferId) -> Option<String>

Read the buffer’s synthetic name. None when the buffer is unnamed (the default for path-less scratch documents) or when id is not registered. B’.7: lets a mode derive its own identity from the buffer it’s attached to without the host having to seed a buffer-local first.

Source

fn insert_document_buffer( &self, id: BufferId, kind: BufferKind, handle: Arc<dyn Document>, flags: BufferFlags, name: Option<String>, )

H.1 (2026-05-31): generic Document-shaped buffer insertion. Used by extension crates (lattice-multibuffer today; future plugin-defined Document-shaped kinds) to push a BufferEntry into the registry without host knowing the kind exists.

kind must be a Document-shaped kind whose payload is an Arc<dyn Document>: today BufferKind::Document / BufferKind::Messages / BufferKind::Multibuffer. For other kinds (FileTree, Oil, Terminal, Help) the payload is structurally different and they keep their host-internal insertion paths until the v2 plugin- architecture work designs the generic extension point (per docs/dev/architecture/kind-agnostic-buffers.md §8 Q2).

Idempotent: if id is already registered the call is a no-op (consistent with the named-singleton create seam, crate::ModeActivator::ensure_named_document). The caller is responsible for allocating id via BufferId::next() first.

Errors fold into the impl’s logging path (e.g. the lattice-host impl logs through tracing and emits a host-side message); the trait surface is infallible because every error here is a programmer error (wrong kind, duplicate id) and there’s no recovery path the caller could enact.

Provided Methods§

Source

fn path_for(&self, _id: BufferId) -> Option<PathBuf>

Read the buffer’s on-disk file path, if it has one. None for path-less/synthetic buffers or when id is not registered. Default None so existing implementors (e.g. NullBufferStore) don’t need updating for this addition.

Source

fn contains_buffer(&self, id: BufferId) -> bool

Is id a buffer this store knows about at all?

The existence oracle, and the reason it is a method rather than a composition of the three above: every one of them returns None for two different reasons — “no such buffer” and “that buffer has no name / no path / no document handle” — so none of them can answer this question, and a caller that picks one is really asking something else.

name_for is the specific trap. It is the SYNTHETIC-name slot, so it answers None for every ordinary file-backed buffer; a caller using it as an existence check refuses exactly the buffers a user actually edits. The plugin project seam did that, and the project plugin was dead in the real editor as a result — every document-opened resolved to none and :project-switch reported “no projects remembered yet” forever, while its tests passed against a stub that answered Some for a file-backed buffer.

The default composes what the trait already offers, so no implementor breaks; it is best-effort and a store that can answer exactly — the host registry can, it has the map — should override. What the default cannot see is a registered buffer with no name, no path and no document handle, which it reports as absent.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§