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}