Skip to main content

Crate lattice_config

Crate lattice_config 

Source
Expand description

The typed options system: every editor, mode, renderer and plugin setting is a registered, typed value in one ConfigRegistry, read on the hot path by type and written at the boundaries (:set, lattice.toml, :setlocal, plugins) by name (DESIGN.md §5.12).

Renderer-agnostic option machinery: the OptionType trait, the typed option::Option<T> spec, the type-erased ErasedOption trait the registry stores, and ConfigRegistry itself.

§What it owns

§What it must not depend on

Its dependencies are the foundation only (lattice-protocol, lattice-core, lattice-completion). Almost every crate reads options, so anything this crate imported would sit beneath the whole editor: no host / App, no renderer, no mode registry, no event bus (lattice-runtime — events leave through an injected EventPublisher closure instead), no plugin host (so PluginTraceLevel duplicates the host’s trace-level labels rather than importing the type). The layer-input override types moved into this crate for the same reason (see overrides).

§Example

use lattice_config::{ConfigRegistry, Tabstop};

let config = ConfigRegistry::new();
config.init_from_linkme(); // register every `options!` declaration

// Hot path: read by type.
assert_eq!(*config.get_typed::<Tabstop>().unwrap(), 4);

// Boundary: write by name, exactly as `:set ts=2` does.
assert_eq!(config.parse_and_set_command("ts=2").unwrap(), "tabstop=2");
assert_eq!(*config.get_typed::<Tabstop>().unwrap(), 2);

// Validation runs on every write; a rejected write changes nothing.
assert!(config.parse_and_set_command("tabstop=99").is_err());
assert_eq!(*config.get_typed::<Tabstop>().unwrap(), 2);

Design: docs/dev/architecture/typed-configuration.md (schemas, composite values), docs/dev/architecture/config-and-init.md (when configuration arrives), docs/dev/architecture/buffer-local-options.md (:setlocal, origins), docs/dev/architecture/mode-architecture.md §6 (declarations, layering, groups).

§Design (γ — value-on-spec storage)

Each option::Option<T> owns its current value behind an [arc_swap::ArcSwap<T>]. Reads through a typed crate::option::OptionHandle<T> are wait-free pointer loads. Writes go through the registry (typed via set / by-name via parse_and_set_command), which validates and stores.

Renderer-specific options live in the renderer’s crate but register against the same ConfigRegistry at App startup. The crate has no knowledge of the App or any concrete renderer.

§Crate boundary

The trait + the three primitive impls (bool, i64, String) live here. So do the impls for the lattice-core domain enums (FoldMethod, IndentMethod, …): the orphan rule allows a local trait on a foreign type, and lattice-core cannot depend on this crate. A crate above this one that defines its own value type implements OptionType itself, importing the trait from lattice-config.

§What’s NOT here

  • App reference. Setters don’t take an &mut App. The value lives in the spec; consumers read it through their typed handle. Renderers run side-effect cascades (relativenumber ⇒ number, foldmethod ⇒ recompute folds, ui.* ⇒ refresh derived theme styles) in their own post-set hook, polling the parsed :set form.
  • Other crates’ options. Options owned elsewhere are declared with the same options! macro in the owning crate and join the registry through OPTION_DECLS at boot — e.g. the ui.separator / ui.statusline_*_fg family in lattice_host::ui::theme_options. Runtime-only options (plugins) use ConfigRegistry::register.

§Event-bus integration (DESIGN.md §5.10 + §5.12)

The registry optionally publishes [lattice_protocol::Event::OptionChanged] on every successful set so consumers can react to typed-option changes without polling. Wire it via ConfigRegistry::set_event_publisher – the closure receives the Event and delegates to the consumer’s bus. The crate is agnostic to which bus (avoids a dep on lattice-runtime); the App today calls event_bus.publish(event) from inside the closure.

Events fire on:

  • typed set::<T>(handle, value) writes
  • cmdline parse_and_set_command(":set foo=bar") (Assign)
  • cmdline :set nofoo (Negate)
  • cmdline :set foo boolean toggle (NameOnly on bool option)

Events do NOT fire on :set foo? (Query) or on validation / parse failures.

Re-exports§

