Skip to main content

BufferRegistry

Struct BufferRegistry 

Source
pub struct BufferRegistry { /* private fields */ }
Expand description

The App’s buffer registry. Methods take &self and lock internally; the registry is Clone so the App’s BufferStore service impl can hold a clone for cross-thread access.

Perf plan B.4.b: carries an AtomicU64 version counter alongside the inner. Every mutating method (insert, remove, set_flags, set_name, and every with_*_mut closure accessor) bumps it. Versioned<T>’s DerefMut discipline can’t fire here because the registry uses interior mutability — callers take &self rather than &mut self, so autoref through DerefMut is impossible. The atomic is shared via the same Arc<...> clone as inner so every registry handle sees the same counter; Clone is one Arc bump for the pair.

version() is the read API. The BuffersRenderState / TabsRenderState caches on Editor::publish_cache compare against the prior captured value to decide cache reuse vs. rebuild.

Implementations§

Source§

impl BufferRegistry

Source

pub fn version(&self) -> u64

Perf plan B.4.b: monotonic mutation counter. Read by the publish cache (see crate::render_state::PublishCache) to decide whether the cached buffers / tabs Arcs can be reused across publishes. Relaxed ordering is fine because the publish path runs on the actor thread; we only need the counter to advance after a mutation, not to synchronise memory order with other writers.

Source§

impl BufferRegistry

Source

pub fn new() -> BufferRegistry

Source

pub fn insert(&self, entry: BufferEntry)

Source

pub fn remove(&self, id: BufferId) -> Option<BufferEntry>

Source

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

Source

pub fn len(&self) -> usize

Source

pub fn is_empty(&self) -> bool

Source

pub fn kind_of(&self, id: BufferId) -> Option<BufferKind>

Kind of the entry at id, or None if absent.

Source

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

Synthetic name of the entry at id, or None if absent or if the entry has no name set.

Source

pub fn flags_of(&self, id: BufferId) -> Option<BufferFlags>

Per-buffer flags. BufferFlags is Copy so this returns owned without locking issues.

Source

pub fn set_flags(&self, id: BufferId, flags: BufferFlags) -> bool

Mutate the per-buffer flags via callback (e.g. flip listed on :setlocal nobuflisted once that lands).

Source

pub fn set_name(&self, id: BufferId, name: Option<String>) -> bool

Rename the entry’s synthetic name slot. Used by the supervisor when an actor exits and the per-instance buffer gets renamed *lsp:rust:/path* → *lsp:rust:/path (exited)*.

Source

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

Kind-specific convenience: clone the Arc<dyn Document> for id. The handle is Send + Sync and can be held across thread boundaries. M.0: returns the polymorphic shape (was RopeDocumentHandle pre-M.0) so the registry serves multibuffer handles (M.1) through the same path.

Source

pub fn buffer_id_for_document( &self, document_id: DocumentId, ) -> Option<BufferId>

D.3.a.1 (2026-05-29): reverse lookup — DocumentId → BufferId. Used by the diff subsystem’s DocumentBufferResolver impl: bus events carry DocumentId, host-side state is keyed by BufferId. Scans the registry’s document entries — O(N_documents) per call, acceptable at v1 buffer counts (~tens; the LSP fan-in and the keymap registry do similar walks). Future inverse index lives behind the same method signature.

Source

pub fn document_path(&self, id: BufferId) -> Option<PathBuf>

Kind-specific convenience: path of the document at id.

Source

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

Kind-specific convenience: dirty flag for the document at id. Returns false for absent / non-document.

Source

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

Source

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

True iff the entry at id is the *messages* transcript. Symmetric with Self::contains_help / Self::contains_oil / Self::contains_file_tree — callers that need to differentiate the Messages identity from a regular Document branch on this.

Source

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

Source

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

Source

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

Source

pub fn entry_summary( &self, id: BufferId, ) -> Option<(BufferId, BufferKind, BufferFlags, Option<String>)>

Compact snapshot of an entry: (id, kind, flags, name, is_document_path_set). Used by :ls and the buffer picker to render rows without holding the lock through complex display logic. Returns None if the entry is absent.

Source

pub fn sorted_ids(&self) -> Vec<BufferId>

All ids in ascending order. Used by :bn / :bp for deterministic cycling order independent of HashMap hash-randomization.

Source

pub fn listed_ids_sorted(&self) -> Vec<BufferId>

All listed ids in ascending order. :bn / :bp skip unlisted buffers (vim semantics); :ls shows them under a separate header (post-v1 polish).

Source

pub fn document_ids_sorted(&self) -> Vec<BufferId>

Document buffers only, sorted by id. The *messages* transcript stores as BufferData::Messages (see Self::messages_ids_sorted) so it is excluded from this list even though storage is identical; callers that want every rope-backed-doc kind should walk both.

Source

pub fn messages_ids_sorted(&self) -> Vec<BufferId>

*messages* (and any future Messages-kind) buffers, sorted by id. Symmetric with Self::document_ids_sorted.

Source

pub fn multibuffer_ids_sorted(&self) -> Vec<BufferId>

K.4.8 (2026-06-02): Multibuffer-kind buffers, sorted by id. Symmetric with Self::messages_ids_sorted / Self::document_ids_sorted. Used by :ls to count the Multibuffer entries separately from Messages now that Multibuffer has its own listing row.

