ailloli_ui_editor/code/
config.rs

1//! Code-editor feature, gutter, scrollbar, and semantic color configuration.
2
3use ailloli_ui_core::{Color, Theme};
4
5use crate::{EditorConfig, EditorScrollbarConfig, EditorWrapMode};
6
7/// Code-editor specific configuration layered over the generic editor config.
8///
9/// # Examples
10///
11/// ```
12/// use ailloli_ui_editor::{CodeEditorConfig, EditorWrapMode};
13/// let config = CodeEditorConfig::default();
14/// assert_eq!(config.editor.wrap_mode, EditorWrapMode::NoWrap);
15/// assert!(config.gutter.enabled && config.scrollbars.enabled);
16/// ```
17#[derive(Debug, Clone, Copy, PartialEq)]
18pub struct CodeEditorConfig {
19    /// Generic editor metrics and no-wrap policy.
20    pub editor: EditorConfig,
21    /// Code-specific semantic colors.
22    pub theme: CodeTheme,
23    /// Left gutter visibility and geometry.
24    pub gutter: GutterConfig,
25    /// Editor-owned scrollbar configuration.
26    pub scrollbars: EditorScrollbarConfig,
27    /// Optional code feature toggles.
28    pub features: CodeEditorFeatureFlags,
29}
30
31/// Selects no-wrap layout, dark theme colors, gutter, scrollbars, and features.
32impl Default for CodeEditorConfig {
33    /// Synchronizes generic editor background/foreground with the code theme.
34    fn default() -> Self {
35        let theme = CodeTheme::default();
36        let mut editor = EditorConfig {
37            wrap_mode: EditorWrapMode::NoWrap,
38            ..EditorConfig::default()
39        };
40        editor.style.bg = theme.background;
41        editor.style.fg = theme.foreground;
42        Self {
43            editor,
44            theme,
45            gutter: GutterConfig::default(),
46            scrollbars: EditorScrollbarConfig::default(),
47            features: CodeEditorFeatureFlags::default(),
48        }
49    }
50}
51
52/// Feature switches for code-specific processing and paint layers.
53///
54/// # Examples
55///
56/// ```
57/// use ailloli_ui_editor::CodeEditorFeatureFlags;
58/// let flags = CodeEditorFeatureFlags::default();
59/// assert!(flags.search && flags.diagnostics && flags.folding && flags.symbols);
60/// assert!(!flags.semantic_backends);
61/// ```
62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63pub struct CodeEditorFeatureFlags {
64    /// Enables search match computation and paint.
65    pub search: bool,
66    /// Enables diagnostic hit testing and paint.
67    pub diagnostics: bool,
68    /// Enables fold-region processing and gutter markers.
69    pub folding: bool,
70    /// Enables local symbol indexing.
71    pub symbols: bool,
72    /// Enables opt-in LSP/SCIP enrichment owned by the caller.
73    pub semantic_backends: bool,
74}
75
76/// Enables local deterministic features while leaving semantic backends off.
77impl Default for CodeEditorFeatureFlags {
78    /// Returns search/diagnostics/folding/symbols true and semantic false.
79    fn default() -> Self {
80        Self {
81            search: true,
82            diagnostics: true,
83            folding: true,
84            symbols: true,
85            semantic_backends: false,
86        }
87    }
88}
89
90/// Gutter controls for code-oriented editor frames.
91///
92/// Width is logical pixels. Viewport construction treats disabled, zero, or
93/// negative width as no gutter and clamps positive width to content width.
94///
95/// # Examples
96///
97/// ```
98/// use ailloli_ui_editor::GutterConfig;
99/// let gutter = GutterConfig::default();
100/// assert_eq!(gutter.width, 48.0);
101/// assert!(gutter.enabled && gutter.line_numbers && gutter.fold_markers);
102/// ```
103#[derive(Debug, Clone, Copy, PartialEq)]
104pub struct GutterConfig {
105    /// Whether any gutter space is reserved.
106    pub enabled: bool,
107    /// Requested gutter width in logical pixels.
108    pub width: f32,
109    /// Whether line-number items are emitted.
110    pub line_numbers: bool,
111    /// Whether fold marker/guide items are emitted.
112    pub fold_markers: bool,
113}
114
115/// Supplies an enabled 48-logical-pixel gutter with numbers and folds.
116impl Default for GutterConfig {
117    /// Returns the documented gutter defaults.
118    fn default() -> Self {
119        Self {
120            enabled: true,
121            width: 48.0,
122            line_numbers: true,
123            fold_markers: true,
124        }
125    }
126}
127
128/// Minimal visual theme for the CodeEditor.
129///
130/// Colors are semantic paint inputs and do not affect shaping/cache geometry.
131///
132/// # Examples
133///
134/// ```
135/// use ailloli_ui_editor::CodeTheme;
136/// assert_eq!(CodeTheme::dark(), CodeTheme::default());
137/// ```
138#[derive(Debug, Clone, Copy, PartialEq)]
139pub struct CodeTheme {
140    /// Main code surface.
141    pub background: Color,
142    /// Default source text.
143    pub foreground: Color,
144    /// Gutter surface.
145    pub gutter_bg: Color,
146    /// Inactive line numbers.
147    pub line_number: Color,
148    /// Active line number.
149    pub active_line_number: Color,
150    /// Active line fill.
151    pub active_line_bg: Color,
152    /// Active line focus ring.
153    pub active_line_ring: Color,
154    /// Inactive search match fill.
155    pub search_match_bg: Color,
156    /// Active search match fill.
157    pub search_active_match_bg: Color,
158    /// Error diagnostic marker/underline.
159    pub diagnostic_error: Color,
160    /// Warning diagnostic marker/underline.
161    pub diagnostic_warning: Color,
162    /// Information diagnostic marker/underline.
163    pub diagnostic_info: Color,
164    /// Hint diagnostic marker/underline.
165    pub diagnostic_hint: Color,
166    /// Active diagnostic line fill.
167    pub diagnostic_active_bg: Color,
168    /// Inactive fold marker.
169    pub fold_marker: Color,
170    /// Active fold marker.
171    pub fold_marker_active: Color,
172    /// Fold guide line.
173    pub fold_guide: Color,
174    /// Syntax keyword.
175    pub syntax_keyword: Color,
176    /// Syntax type.
177    pub syntax_type: Color,
178    /// Syntax function.
179    pub syntax_function: Color,
180    /// Syntax string.
181    pub syntax_string: Color,
182    /// Syntax numeric literal.
183    pub syntax_number: Color,
184    /// Syntax comment.
185    pub syntax_comment: Color,
186    /// Syntax operator.
187    pub syntax_operator: Color,
188    /// Syntax punctuation.
189    pub syntax_punctuation: Color,
190    /// Syntax identifier/default token.
191    pub syntax_identifier: Color,
192}
193
194/// Code-theme constructors.
195impl CodeTheme {
196    /// Returns the framework default dark-derived theme.
197    ///
198    /// # Examples
199    ///
200    /// ```
201    /// use ailloli_ui_editor::CodeTheme;
202    /// assert_eq!(CodeTheme::dark(), CodeTheme::default());
203    /// ```
204    pub fn dark() -> Self {
205        Self::default()
206    }
207
208    /// Maps framework palette roles plus fixed syntax accents into code colors.
209    ///
210    /// # Examples
211    ///
212    /// ```
213    /// use ailloli_ui_core::Theme;
214    /// use ailloli_ui_editor::CodeTheme;
215    /// let base = Theme::default();
216    /// let code = CodeTheme::from_theme(base);
217    /// assert_eq!(code.background, base.palette().background);
218    /// assert_eq!(code.foreground, base.palette().text);
219    /// ```
220    pub fn from_theme(theme: Theme) -> Self {
221        let palette = theme.palette();
222        Self {
223            background: palette.background,
224            foreground: palette.text,
225            gutter_bg: palette.surface,
226            line_number: palette.text_muted,
227            active_line_number: palette.text,
228            active_line_bg: Color::rgba(255, 255, 255, 0.05),
229            active_line_ring: palette.focus.with_alpha(0.32),
230            search_match_bg: palette.warning.with_alpha(0.28),
231            search_active_match_bg: palette.accent.with_alpha(0.48),
232            diagnostic_error: palette.danger,
233            diagnostic_warning: palette.warning,
234            diagnostic_info: palette.info,
235            diagnostic_hint: palette.text_muted,
236            diagnostic_active_bg: palette.danger.with_alpha(0.12),
237            fold_marker: palette.warning,
238            fold_marker_active: palette.accent,
239            fold_guide: palette.warning.with_alpha(0.36),
240            syntax_keyword: Color::rgb(197, 134, 192),
241            syntax_type: palette.info,
242            syntax_function: Color::rgb(220, 220, 170),
243            syntax_string: Color::rgb(206, 145, 120),
244            syntax_number: Color::rgb(181, 206, 168),
245            syntax_comment: Color::rgb(106, 153, 85),
246            syntax_operator: palette.text,
247            syntax_punctuation: palette.text_muted,
248            syntax_identifier: palette.text,
249        }
250    }
251}
252
253/// Derives the code palette from [`Theme::default`].
254impl Default for CodeTheme {
255    /// Returns the framework-default themed palette.
256    fn default() -> Self {
257        Self::from_theme(Theme::default())
258    }
259}