Skip to main content

lattice_core/
lib.rs

1//! The editor's text model: rope-backed buffers, documents with undo and
2//! dirty tracking, regex search, and the small renderer-neutral vocabularies
3//! (buffer ids and kinds, pane geometry, folds, indent units, project roots)
4//! that every other lattice crate shares.
5//!
6//! This crate owns the actor-protected document model. It is content-type
7//! agnostic; tree-sitter, LSP, plugin, and rendering concerns live elsewhere.
8//! The dispatcher that serialises edits is not here either — it lives in
9//! `lattice-host`; this crate only guarantees each operation is consistent.
10//!
11//! # What it owns
12//!
13//! - **Text and editing.** [`Buffer`] wraps a `ropey::Rope` and applies
14//!   [`protocol::Edit`]s, returning an [`buffer::AppliedEdit`] (inverse +
15//!   tree-sitter delta). [`Document`] adds identity, path, versions,
16//!   selections, the [`UndoStack`] (with insert-session coalescing via
17//!   [`Document::begin_undo_group`]) and dirty tracking. Errors are
18//!   [`CoreError`].
19//! - **Search.** [`search::find`] / [`search::find_all`] stream a compiled
20//!   `fancy_regex::Regex` over the rope without materialising it.
21//! - **Shared vocabularies.** [`BufferId`] / [`BufferKind`] /
22//!   [`BufferFlags`]; the pane tree and its geometry
23//!   ([`ui::pane::PaneTree`]); [`Fold`] / [`FoldMethod`];
24//!   [`IndentUnit`] / [`IndentMethod`]; [`ProviderChain`] for formatting;
25//!   [`AutoWrap`]; the [`labeled_enum!`] macro every enum-typed option is
26//!   declared with.
27//! - **Service seams** for crates that sit below the host:
28//!   [`Clipboard`], [`ProjectResolver`], [`FoldOverlayService`],
29//!   [`ExcerptSourceResolver`], [`ViewArgsResolver`] — traits here,
30//!   implementations wired in at boot.
31//!
32//! # Coordinates
33//!
34//! Every position is a [`protocol::Position`]: a **0-based line** and a
35//! **0-based UTF-8 byte offset within that line** — not a char index and
36//! not a display column. Ranges are half-open `[start, end)`.
37//!
38//! # What it must not depend on
39//!
40//! Nothing above [`lattice_protocol`]: no syntax, grammar, config, mode,
41//! LSP, plugin or renderer crate, and no async runtime. Roughly thirty
42//! crates depend on this one, so any dependency added here is a dependency
43//! of the whole workspace — and one that reaches upward is a cycle. That
44//! is the structural reason it is its own crate: it is the floor. Types
45//! that several upper crates must share without depending on each other
46//! (fold sources, pane-group row mappers, project resolution) are hoisted
47//! *down* to here as data or traits, and implemented above.
48//!
49//! # Example
50//!
51//! ```
52//! use lattice_core::Document;
53//! use lattice_core::protocol::edit::Edit;
54//! use lattice_core::protocol::position::{Position, Range};
55//!
56//! # fn main() -> lattice_core::CoreResult<()> {
57//! let mut doc = Document::from_text("fn main() {}\n");
58//!
59//! // Rename `main` (line 0, bytes 3..7).
60//! let range = Range::new(Position::new(0, 3), Position::new(0, 7));
61//! let applied = doc.apply_edit(Edit::replace(range, "start"))?;
62//! assert_eq!(doc.text(), "fn start() {}\n");
63//! assert_eq!(applied.replaced_text, "main");
64//! assert_eq!(doc.text_version(), 1);
65//!
66//! doc.undo()?;
67//! assert_eq!(doc.text(), "fn main() {}\n");
68//! assert!(!doc.dirty());
69//! # Ok(())
70//! # }
71//! ```
72//!
73//! # Design documents
74//!
75//! - `docs/dev/architecture/design.md` §5.1 (buffer / document model) and
76//!   §5.9 (everything is a buffer; panes)
77//! - `docs/dev/architecture/owner-write-caret.md` (selection transform
78//!   across edits)
79//! - `docs/dev/architecture/project-resolution.md`,
80//!   `docs/dev/architecture/fold-architecture.md`,
81//!   `docs/dev/architecture/clipboard.md`,
82//!   `docs/dev/architecture/text-reflow.md`,
83//!   `docs/dev/architecture/pane-zoom.md`,
84//!   `docs/dev/architecture/pane-groups.md`
85
86#![warn(missing_docs)]
87
88// `labeled_enum!` lives at the top so its `#[macro_export]` is
89// visible to the modules below that consume it (`folding`,
90// `ui::display`). `#[macro_use]` makes the macro callable inside
91// the crate without `use`; the `#[macro_export]` attribute on the
92// macro itself exposes it to downstream crates.
93#[macro_use]
94pub mod labeled_enum;
95
96pub mod buffer;
97pub mod buffers;
98pub mod clipboard;
99pub mod document;
100pub mod error;
101pub mod folding;
102// RF.0: the `format.{indent,reflow,reformat}` provider vocabulary. Here
103// for the same reason `indent` is — the resolver lives in the host but
104// the grammar operators and the config layer both name these types, and
105// this crate is the floor both already stand on.
106pub mod format_chain;
107/// `~` expansion, shared so every consumer resolves a home the same way.
108pub mod home;
109// IN.0: `IndentUnit` / `IndentMethod` — the resolved indent value the
110// `>` / `<` operators consume. Here rather than in `lattice-indent`
111// because `lattice-syntax` → `lattice-grammar` makes an engine-side
112// home a dependency cycle; see `indent.rs`'s module doc.
113pub mod indent;
114pub mod indent_blocks;
115// SS.1: the shared on-disk fingerprint (autoread + multibuffer sources).
116pub mod on_disk;
117// PR.1: which project a path belongs to. Here rather than in a crate of
118// its own (heuristic #6: it carves out no dependency surface — the whole
119// mechanism is `std::path` + `std::fs::exists`) and here rather than in
120// `lattice-host` (no subsystem crate depends on the host, so terminal /
121// compilation / magit / multibuffer would each be a cycle away).
122pub mod project;
123pub mod search;
124pub mod ui;
125pub mod undo;
126// RF.0: `autowrap` — wrap-while-typing. Peer of `IndentMethod`; see
127// `wrap.rs` for why it is an option rather than a minor mode.
128pub mod wrap;
129
130pub use crate::buffer::Buffer;
131pub use crate::buffers::{BufferFlags, BufferId, BufferKind};
132pub use crate::clipboard::{Clipboard, ClipboardHandle, FakeClipboard};
133pub use crate::document::{Document, DocumentBuilder};
134pub use crate::error::{CoreError, CoreResult};
135pub use crate::folding::{
136    Fold, FoldMethod, FoldOverlayService, FoldOverlayServiceHandle, FoldSource, ProviderId,
137    ProviderKind,
138};
139pub use crate::format_chain::{FormatIntent, FormatProvider, ProviderChain};
140pub use crate::indent::{IndentMethod, IndentUnit};
141pub use crate::indent_blocks::LineShape;
142pub use crate::project::{
143    DEFAULT_ROOT_MARKERS, ExcerptSource, ExcerptSourceResolver, ExcerptSourceResolverHandle,
144    MarkerResolver, Project, ProjectKind, ProjectResolver, ProjectResolverHandle, ViewArgsResolver,
145    ViewArgsResolverHandle,
146};
147pub use crate::search::{Direction as SearchDir, SearchHit, find as search_find};
148pub use crate::undo::{UndoEntry, UndoStack};
149pub use crate::wrap::{AutoWrap, DEFAULT_TEXTWIDTH, WrapWidth};
150
151pub use lattice_protocol as protocol;