Skip to main content

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}