pub use completion::OptionsGenerator;
pub use core_options::COMPLETION_SOURCE_SNIPPET_DEFAULT_PRIORITY;
pub use core_options::AutoWrapOption;
pub use core_options::ClipboardEnabled;
pub use core_options::CommandLineExpandHeight;
pub use core_options::CompletionAutoInsertSingle;
pub use core_options::CompletionExtraCommitChars;
pub use core_options::CompletionGhostText;
pub use core_options::CompletionSourceBufferWordsPriority;
pub use core_options::CompletionSourceLspPriority;
pub use core_options::CompletionSourcePathPriority;
pub use core_options::CompletionSourceSnippetPriority;
pub use core_options::CompletionSourceTreeSitterPriority;
pub use core_options::CursorLine;
pub use core_options::DiagnosticsInlineOption;
pub use core_options::DiagnosticsMinSeverityOption;
pub use core_options::ElectricIndent;
pub use core_options::ExpandTab;
pub use core_options::FoldEnable;
pub use core_options::FoldMethodOption;
pub use core_options::FormatIndentChain;
pub use core_options::FormatOnSave;
pub use core_options::FormatPrg;
pub use core_options::FormatReflowChain;
pub use core_options::FormatReformatChain;
pub use core_options::HelpAproposDisplay;
pub use core_options::HelpDescribeDisplay;
pub use core_options::HelpListDisplay;
pub use core_options::HelpTopicDisplay;
pub use core_options::HoverDisplay;
pub use core_options::IgnoreCase;
pub use core_options::IndentMethodOption;
pub use core_options::LspLogDisplay;
pub use core_options::LspStatusDisplay;
pub use core_options::MessagesDisplay;
pub use core_options::MessagesFilter;
pub use core_options::ModelineCenter;
pub use core_options::ModelineLeft;
pub use core_options::ModelinePadding;
pub use core_options::ModelineRight;
pub use core_options::ModelineSeparator;
pub use core_options::MouseEnabled;
pub use core_options::NoFile;
pub use core_options::Number;
pub use core_options::PickerResultDisplay;
pub use core_options::ProjectRootMarkers;
pub use core_options::ReadOnly;
pub use core_options::RelativeNumber;
pub use core_options::Scroll;
pub use core_options::Scrollbind;
pub use core_options::Scrolloff;
pub use core_options::Shiftwidth;
pub use core_options::Sidescroll;
pub use core_options::Sidescrolloff;
pub use core_options::SignColumnOption;
pub use core_options::SignatureDisplay;
pub use core_options::StartOfLine;
pub use core_options::TablineShowOption;
pub use core_options::Tabstop;
pub use core_options::TerminalEscExits;
pub use core_options::TerminalScrollbackLines;
pub use core_options::TextWidth;
pub use core_options::TransientMaxRows;
pub use core_options::Whitespace;
pub use core_options::WhitespaceEol;
pub use core_options::WhitespaceLeading;
pub use core_options::WhitespaceSpace;
pub use core_options::WhitespaceTab;
pub use core_options::WhitespaceTrailing;
pub use core_options::Wrap;
pub use group::Ai;
pub use group::Appearance;
pub use group::Completion;
pub use group::Diagnostics;
pub use group::Display;
pub use group::Editing;
pub use group::Editor;
pub use group::Filetree;
pub use group::GROUP_DECLS;
pub use group::Help;
pub use group::Lsp;
pub use group::Magit;
pub use group::Messages;
pub use group::Modeline;
pub use group::Mouse;
pub use group::Notifications;
pub use group::Oil;
pub use group::OptionGroup;
pub use group::OptionGroupMetadata;
pub use group::Pane;
pub use group::Picker;
pub use group::Plugin;
pub use group::Project;
pub use group::Search;
pub use group::Snippet;
pub use group::Tabline;
pub use group::Terminal;
pub use group::Window;
pub use group::ends_with_mode_suffix;
pub use loader::LoadMessage;
pub use loader::LoadMessageLevel;
pub use loader::LoadOutcome;
pub use loader::cache_home;
pub use loader::cache_home_from;
pub use loader::config_home;
pub use loader::default_user_config_path;
pub use loader::load_default_paths;
pub use loader::load_file;
pub use loader::lookup_dotted_path;
pub use loader::migrate_path;
pub use loader::project_config_path;
pub use option_decl::OPTION_DECLS;
pub use schema::ConfigSchema;
pub use schema::ConfigValue;
pub use schema::ScalarKind;
pub use schema::SchemaError;
pub use schema::SchemaField;
pub use overrides::OptionOverride;
pub use overrides::OptionOverrideSet;
pub use overrides::OverridePriority;

Modules§

completion
OptionsGenerator — completion source for :set <Tab>.
core_options
Renderer-agnostic options. M.2.0b migrates these from the pre-typed-keys imperative Option::builder() form to the macro-driven declarative form (Design B + D from the mode-architecture.md discussion).
group
Option groups: the user-facing organization unit for :customize <name> (mode-architecture.md §6.7.1.1).
loader
Static config-file loader (DESIGN.md §5.12; first slice of the TOML surface called out in the design doc’s “TOML covers static option overrides only” line).
option
Typed Option<T> spec + the OptionHandle<T> consumers use for hot-path reads.
overrides
Layered option overrides (M.2.1).
schema
TC.1: ConfigSchema / ConfigValue — what an option’s value is shaped like, as data, plus schema-checked validation that reports a path. TC.1 — what an option’s value is shaped like, as data.

Macros§