Source

pub fn file_tree_ids_sorted(&self) -> Vec<BufferId>

File-tree buffers only, sorted by id.

Source

pub fn help_ids_sorted(&self) -> Vec<BufferId>

Help buffers only, sorted by id.

Source

pub fn oil_ids_sorted(&self) -> Vec<BufferId>

Source

pub fn file_tree_ids(&self) -> Vec<BufferId>

IDs of every registered file-tree buffer, in arbitrary order. The App-side file_tree_with_root walks these + probes each one’s FileTreeRoot buffer-local for the dedup lookup; the registry can’t do that walk because it doesn’t own buffer-locals.

Source

pub fn oil_ids(&self) -> Vec<BufferId>

IDs of every registered oil buffer, in arbitrary order.

Source

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

First buffer whose name matches exactly. Used by subsystem-owned synthetic buffers (*lsp*, *messages*, per-instance LSP log buffers) so re-running the owner’s create-or-activate path surfaces the existing entry rather than allocating a duplicate.

Source

pub fn help_with_title(&self, title: &str) -> Option<BufferId>

First help buffer with the given title, if any. Used by the :lsp-log / :lsp-trace-log openers so re-running the command surfaces the existing buffer rather than allocating a duplicate.

Source

pub fn document_with_path(&self, path: &Path) -> Option<BufferId>

First document buffer with the given path, if any. Used by :e FILE to detect “already open”.

Source

pub fn with_entry<R>( &self, id: BufferId, f: impl FnOnce(&BufferEntry) -> R, ) -> Option<R>

Run f against the BufferEntry at id while holding the registry lock. Returns None if the entry is absent.

Source

pub fn with_entry_mut<R>( &self, id: BufferId, f: impl FnOnce(&mut BufferEntry) -> R, ) -> Option<R>

Mutable variant of Self::with_entry.

Perf plan B.4.b: conservatively bumps the version after the closure runs, even if the closure didn’t actually mutate. Over-bumping causes a one-time cache miss on the next publish — safe and bounded — versus the alternative of missing a real mutation, which would leave stale Arcs visible to renderers indefinitely.

Source

pub fn with_document<R>( &self, id: BufferId, f: impl FnOnce(&DocumentEntry) -> R, ) -> Option<R>

Source

pub fn with_document_mut<R>( &self, id: BufferId, f: impl FnOnce(&mut DocumentEntry) -> R, ) -> Option<R>

Source

pub fn help_content_view(&self, id: BufferId) -> Option<HelpBuffer>

PU.1a: reconstruct a transient HelpBuffer view from the registry Document at id. Help content is now an actor-backed synthetic Document; this builds the slim view value the bespoke help renderers still consume (PU.1b deletes both). The view’s scroll / cursor default to 0 — callers overlay the live popup (popup_scroll/popup_cursor) or pane scroll+cursor. None when id is not a help buffer.

Source

pub fn with_terminal<R>( &self, id: BufferId, f: impl FnOnce(&TerminalBuffer) -> R, ) -> Option<R>

Source

pub fn with_terminal_mut<R>( &self, id: BufferId, f: impl FnOnce(&mut TerminalBuffer) -> R, ) -> Option<R>

Source

pub fn for_each<F>(&self, f: F)
where F: FnMut(&BufferEntry),

Run f against every entry under the registry lock. Callers must not re-enter the registry from inside.

Trait Implementations§

Source§

impl BufferStore for BufferRegistry

Source§

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

Answered exactly rather than through the trait’s best-effort default: this registry holds the map, so it can see a registered buffer that has no name, no path and no document handle — which the default reports as absent.

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 for extension crates (lattice-multibuffer today; future plugin-defined Document-shaped kinds). Maps kind to the appropriate BufferData variant; other kinds (FileTree, Oil, Terminal, Help) log + skip — their payload is not a Document.

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(...)). Read more
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 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§

impl Clone for BufferRegistry

Source§

fn clone(&self) -> BufferRegistry

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 BufferRegistry

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for BufferRegistry

Source§

fn default() -> BufferRegistry

Returns the “default value” for a type. Read more
Source§

impl TerminalStore for BufferRegistry

Source§

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

Build a SyntheticDoc from the terminal buffer’s current grid state and stash it on the buffer. Returns true if a terminal buffer existed for id (and the doc was installed); false otherwise. Idempotent — re-calling rebuilds the doc.
Source§

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

Drop any existing SyntheticDoc on the buffer. Idempotent. Returns true if a terminal buffer existed for id; false otherwise.

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
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync> ⓘ

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

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

Source§

fn __clone_box(&self, _: Private) -> *mut ()

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> IntoMaybeUndefined<T> for T

§

fn into_maybe_undefined(self) -> MaybeUndefined<T>

Converts this value into a three-state builder argument.
§

impl<T> IntoOption<T> for T

§

fn into_option(self) -> Option<T>

Converts this value into an optional builder argument.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Pointee for T

§

type Pointer = u32

§

fn debug( pointer: <T as Pointee>::Pointer, f: &mut Formatter<'_>, ) -> Result<(), Error>

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

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