lattice_mode/capability.rs
1//! `CapabilitySet`: typed bitfield describing what a buffer can
2//! offer. Modes declare what they require via
3//! [`crate::Mode::required_capabilities`]; the registry validates the
4//! buffer satisfies all required bits before activation.
5//!
6//! New capabilities are added as the mode system grows. Bit
7//! layout is stable once a capability is shipped; a removed
8//! capability leaves a hole rather than reusing the bit, so old
9//! plugins compiled against the bit don't accidentally mean
10//! something different.
11
12use bitflags::bitflags;
13
14bitflags! {
15 /// Capabilities a buffer may expose to modes. A mode that
16 /// requires `LSP` cannot activate on a `text-mode` buffer with
17 /// no LSP attachment; the registry returns
18 /// [`crate::ModeActivationError::MissingCapability`].
19 #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
20 pub struct CapabilitySet: u32 {
21 /// Buffer has a stable URI (file path or URL). Most
22 /// LSP-related modes need this.
23 const BUFFER_URI = 0b0000_0001;
24 /// At least one LSP server is attached.
25 const LSP = 0b0000_0010;
26 /// Tree-sitter parser is attached (the major mode owns
27 /// the parser; minor modes that do tree-sitter queries
28 /// require this).
29 const TREE_SITTER = 0b0000_0100;
30 /// Buffer supports folding (rope + fold metadata).
31 const FOLDS = 0b0000_1000;
32 /// Buffer is editable (not read-only). The
33 /// `read-only-mode` minor flips this off.
34 const WRITABLE = 0b0001_0000;
35 /// Buffer has diagnostic-overlay support (decoration
36 /// provider for inline + gutter squiggles).
37 const DIAGNOSTICS = 0b0010_0000;
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn empty_satisfies_no_requirements() {
47 let buf = CapabilitySet::empty();
48 let req = CapabilitySet::LSP;
49 assert!(!buf.contains(req));
50 }
51
52 #[test]
53 fn superset_satisfies_subset() {
54 let buf = CapabilitySet::BUFFER_URI | CapabilitySet::LSP | CapabilitySet::WRITABLE;
55 let req = CapabilitySet::BUFFER_URI | CapabilitySet::LSP;
56 assert!(buf.contains(req));
57 }
58
59 #[test]
60 fn missing_bit_fails_validation() {
61 let buf = CapabilitySet::BUFFER_URI | CapabilitySet::WRITABLE;
62 let req = CapabilitySet::BUFFER_URI | CapabilitySet::LSP;
63 assert!(!buf.contains(req));
64 // The missing bits computed by `req - buf` describe what's
65 // absent -- useful for the diagnostic surfaced in
66 // `ModeActivationError::MissingCapability`.
67 let missing = req - buf;
68 assert_eq!(missing, CapabilitySet::LSP);
69 }
70}