groups
Declarative group declaration block. See lattice_config::OptionGroup and lattice_config::groups! for the surface contract.
options
Declarative option declaration block. See the trait doc on lattice_config::OptionDecl and the macro doc on lattice_config::options! for the surface contract.
overrides
Construct a typed OptionOverrideSet for a Mode::options() return.

Structs§

ConfigRegistry
Process-shared registry.
OptionDeclMetadata
Metadata captured at macro expansion for one option. The register function pointer is monomorphised at the call site so the registry boot path can register every option without pulling each <T> into a generic over the slice.
PaneBufferHistorySize
How many buffers one pane remembers in its back/forward trail (<C-6> / <C-7>, :history pane-buffers).
PaneZoomIndicator
ZP.4: where the zoom marker shows while a pane is zoomed (<C-w>z / :zoom-pane).
PluginTraceLevelOption
Global default plugin boundary-trace verbosity. off / error / warn / info (default) / debug / trace. info and below carry only crash/lifecycle signal — no per-call traces (the keystroke hot path stays free). Raise to debug to trace every host↔guest call; per-plugin overrides live in the :plugins view (T).
ResolvedOptions
Cached snapshot of the resolved value for every option a buffer reads. Built by the crate::Resolver; invalidated on mode toggle, option write, or modal-state transition; recomputed eagerly on invalidation per the v1 invalidation policy (mode-architecture.md §6.3.1).
Resolver
Walks layered overrides and emits a fresh ResolvedOptions.
RootMarkers
The ordered marker set a project root is recognised by.
StartMaximized
Maximize the window on launch (fill the work area, keep the menu bar — not native fullscreen). GPUI peer only; ignored by the TUI.
WindowDecorationsOption
OS window chrome (GPUI only; ignored by the terminal UI). One of: full (default) — system titlebar + window controls. none — borderless: no titlebar or controls, like alacritty decorations = none / kitty / emacs undecorated. On macOS a none window is non-resizable by any means — even Raycast/yabai can’t move or resize it; it opens at a fixed size. transparent — frameless-looking but still resizable: a transparent titlebar with the traffic-light buttons hidden. Edge-resize works and window managers (Raycast/yabai) can drive it; rounded corners + shadow remain. The macOS-friendly frameless option. Applied at window creation; a change takes effect on the next launch.

Enums§

ConfigError
What the registry’s fallible operations can fail with. Kept separate from raw String errors so callers can echo the canonical message without re-stringifying.
Decorations
ui.window.decorations — OS window chrome.
DiagnosticsInline
ui.diagnostics.inline — where the inline (end-of-line virtual-text) diagnostic summary renders.
DiagnosticsSeverity
ui.diagnostics.inline-min-severity — the least-severe level a diagnostic must be to appear in the inline summary. A diagnostic is included when its severity is as severe or more severe than this (i.e. its rank ≤ this rank).
ExpandHeight
command-line.expand-height — how tall the expanded : band grows.
ModelineZone
A modeline zone’s configured layout: descriptor-driven (Auto) or an explicit ordered element-id list (Ids).
OptionOrigin
The layer that supplied the winning value in a resolution cycle.
ParsedSet
One :set argument, classified by syntax alone.
PluginTraceLevel
plugin.trace-level — the global default plugin boundary-trace verbosity. Ordered least→most verbose; a record is kept when its level ≤ this gate. info (the default) drops per-call traces — authors opt a plugin up to debug / trace (globally here, or per-plugin from the :plugins view).
SignColumn
signcolumn — whether to reserve the gutter sign columns.

Statics§

OPTION_DECLS
Distributed slice of every option declared anywhere in the workspace. Each options! macro invocation submits a &'static OptionDeclMetadata element here; the registry’s startup loader walks the slice to register each option and validate cross-crate display-name uniqueness.

Traits§

ErasedOption
Type-erased operations every typed Option<T> supports. The registry stores Arc<dyn ErasedOption> in a Vec indexed by the private idx field of crate::option::OptionHandle; parse_and_set_by_name drives this trait when the user types :set name=value.
HasGroup
Group binding declared by OptionDecl declarations. Each option belongs to exactly one crate::OptionGroup (selected per declaration block in the macro, with optional per-option override). Stored on the metadata record so :customize <name> can prefix-match.
OptionDecl
Compile-time declaration of one option. Each option type is a unique unit struct (typically generated by the crate::options! macro) implementing this trait.
OptionType
Surface contract for any value a typed crate::option::Option can hold. Implementors describe how their type round-trips through the user-facing :set foo=value syntax.

Functions§

parse_set
Classify one :set argument (without the :set prefix).
plugin_option_groups
Runtime-registered options that have no compile-time declaration — i.e. plugin options — grouped by their dotted namespace.

Type Aliases§

EventPublisher
Sink the registry calls after every successful set so consumers can react to typed-option changes through the §5.10 event bus. Stored as a Box<dyn Fn> so lattice-config doesn’t depend on lattice-runtime’s EventBus directly – the App wires event_bus.publish(event) as the closure body at boot.