1use gpui::App;
2use settings::{LanguageSettingsContent, SettingsContent};
3use std::sync::Arc;
4use ui::{IntoElement, SharedString};
5
6use crate::{
7 LOCAL, SettingField, SettingItem, SettingsFieldMetadata, SettingsPage, SettingsPageItem,
8 SubPageLink, USER, all_language_names, sub_page_stack,
9};
10
11pub(crate) fn settings_data(cx: &App) -> Vec<SettingsPage> {
12 vec![
13 SettingsPage {
14 title: "General",
15 items: vec![
16 SettingsPageItem::SectionHeader("General Settings"),
17 SettingsPageItem::SettingItem(SettingItem {
18 title: "Confirm Quit",
19 description: "Confirm before quitting Zed",
20 field: Box::new(SettingField {
21 pick: |settings_content| &settings_content.workspace.confirm_quit,
22 pick_mut: |settings_content| &mut settings_content.workspace.confirm_quit,
23 }),
24 metadata: None,
25 files: USER,
26 }),
27 SettingsPageItem::SettingItem(SettingItem {
28 title: "When Closing With No Tabs",
29 description: "What to do when using the 'close active item' action with no tabs",
30 field: Box::new(SettingField {
31 pick: |settings_content| {
32 &settings_content.workspace.when_closing_with_no_tabs
33 },
34 pick_mut: |settings_content| {
35 &mut settings_content.workspace.when_closing_with_no_tabs
36 },
37 }),
38 metadata: None,
39 files: USER,
40 }),
41 SettingsPageItem::SettingItem(SettingItem {
42 title: "On Last Window Closed",
43 description: "What to do when the last window is closed",
44 field: Box::new(SettingField {
45 pick: |settings_content| &settings_content.workspace.on_last_window_closed,
46 pick_mut: |settings_content| {
47 &mut settings_content.workspace.on_last_window_closed
48 },
49 }),
50 metadata: None,
51 files: USER,
52 }),
53 SettingsPageItem::SettingItem(SettingItem {
54 title: "Use System Path Prompts",
55 description: "Use native OS dialogs for 'Open' and 'Save As'",
56 field: Box::new(SettingField {
57 pick: |settings_content| {
58 &settings_content.workspace.use_system_path_prompts
59 },
60 pick_mut: |settings_content| {
61 &mut settings_content.workspace.use_system_path_prompts
62 },
63 }),
64 metadata: None,
65 files: USER,
66 }),
67 SettingsPageItem::SettingItem(SettingItem {
68 title: "Use System Prompts",
69 description: "Use native OS dialogs for confirmations",
70 field: Box::new(SettingField {
71 pick: |settings_content| &settings_content.workspace.use_system_prompts,
72 pick_mut: |settings_content| {
73 &mut settings_content.workspace.use_system_prompts
74 },
75 }),
76 metadata: None,
77 files: USER,
78 }),
79 SettingsPageItem::SettingItem(SettingItem {
80 title: "Redact Private Values",
81 description: "Hide the values of variables in private files",
82 field: Box::new(SettingField {
83 pick: |settings_content| &settings_content.editor.redact_private_values,
84 pick_mut: |settings_content| {
85 &mut settings_content.editor.redact_private_values
86 },
87 }),
88 metadata: None,
89 files: USER,
90 }),
91 SettingsPageItem::SettingItem(SettingItem {
92 title: "Private Files",
93 description: "Globs to match against file paths to determine if a file is private",
94 field: Box::new(
95 SettingField {
96 pick: |settings_content| {
97 &settings_content.project.worktree.private_files
98 },
99 pick_mut: |settings_content| {
100 &mut settings_content.project.worktree.private_files
101 },
102 }
103 .unimplemented(),
104 ),
105 metadata: None,
106 files: USER,
107 }),
108 SettingsPageItem::SectionHeader("Workspace Restoration"),
109 SettingsPageItem::SettingItem(SettingItem {
110 title: "Restore Unsaved Buffers",
111 description: "Whether or not to restore unsaved buffers on restart",
112 field: Box::new(SettingField {
113 pick: |settings_content| match settings_content.session.as_ref() {
114 Some(session) => &session.restore_unsaved_buffers,
115 None => &None,
116 },
117 pick_mut: |settings_content| {
118 &mut settings_content
119 .session
120 .get_or_insert_default()
121 .restore_unsaved_buffers
122 },
123 }),
124 metadata: None,
125 files: USER,
126 }),
127 SettingsPageItem::SettingItem(SettingItem {
128 title: "Restore On Startup",
129 description: "What to restore from the previous session when opening Zed",
130 field: Box::new(SettingField {
131 pick: |settings_content| &settings_content.workspace.restore_on_startup,
132 pick_mut: |settings_content| {
133 &mut settings_content.workspace.restore_on_startup
134 },
135 }),
136 metadata: None,
137 files: USER,
138 }),
139 SettingsPageItem::SectionHeader("Scoped Settings"),
140 SettingsPageItem::SettingItem(SettingItem {
141 // todo(settings_ui): Implement another setting item type that just shows an edit in settings.json
142 files: USER,
143 title: "Preview Channel",
144 description: "Which settings should be activated only in Preview build of Zed",
145 field: Box::new(
146 SettingField {
147 pick: |settings_content| &settings_content.workspace.use_system_prompts,
148 pick_mut: |settings_content| {
149 &mut settings_content.workspace.use_system_prompts
150 },
151 }
152 .unimplemented(),
153 ),
154 metadata: None,
155 }),
156 SettingsPageItem::SettingItem(SettingItem {
157 files: USER,
158 title: "Settings Profiles",
159 description: "Any number of settings profiles that are temporarily applied on top of your existing user settings",
160 field: Box::new(
161 SettingField {
162 pick: |settings_content| &settings_content.workspace.use_system_prompts,
163 pick_mut: |settings_content| {
164 &mut settings_content.workspace.use_system_prompts
165 },
166 }
167 .unimplemented(),
168 ),
169 metadata: None,
170 }),
171 SettingsPageItem::SectionHeader("Privacy"),
172 SettingsPageItem::SettingItem(SettingItem {
173 title: "Telemetry Diagnostics",
174 description: "Send debug information like crash reports",
175 field: Box::new(SettingField {
176 pick: |settings_content| {
177 if let Some(telemetry) = &settings_content.telemetry {
178 &telemetry.diagnostics
179 } else {
180 &None
181 }
182 },
183 pick_mut: |settings_content| {
184 &mut settings_content
185 .telemetry
186 .get_or_insert_default()
187 .diagnostics
188 },
189 }),
190 metadata: None,
191 files: USER,
192 }),
193 SettingsPageItem::SettingItem(SettingItem {
194 title: "Telemetry Metrics",
195 description: "Send anonymized usage data like what languages you're using Zed with",
196 field: Box::new(SettingField {
197 pick: |settings_content| {
198 if let Some(telemetry) = &settings_content.telemetry {
199 &telemetry.metrics
200 } else {
201 &None
202 }
203 },
204 pick_mut: |settings_content| {
205 &mut settings_content.telemetry.get_or_insert_default().metrics
206 },
207 }),
208 metadata: None,
209 files: USER,
210 }),
211 SettingsPageItem::SectionHeader("Auto Update"),
212 SettingsPageItem::SettingItem(SettingItem {
213 title: "Auto Update",
214 description: "Whether or not to automatically check for updates",
215 field: Box::new(SettingField {
216 pick: |settings_content| &settings_content.auto_update,
217 pick_mut: |settings_content| &mut settings_content.auto_update,
218 }),
219 metadata: None,
220 files: USER,
221 }),
222 ],
223 },
224 SettingsPage {
225 title: "Appearance",
226 items: vec![
227 SettingsPageItem::SectionHeader("Theme"),
228 // todo(settings_ui): Figure out how we want to add these
229 SettingsPageItem::SettingItem(SettingItem {
230 files: USER,
231 title: "Theme Mode",
232 description: "How to select the theme",
233 field: Box::new(
234 SettingField {
235 pick: |settings_content| &settings_content.theme.theme,
236 pick_mut: |settings_content| &mut settings_content.theme.theme,
237 }
238 .unimplemented(),
239 ),
240 metadata: None,
241 }),
242 SettingsPageItem::SettingItem(SettingItem {
243 files: USER,
244 title: "Icon Theme",
245 // todo(settings_ui)
246 // This description is misleading because the icon theme is used in more places than the file explorer)
247 description: "Choose the icon theme for file explorer",
248 field: Box::new(
249 SettingField {
250 pick: |settings_content| &settings_content.theme.icon_theme,
251 pick_mut: |settings_content| &mut settings_content.theme.icon_theme,
252 }
253 .unimplemented(),
254 ),
255 metadata: None,
256 }),
257 SettingsPageItem::SectionHeader("Buffer Font"),
258 SettingsPageItem::SettingItem(SettingItem {
259 title: "Font Family",
260 description: "Font family for editor text",
261 field: Box::new(SettingField {
262 pick: |settings_content| &settings_content.theme.buffer_font_family,
263 pick_mut: |settings_content| &mut settings_content.theme.buffer_font_family,
264 }),
265 metadata: None,
266 files: USER,
267 }),
268 SettingsPageItem::SettingItem(SettingItem {
269 title: "Font Size",
270 description: "Font size for editor text",
271 field: Box::new(SettingField {
272 pick: |settings_content| &settings_content.theme.buffer_font_size,
273 pick_mut: |settings_content| &mut settings_content.theme.buffer_font_size,
274 }),
275 metadata: None,
276 files: USER,
277 }),
278 SettingsPageItem::SettingItem(SettingItem {
279 title: "Font Weight",
280 description: "Font weight for editor text (100-900)",
281 field: Box::new(SettingField {
282 pick: |settings_content| &settings_content.theme.buffer_font_weight,
283 pick_mut: |settings_content| &mut settings_content.theme.buffer_font_weight,
284 }),
285 metadata: None,
286 files: USER,
287 }),
288 // todo(settings_ui): This needs custom ui
289 SettingsPageItem::SettingItem(SettingItem {
290 files: USER,
291 title: "Line Height",
292 description: "Line height for editor text",
293 field: Box::new(
294 SettingField {
295 pick: |settings_content| &settings_content.theme.buffer_line_height,
296 pick_mut: |settings_content| {
297 &mut settings_content.theme.buffer_line_height
298 },
299 }
300 .unimplemented(),
301 ),
302 metadata: None,
303 }),
304 SettingsPageItem::SettingItem(SettingItem {
305 files: USER,
306 title: "Font Features",
307 description: "The OpenType features to enable for rendering in text buffers.",
308 field: Box::new(
309 SettingField {
310 pick: |settings_content| &settings_content.theme.buffer_font_features,
311 pick_mut: |settings_content| {
312 &mut settings_content.theme.buffer_font_features
313 },
314 }
315 .unimplemented(),
316 ),
317 metadata: None,
318 }),
319 SettingsPageItem::SettingItem(SettingItem {
320 files: USER,
321 title: "Font Fallbacks",
322 description: "The font fallbacks to use for rendering in text buffers.",
323 field: Box::new(
324 SettingField {
325 pick: |settings_content| &settings_content.theme.buffer_font_fallbacks,
326 pick_mut: |settings_content| {
327 &mut settings_content.theme.buffer_font_fallbacks
328 },
329 }
330 .unimplemented(),
331 ),
332 metadata: None,
333 }),
334 SettingsPageItem::SectionHeader("UI Font"),
335 SettingsPageItem::SettingItem(SettingItem {
336 title: "Font Family",
337 description: "Font family for UI elements",
338 field: Box::new(SettingField {
339 pick: |settings_content| &settings_content.theme.ui_font_family,
340 pick_mut: |settings_content| &mut settings_content.theme.ui_font_family,
341 }),
342 metadata: None,
343 files: USER,
344 }),
345 SettingsPageItem::SettingItem(SettingItem {
346 title: "Font Size",
347 description: "Font size for UI elements",
348 field: Box::new(SettingField {
349 pick: |settings_content| &settings_content.theme.ui_font_size,
350 pick_mut: |settings_content| &mut settings_content.theme.ui_font_size,
351 }),
352 metadata: None,
353 files: USER,
354 }),
355 SettingsPageItem::SettingItem(SettingItem {
356 title: "Font Weight",
357 description: "Font weight for UI elements (100-900)",
358 field: Box::new(SettingField {
359 pick: |settings_content| &settings_content.theme.ui_font_weight,
360 pick_mut: |settings_content| &mut settings_content.theme.ui_font_weight,
361 }),
362 metadata: None,
363 files: USER,
364 }),
365 SettingsPageItem::SettingItem(SettingItem {
366 files: USER,
367 title: "Font Features",
368 description: "The OpenType features to enable for rendering in UI elements.",
369 field: Box::new(
370 SettingField {
371 pick: |settings_content| &settings_content.theme.ui_font_features,
372 pick_mut: |settings_content| {
373 &mut settings_content.theme.ui_font_features
374 },
375 }
376 .unimplemented(),
377 ),
378 metadata: None,
379 }),
380 SettingsPageItem::SettingItem(SettingItem {
381 files: USER,
382 title: "Font Fallbacks",
383 description: "The font fallbacks to use for rendering in the UI.",
384 field: Box::new(
385 SettingField {
386 pick: |settings_content| &settings_content.theme.ui_font_fallbacks,
387 pick_mut: |settings_content| {
388 &mut settings_content.theme.ui_font_fallbacks
389 },
390 }
391 .unimplemented(),
392 ),
393 metadata: None,
394 }),
395 SettingsPageItem::SectionHeader("Agent Panel Font"),
396 SettingsPageItem::SettingItem(SettingItem {
397 title: "UI Font Size",
398 description: "Font size for agent response text in the agent panel. Falls back to the regular UI font size.",
399 field: Box::new(SettingField {
400 pick: |settings_content| {
401 if settings_content.theme.agent_ui_font_size.is_some() {
402 &settings_content.theme.agent_ui_font_size
403 } else {
404 &settings_content.theme.ui_font_size
405 }
406 },
407 pick_mut: |settings_content| &mut settings_content.theme.agent_ui_font_size,
408 }),
409 metadata: None,
410 files: USER,
411 }),
412 SettingsPageItem::SettingItem(SettingItem {
413 title: "Buffer Font Size",
414 description: "Font size for user messages text in the agent panel",
415 field: Box::new(SettingField {
416 pick: |settings_content| &settings_content.theme.agent_buffer_font_size,
417 pick_mut: |settings_content| {
418 &mut settings_content.theme.agent_buffer_font_size
419 },
420 }),
421 metadata: None,
422 files: USER,
423 }),
424 SettingsPageItem::SectionHeader("Cursor"),
425 SettingsPageItem::SettingItem(SettingItem {
426 title: "Multi Cursor Modifier",
427 description: "Modifier key for adding multiple cursors",
428 field: Box::new(SettingField {
429 pick: |settings_content| &settings_content.editor.multi_cursor_modifier,
430 pick_mut: |settings_content| {
431 &mut settings_content.editor.multi_cursor_modifier
432 },
433 }),
434 metadata: None,
435 files: USER,
436 }),
437 SettingsPageItem::SettingItem(SettingItem {
438 title: "Cursor Blink",
439 description: "Whether the cursor blinks in the editor",
440 field: Box::new(SettingField {
441 pick: |settings_content| &settings_content.editor.cursor_blink,
442 pick_mut: |settings_content| &mut settings_content.editor.cursor_blink,
443 }),
444 metadata: None,
445 files: USER,
446 }),
447 SettingsPageItem::SettingItem(SettingItem {
448 title: "Cursor Shape",
449 description: "Cursor shape for the editor",
450 field: Box::new(SettingField {
451 pick: |settings_content| &settings_content.editor.cursor_shape,
452 pick_mut: |settings_content| &mut settings_content.editor.cursor_shape,
453 }),
454 metadata: None,
455 files: USER,
456 }),
457 SettingsPageItem::SettingItem(SettingItem {
458 title: "Hide Mouse",
459 description: "When to hide the mouse cursor",
460 field: Box::new(SettingField {
461 pick: |settings_content| &settings_content.editor.hide_mouse,
462 pick_mut: |settings_content| &mut settings_content.editor.hide_mouse,
463 }),
464 metadata: None,
465 files: USER,
466 }),
467 SettingsPageItem::SectionHeader("Highlighting"),
468 SettingsPageItem::SettingItem(SettingItem {
469 title: "Unnecessary Code Fade",
470 description: "How much to fade out unused code (0.0 - 0.9)",
471 field: Box::new(SettingField {
472 pick: |settings_content| &settings_content.theme.unnecessary_code_fade,
473 pick_mut: |settings_content| {
474 &mut settings_content.theme.unnecessary_code_fade
475 },
476 }),
477 metadata: None,
478 files: USER,
479 }),
480 SettingsPageItem::SettingItem(SettingItem {
481 title: "Current Line Highlight",
482 description: "How to highlight the current line",
483 field: Box::new(SettingField {
484 pick: |settings_content| &settings_content.editor.current_line_highlight,
485 pick_mut: |settings_content| {
486 &mut settings_content.editor.current_line_highlight
487 },
488 }),
489 metadata: None,
490 files: USER,
491 }),
492 SettingsPageItem::SettingItem(SettingItem {
493 title: "Selection Highlight",
494 description: "Highlight all occurrences of selected text",
495 field: Box::new(SettingField {
496 pick: |settings_content| &settings_content.editor.selection_highlight,
497 pick_mut: |settings_content| {
498 &mut settings_content.editor.selection_highlight
499 },
500 }),
501 metadata: None,
502 files: USER,
503 }),
504 SettingsPageItem::SettingItem(SettingItem {
505 title: "Rounded Selection",
506 description: "Whether the text selection should have rounded corners",
507 field: Box::new(SettingField {
508 pick: |settings_content| &settings_content.editor.rounded_selection,
509 pick_mut: |settings_content| &mut settings_content.editor.rounded_selection,
510 }),
511 metadata: None,
512 files: USER,
513 }),
514 SettingsPageItem::SettingItem(SettingItem {
515 title: "Minimum Contrast For Highlights",
516 description: "The minimum APCA perceptual contrast to maintain when rendering text over highlight backgrounds",
517 field: Box::new(SettingField {
518 pick: |settings_content| {
519 &settings_content.editor.minimum_contrast_for_highlights
520 },
521 pick_mut: |settings_content| {
522 &mut settings_content.editor.minimum_contrast_for_highlights
523 },
524 }),
525 metadata: None,
526 files: USER,
527 }),
528 SettingsPageItem::SectionHeader("Guides"),
529 SettingsPageItem::SettingItem(SettingItem {
530 title: "Show Wrap Guides",
531 description: "Show wrap guides (vertical rulers)",
532 field: Box::new(SettingField {
533 pick: |settings_content| {
534 &settings_content
535 .project
536 .all_languages
537 .defaults
538 .show_wrap_guides
539 },
540 pick_mut: |settings_content| {
541 &mut settings_content
542 .project
543 .all_languages
544 .defaults
545 .show_wrap_guides
546 },
547 }),
548 metadata: None,
549 files: USER | LOCAL,
550 }),
551 // todo(settings_ui): This needs a custom component
552 SettingsPageItem::SettingItem(SettingItem {
553 title: "Wrap Guides",
554 description: "Character counts at which to show wrap guides",
555 field: Box::new(
556 SettingField {
557 pick: |settings_content| {
558 &settings_content.project.all_languages.defaults.wrap_guides
559 },
560 pick_mut: |settings_content| {
561 &mut settings_content.project.all_languages.defaults.wrap_guides
562 },
563 }
564 .unimplemented(),
565 ),
566 metadata: None,
567 files: USER | LOCAL,
568 }),
569 ],
570 },
571 SettingsPage {
572 title: "Keymap",
573 items: vec![
574 SettingsPageItem::SectionHeader("Base Keymap"),
575 SettingsPageItem::SettingItem(SettingItem {
576 title: "Base Keymap",
577 description: "The name of a base set of key bindings to use",
578 field: Box::new(SettingField {
579 pick: |settings_content| &settings_content.base_keymap,
580 pick_mut: |settings_content| &mut settings_content.base_keymap,
581 }),
582 metadata: Some(Box::new(SettingsFieldMetadata {
583 should_do_titlecase: Some(false),
584 ..Default::default()
585 })),
586 files: USER,
587 }),
588 SettingsPageItem::SectionHeader("Modal Editing"),
589 // todo(settings_ui): Vim/Helix Mode should be apart of one type because it's undefined
590 // behavior to have them both enabled at the same time
591 SettingsPageItem::SettingItem(SettingItem {
592 title: "Vim Mode",
593 description: "Enable vim modes and key bindings",
594 field: Box::new(SettingField {
595 pick: |settings_content| &settings_content.vim_mode,
596 pick_mut: |settings_content| &mut settings_content.vim_mode,
597 }),
598 metadata: None,
599 files: USER,
600 }),
601 SettingsPageItem::SettingItem(SettingItem {
602 title: "Helix Mode",
603 description: "Enable helix modes and key bindings",
604 field: Box::new(SettingField {
605 pick: |settings_content| &settings_content.helix_mode,
606 pick_mut: |settings_content| &mut settings_content.helix_mode,
607 }),
608 metadata: None,
609 files: USER,
610 }),
611 ],
612 },
613 SettingsPage {
614 title: "Editor",
615 items: {
616 let mut items = vec![
617 SettingsPageItem::SectionHeader("Auto Save"),
618 SettingsPageItem::SettingItem(SettingItem {
619 title: "Auto Save Mode",
620 description: "When to Auto Save Buffer Changes",
621 field: Box::new(
622 SettingField {
623 pick: |settings_content| &settings_content.workspace.autosave,
624 pick_mut: |settings_content| {
625 &mut settings_content.workspace.autosave
626 },
627 }
628 .unimplemented(),
629 ),
630 metadata: None,
631 files: USER,
632 }),
633 SettingsPageItem::SectionHeader("Multibuffer"),
634 SettingsPageItem::SettingItem(SettingItem {
635 title: "Double Click In Multibuffer",
636 description: "What to do when multibuffer is double-clicked in some of its excerpts",
637 field: Box::new(SettingField {
638 pick: |settings_content| {
639 &settings_content.editor.double_click_in_multibuffer
640 },
641 pick_mut: |settings_content| {
642 &mut settings_content.editor.double_click_in_multibuffer
643 },
644 }),
645 metadata: None,
646 files: USER,
647 }),
648 SettingsPageItem::SettingItem(SettingItem {
649 title: "Expand Excerpt Lines",
650 description: "How many lines to expand the multibuffer excerpts by default",
651 field: Box::new(SettingField {
652 pick: |settings_content| &settings_content.editor.expand_excerpt_lines,
653 pick_mut: |settings_content| {
654 &mut settings_content.editor.expand_excerpt_lines
655 },
656 }),
657 metadata: None,
658 files: USER,
659 }),
660 SettingsPageItem::SettingItem(SettingItem {
661 title: "Excerpt Context Lines",
662 description: "How many lines of context to provide in multibuffer excerpts by default",
663 field: Box::new(SettingField {
664 pick: |settings_content| &settings_content.editor.excerpt_context_lines,
665 pick_mut: |settings_content| {
666 &mut settings_content.editor.excerpt_context_lines
667 },
668 }),
669 metadata: None,
670 files: USER,
671 }),
672 SettingsPageItem::SettingItem(SettingItem {
673 title: "Expand Outlines With Depth",
674 description: "Default depth to expand outline items in the current file",
675 field: Box::new(SettingField {
676 pick: |settings_content| {
677 if let Some(outline_panel) = &settings_content.outline_panel {
678 &outline_panel.expand_outlines_with_depth
679 } else {
680 &None
681 }
682 },
683 pick_mut: |settings_content| {
684 &mut settings_content
685 .outline_panel
686 .get_or_insert_default()
687 .expand_outlines_with_depth
688 },
689 }),
690 metadata: None,
691 files: USER,
692 }),
693 SettingsPageItem::SectionHeader("Scrolling"),
694 SettingsPageItem::SettingItem(SettingItem {
695 title: "Scroll Beyond Last Line",
696 description: "Whether the editor will scroll beyond the last line",
697 field: Box::new(SettingField {
698 pick: |settings_content| {
699 &settings_content.editor.scroll_beyond_last_line
700 },
701 pick_mut: |settings_content| {
702 &mut settings_content.editor.scroll_beyond_last_line
703 },
704 }),
705 metadata: None,
706 files: USER,
707 }),
708 SettingsPageItem::SettingItem(SettingItem {
709 title: "Vertical Scroll Margin",
710 description: "The number of lines to keep above/below the cursor when auto-scrolling",
711 field: Box::new(SettingField {
712 pick: |settings_content| {
713 &settings_content.editor.vertical_scroll_margin
714 },
715 pick_mut: |settings_content| {
716 &mut settings_content.editor.vertical_scroll_margin
717 },
718 }),
719 metadata: None,
720 files: USER,
721 }),
722 SettingsPageItem::SettingItem(SettingItem {
723 title: "Horizontal Scroll Margin",
724 description: "The number of characters to keep on either side when scrolling with the mouse",
725 field: Box::new(SettingField {
726 pick: |settings_content| {
727 &settings_content.editor.horizontal_scroll_margin
728 },
729 pick_mut: |settings_content| {
730 &mut settings_content.editor.horizontal_scroll_margin
731 },
732 }),
733 metadata: None,
734 files: USER,
735 }),
736 SettingsPageItem::SettingItem(SettingItem {
737 title: "Scroll Sensitivity",
738 description: "Scroll sensitivity multiplier for both horizontal and vertical scrolling",
739 field: Box::new(SettingField {
740 pick: |settings_content| &settings_content.editor.scroll_sensitivity,
741 pick_mut: |settings_content| {
742 &mut settings_content.editor.scroll_sensitivity
743 },
744 }),
745 metadata: None,
746 files: USER,
747 }),
748 SettingsPageItem::SettingItem(SettingItem {
749 title: "Fast Scroll Sensitivity",
750 description: "Fast Scroll sensitivity multiplier for both horizontal and vertical scrolling",
751 field: Box::new(SettingField {
752 pick: |settings_content| {
753 &settings_content.editor.fast_scroll_sensitivity
754 },
755 pick_mut: |settings_content| {
756 &mut settings_content.editor.fast_scroll_sensitivity
757 },
758 }),
759 metadata: None,
760 files: USER,
761 }),
762 SettingsPageItem::SettingItem(SettingItem {
763 title: "Autoscroll On Clicks",
764 description: "Whether to scroll when clicking near the edge of the visible text area",
765 field: Box::new(SettingField {
766 pick: |settings_content| &settings_content.editor.autoscroll_on_clicks,
767 pick_mut: |settings_content| {
768 &mut settings_content.editor.autoscroll_on_clicks
769 },
770 }),
771 metadata: None,
772 files: USER,
773 }),
774 SettingsPageItem::SectionHeader("Signature Help"),
775 SettingsPageItem::SettingItem(SettingItem {
776 title: "Auto Signature Help",
777 description: "Automatically show a signature help pop-up",
778 field: Box::new(SettingField {
779 pick: |settings_content| &settings_content.editor.auto_signature_help,
780 pick_mut: |settings_content| {
781 &mut settings_content.editor.auto_signature_help
782 },
783 }),
784 metadata: None,
785 files: USER,
786 }),
787 SettingsPageItem::SettingItem(SettingItem {
788 title: "Show Signature Help After Edits",
789 description: "Show the signature help pop-up after completions or bracket pairs are inserted",
790 field: Box::new(SettingField {
791 pick: |settings_content| {
792 &settings_content.editor.show_signature_help_after_edits
793 },
794 pick_mut: |settings_content| {
795 &mut settings_content.editor.show_signature_help_after_edits
796 },
797 }),
798 metadata: None,
799 files: USER,
800 }),
801 SettingsPageItem::SettingItem(SettingItem {
802 title: "Snippet Sort Order",
803 description: "Determines how snippets are sorted relative to other completion items",
804 field: Box::new(SettingField {
805 pick: |settings_content| &settings_content.editor.snippet_sort_order,
806 pick_mut: |settings_content| {
807 &mut settings_content.editor.snippet_sort_order
808 },
809 }),
810 metadata: None,
811 files: USER,
812 }),
813 SettingsPageItem::SectionHeader("Hover Popover"),
814 SettingsPageItem::SettingItem(SettingItem {
815 title: "Enabled",
816 description: "Show the informational hover box when moving the mouse over symbols in the editor",
817 field: Box::new(SettingField {
818 pick: |settings_content| &settings_content.editor.hover_popover_enabled,
819 pick_mut: |settings_content| {
820 &mut settings_content.editor.hover_popover_enabled
821 },
822 }),
823 metadata: None,
824 files: USER,
825 }),
826 // todo(settings ui): add units to this number input
827 SettingsPageItem::SettingItem(SettingItem {
828 title: "Delay",
829 description: "Time to wait in milliseconds before showing the informational hover box",
830 field: Box::new(SettingField {
831 pick: |settings_content| &settings_content.editor.hover_popover_delay,
832 pick_mut: |settings_content| {
833 &mut settings_content.editor.hover_popover_delay
834 },
835 }),
836 metadata: None,
837 files: USER,
838 }),
839 SettingsPageItem::SectionHeader("Drag And Drop Selection"),
840 SettingsPageItem::SettingItem(SettingItem {
841 title: "Enabled",
842 description: "Enable drag and drop selection",
843 field: Box::new(SettingField {
844 pick: |settings_content| {
845 if let Some(drag_and_drop) =
846 &settings_content.editor.drag_and_drop_selection
847 {
848 &drag_and_drop.enabled
849 } else {
850 &None
851 }
852 },
853 pick_mut: |settings_content| {
854 &mut settings_content
855 .editor
856 .drag_and_drop_selection
857 .get_or_insert_default()
858 .enabled
859 },
860 }),
861 metadata: None,
862 files: USER,
863 }),
864 SettingsPageItem::SettingItem(SettingItem {
865 title: "Delay",
866 description: "Delay in milliseconds before drag and drop selection starts",
867 field: Box::new(SettingField {
868 pick: |settings_content| {
869 if let Some(drag_and_drop) =
870 &settings_content.editor.drag_and_drop_selection
871 {
872 &drag_and_drop.delay
873 } else {
874 &None
875 }
876 },
877 pick_mut: |settings_content| {
878 &mut settings_content
879 .editor
880 .drag_and_drop_selection
881 .get_or_insert_default()
882 .delay
883 },
884 }),
885 metadata: None,
886 files: USER,
887 }),
888 SettingsPageItem::SectionHeader("Gutter"),
889 SettingsPageItem::SettingItem(SettingItem {
890 title: "Show Line Numbers",
891 description: "Show line numbers in the gutter",
892 field: Box::new(SettingField {
893 pick: |settings_content| {
894 if let Some(gutter) = &settings_content.editor.gutter {
895 &gutter.line_numbers
896 } else {
897 &None
898 }
899 },
900 pick_mut: |settings_content| {
901 &mut settings_content
902 .editor
903 .gutter
904 .get_or_insert_default()
905 .line_numbers
906 },
907 }),
908 metadata: None,
909 files: USER,
910 }),
911 SettingsPageItem::SettingItem(SettingItem {
912 title: "Relative Line Numbers",
913 description: "Whether the line numbers in the editor's gutter are relative or not",
914 field: Box::new(SettingField {
915 pick: |settings_content| &settings_content.editor.relative_line_numbers,
916 pick_mut: |settings_content| {
917 &mut settings_content.editor.relative_line_numbers
918 },
919 }),
920 metadata: None,
921 files: USER,
922 }),
923 SettingsPageItem::SettingItem(SettingItem {
924 title: "Show Runnables",
925 description: "Show runnable buttons in the gutter",
926 field: Box::new(SettingField {
927 pick: |settings_content| {
928 if let Some(gutter) = &settings_content.editor.gutter {
929 &gutter.runnables
930 } else {
931 &None
932 }
933 },
934 pick_mut: |settings_content| {
935 &mut settings_content
936 .editor
937 .gutter
938 .get_or_insert_default()
939 .runnables
940 },
941 }),
942 metadata: None,
943 files: USER,
944 }),
945 SettingsPageItem::SettingItem(SettingItem {
946 title: "Show Breakpoints",
947 description: "Show breakpoints in the gutter",
948 field: Box::new(SettingField {
949 pick: |settings_content| {
950 if let Some(gutter) = &settings_content.editor.gutter {
951 &gutter.breakpoints
952 } else {
953 &None
954 }
955 },
956 pick_mut: |settings_content| {
957 &mut settings_content
958 .editor
959 .gutter
960 .get_or_insert_default()
961 .breakpoints
962 },
963 }),
964 metadata: None,
965 files: USER,
966 }),
967 SettingsPageItem::SettingItem(SettingItem {
968 title: "Show Folds",
969 description: "Show code folding controls in the gutter",
970 field: Box::new(SettingField {
971 pick: |settings_content| {
972 if let Some(gutter) = &settings_content.editor.gutter {
973 &gutter.folds
974 } else {
975 &None
976 }
977 },
978 pick_mut: |settings_content| {
979 &mut settings_content.editor.gutter.get_or_insert_default().folds
980 },
981 }),
982 metadata: None,
983 files: USER,
984 }),
985 SettingsPageItem::SettingItem(SettingItem {
986 title: "Min Line Number Digits",
987 description: "Minimum number of characters to reserve space for in the gutter",
988 field: Box::new(SettingField {
989 pick: |settings_content| {
990 if let Some(gutter) = &settings_content.editor.gutter {
991 &gutter.min_line_number_digits
992 } else {
993 &None
994 }
995 },
996 pick_mut: |settings_content| {
997 &mut settings_content
998 .editor
999 .gutter
1000 .get_or_insert_default()
1001 .min_line_number_digits
1002 },
1003 }),
1004 metadata: None,
1005 files: USER,
1006 }),
1007 SettingsPageItem::SettingItem(SettingItem {
1008 title: "Inline Code Actions",
1009 description: "Show code action button at start of buffer line",
1010 field: Box::new(SettingField {
1011 pick: |settings_content| &settings_content.editor.inline_code_actions,
1012 pick_mut: |settings_content| {
1013 &mut settings_content.editor.inline_code_actions
1014 },
1015 }),
1016 metadata: None,
1017 files: USER,
1018 }),
1019 SettingsPageItem::SectionHeader("Scrollbar"),
1020 SettingsPageItem::SettingItem(SettingItem {
1021 title: "Show",
1022 description: "When to show the scrollbar in the editor",
1023 field: Box::new(SettingField {
1024 pick: |settings_content| {
1025 if let Some(scrollbar) = &settings_content.editor.scrollbar {
1026 &scrollbar.show
1027 } else {
1028 &None
1029 }
1030 },
1031 pick_mut: |settings_content| {
1032 &mut settings_content
1033 .editor
1034 .scrollbar
1035 .get_or_insert_default()
1036 .show
1037 },
1038 }),
1039 metadata: None,
1040 files: USER,
1041 }),
1042 SettingsPageItem::SettingItem(SettingItem {
1043 title: "Cursors",
1044 description: "Show cursor positions in the scrollbar",
1045 field: Box::new(SettingField {
1046 pick: |settings_content| {
1047 if let Some(scrollbar) = &settings_content.editor.scrollbar {
1048 &scrollbar.cursors
1049 } else {
1050 &None
1051 }
1052 },
1053 pick_mut: |settings_content| {
1054 &mut settings_content
1055 .editor
1056 .scrollbar
1057 .get_or_insert_default()
1058 .cursors
1059 },
1060 }),
1061 metadata: None,
1062 files: USER,
1063 }),
1064 SettingsPageItem::SettingItem(SettingItem {
1065 title: "Git Diff",
1066 description: "Show git diff indicators in the scrollbar",
1067 field: Box::new(SettingField {
1068 pick: |settings_content| {
1069 if let Some(scrollbar) = &settings_content.editor.scrollbar {
1070 &scrollbar.git_diff
1071 } else {
1072 &None
1073 }
1074 },
1075 pick_mut: |settings_content| {
1076 &mut settings_content
1077 .editor
1078 .scrollbar
1079 .get_or_insert_default()
1080 .git_diff
1081 },
1082 }),
1083 metadata: None,
1084 files: USER,
1085 }),
1086 SettingsPageItem::SettingItem(SettingItem {
1087 title: "Search Results",
1088 description: "Show buffer search result indicators in the scrollbar",
1089 field: Box::new(SettingField {
1090 pick: |settings_content| {
1091 if let Some(scrollbar) = &settings_content.editor.scrollbar {
1092 &scrollbar.search_results
1093 } else {
1094 &None
1095 }
1096 },
1097 pick_mut: |settings_content| {
1098 &mut settings_content
1099 .editor
1100 .scrollbar
1101 .get_or_insert_default()
1102 .search_results
1103 },
1104 }),
1105 metadata: None,
1106 files: USER,
1107 }),
1108 SettingsPageItem::SettingItem(SettingItem {
1109 title: "Selected Text",
1110 description: "Show selected text occurrences in the scrollbar",
1111 field: Box::new(SettingField {
1112 pick: |settings_content| {
1113 if let Some(scrollbar) = &settings_content.editor.scrollbar {
1114 &scrollbar.selected_text
1115 } else {
1116 &None
1117 }
1118 },
1119 pick_mut: |settings_content| {
1120 &mut settings_content
1121 .editor
1122 .scrollbar
1123 .get_or_insert_default()
1124 .selected_text
1125 },
1126 }),
1127 metadata: None,
1128 files: USER,
1129 }),
1130 SettingsPageItem::SettingItem(SettingItem {
1131 title: "Selected Symbol",
1132 description: "Show selected symbol occurrences in the scrollbar",
1133 field: Box::new(SettingField {
1134 pick: |settings_content| {
1135 if let Some(scrollbar) = &settings_content.editor.scrollbar {
1136 &scrollbar.selected_symbol
1137 } else {
1138 &None
1139 }
1140 },
1141 pick_mut: |settings_content| {
1142 &mut settings_content
1143 .editor
1144 .scrollbar
1145 .get_or_insert_default()
1146 .selected_symbol
1147 },
1148 }),
1149 metadata: None,
1150 files: USER,
1151 }),
1152 SettingsPageItem::SettingItem(SettingItem {
1153 title: "Diagnostics",
1154 description: "Which diagnostic indicators to show in the scrollbar",
1155 field: Box::new(SettingField {
1156 pick: |settings_content| {
1157 if let Some(scrollbar) = &settings_content.editor.scrollbar {
1158 &scrollbar.diagnostics
1159 } else {
1160 &None
1161 }
1162 },
1163 pick_mut: |settings_content| {
1164 &mut settings_content
1165 .editor
1166 .scrollbar
1167 .get_or_insert_default()
1168 .diagnostics
1169 },
1170 }),
1171 metadata: None,
1172 files: USER,
1173 }),
1174 SettingsPageItem::SettingItem(SettingItem {
1175 title: "Horizontal Scrollbar",
1176 description: "When false, forcefully disables the horizontal scrollbar",
1177 field: Box::new(SettingField {
1178 pick: |settings_content| {
1179 if let Some(scrollbar) = &settings_content.editor.scrollbar {
1180 if let Some(axes) = &scrollbar.axes {
1181 &axes.horizontal
1182 } else {
1183 &None
1184 }
1185 } else {
1186 &None
1187 }
1188 },
1189 pick_mut: |settings_content| {
1190 &mut settings_content
1191 .editor
1192 .scrollbar
1193 .get_or_insert_default()
1194 .axes
1195 .get_or_insert_default()
1196 .horizontal
1197 },
1198 }),
1199 metadata: None,
1200 files: USER,
1201 }),
1202 SettingsPageItem::SettingItem(SettingItem {
1203 title: "Vertical Scrollbar",
1204 description: "When false, forcefully disables the vertical scrollbar",
1205 field: Box::new(SettingField {
1206 pick: |settings_content| {
1207 if let Some(scrollbar) = &settings_content.editor.scrollbar {
1208 if let Some(axes) = &scrollbar.axes {
1209 &axes.vertical
1210 } else {
1211 &None
1212 }
1213 } else {
1214 &None
1215 }
1216 },
1217 pick_mut: |settings_content| {
1218 &mut settings_content
1219 .editor
1220 .scrollbar
1221 .get_or_insert_default()
1222 .axes
1223 .get_or_insert_default()
1224 .vertical
1225 },
1226 }),
1227 metadata: None,
1228 files: USER,
1229 }),
1230 SettingsPageItem::SectionHeader("Minimap"),
1231 SettingsPageItem::SettingItem(SettingItem {
1232 title: "Show",
1233 description: "When to show the minimap in the editor",
1234 field: Box::new(SettingField {
1235 pick: |settings_content| {
1236 if let Some(minimap) = &settings_content.editor.minimap {
1237 &minimap.show
1238 } else {
1239 &None
1240 }
1241 },
1242 pick_mut: |settings_content| {
1243 &mut settings_content.editor.minimap.get_or_insert_default().show
1244 },
1245 }),
1246 metadata: None,
1247 files: USER,
1248 }),
1249 SettingsPageItem::SettingItem(SettingItem {
1250 title: "Display In",
1251 description: "Where to show the minimap in the editor",
1252 field: Box::new(SettingField {
1253 pick: |settings_content| {
1254 if let Some(minimap) = &settings_content.editor.minimap {
1255 &minimap.display_in
1256 } else {
1257 &None
1258 }
1259 },
1260 pick_mut: |settings_content| {
1261 &mut settings_content
1262 .editor
1263 .minimap
1264 .get_or_insert_default()
1265 .display_in
1266 },
1267 }),
1268 metadata: None,
1269 files: USER,
1270 }),
1271 SettingsPageItem::SettingItem(SettingItem {
1272 title: "Thumb",
1273 description: "When to show the minimap thumb",
1274 field: Box::new(SettingField {
1275 pick: |settings_content| {
1276 if let Some(minimap) = &settings_content.editor.minimap {
1277 &minimap.thumb
1278 } else {
1279 &None
1280 }
1281 },
1282 pick_mut: |settings_content| {
1283 &mut settings_content
1284 .editor
1285 .minimap
1286 .get_or_insert_default()
1287 .thumb
1288 },
1289 }),
1290 metadata: None,
1291 files: USER,
1292 }),
1293 SettingsPageItem::SettingItem(SettingItem {
1294 title: "Thumb Border",
1295 description: "Border style for the minimap's scrollbar thumb",
1296 field: Box::new(SettingField {
1297 pick: |settings_content| {
1298 if let Some(minimap) = &settings_content.editor.minimap {
1299 &minimap.thumb_border
1300 } else {
1301 &None
1302 }
1303 },
1304 pick_mut: |settings_content| {
1305 &mut settings_content
1306 .editor
1307 .minimap
1308 .get_or_insert_default()
1309 .thumb_border
1310 },
1311 }),
1312 metadata: None,
1313 files: USER,
1314 }),
1315 SettingsPageItem::SettingItem(SettingItem {
1316 title: "Current Line Highlight",
1317 description: "How to highlight the current line in the minimap",
1318 field: Box::new(SettingField {
1319 pick: |settings_content| {
1320 if let Some(minimap) = &settings_content.editor.minimap
1321 && minimap.current_line_highlight.is_some()
1322 {
1323 &minimap.current_line_highlight
1324 } else {
1325 &settings_content.editor.current_line_highlight
1326 }
1327 },
1328 pick_mut: |settings_content| {
1329 &mut settings_content
1330 .editor
1331 .minimap
1332 .get_or_insert_default()
1333 .current_line_highlight
1334 },
1335 }),
1336 metadata: None,
1337 files: USER,
1338 }),
1339 SettingsPageItem::SettingItem(SettingItem {
1340 title: "Max Width Columns",
1341 description: "Maximum number of columns to display in the minimap",
1342 field: Box::new(SettingField {
1343 pick: |settings_content| {
1344 if let Some(minimap) = &settings_content.editor.minimap {
1345 &minimap.max_width_columns
1346 } else {
1347 &None
1348 }
1349 },
1350 pick_mut: |settings_content| {
1351 &mut settings_content
1352 .editor
1353 .minimap
1354 .get_or_insert_default()
1355 .max_width_columns
1356 },
1357 }),
1358 metadata: None,
1359 files: USER,
1360 }),
1361 SettingsPageItem::SectionHeader("Toolbar"),
1362 SettingsPageItem::SettingItem(SettingItem {
1363 title: "Breadcrumbs",
1364 description: "Show breadcrumbs",
1365 field: Box::new(SettingField {
1366 pick: |settings_content| {
1367 if let Some(toolbar) = &settings_content.editor.toolbar {
1368 &toolbar.breadcrumbs
1369 } else {
1370 &None
1371 }
1372 },
1373 pick_mut: |settings_content| {
1374 &mut settings_content
1375 .editor
1376 .toolbar
1377 .get_or_insert_default()
1378 .breadcrumbs
1379 },
1380 }),
1381 metadata: None,
1382 files: USER,
1383 }),
1384 SettingsPageItem::SettingItem(SettingItem {
1385 title: "Quick Actions",
1386 description: "Show quick action buttons (e.g., search, selection, editor controls, etc.)",
1387 field: Box::new(SettingField {
1388 pick: |settings_content| {
1389 if let Some(toolbar) = &settings_content.editor.toolbar {
1390 &toolbar.quick_actions
1391 } else {
1392 &None
1393 }
1394 },
1395 pick_mut: |settings_content| {
1396 &mut settings_content
1397 .editor
1398 .toolbar
1399 .get_or_insert_default()
1400 .quick_actions
1401 },
1402 }),
1403 metadata: None,
1404 files: USER,
1405 }),
1406 SettingsPageItem::SettingItem(SettingItem {
1407 title: "Selections Menu",
1408 description: "Show the selections menu in the editor toolbar",
1409 field: Box::new(SettingField {
1410 pick: |settings_content| {
1411 if let Some(toolbar) = &settings_content.editor.toolbar {
1412 &toolbar.selections_menu
1413 } else {
1414 &None
1415 }
1416 },
1417 pick_mut: |settings_content| {
1418 &mut settings_content
1419 .editor
1420 .toolbar
1421 .get_or_insert_default()
1422 .selections_menu
1423 },
1424 }),
1425 metadata: None,
1426 files: USER,
1427 }),
1428 SettingsPageItem::SettingItem(SettingItem {
1429 title: "Agent Review",
1430 description: "Show agent review buttons in the editor toolbar",
1431 field: Box::new(SettingField {
1432 pick: |settings_content| {
1433 if let Some(toolbar) = &settings_content.editor.toolbar {
1434 &toolbar.agent_review
1435 } else {
1436 &None
1437 }
1438 },
1439 pick_mut: |settings_content| {
1440 &mut settings_content
1441 .editor
1442 .toolbar
1443 .get_or_insert_default()
1444 .agent_review
1445 },
1446 }),
1447 metadata: None,
1448 files: USER,
1449 }),
1450 SettingsPageItem::SettingItem(SettingItem {
1451 title: "Code Actions",
1452 description: "Show code action buttons in the editor toolbar",
1453 field: Box::new(SettingField {
1454 pick: |settings_content| {
1455 if let Some(toolbar) = &settings_content.editor.toolbar {
1456 &toolbar.code_actions
1457 } else {
1458 &None
1459 }
1460 },
1461 pick_mut: |settings_content| {
1462 &mut settings_content
1463 .editor
1464 .toolbar
1465 .get_or_insert_default()
1466 .code_actions
1467 },
1468 }),
1469 metadata: None,
1470 files: USER,
1471 }),
1472 ];
1473 items.extend(language_settings_data());
1474 items
1475 },
1476 },
1477 SettingsPage {
1478 title: "Languages & Tools",
1479 items: {
1480 let mut items = vec![];
1481 items.extend(non_editor_language_settings_data());
1482 items.extend([
1483 SettingsPageItem::SectionHeader("File Types"),
1484 SettingsPageItem::SettingItem(SettingItem {
1485 title: "File Type Associations",
1486 description: "A Mapping from Languages to files and file extensions that should be treated as that language",
1487 field: Box::new(
1488 SettingField {
1489 pick: |settings_content| {
1490 &settings_content.project.all_languages.file_types
1491 },
1492 pick_mut: |settings_content| {
1493 &mut settings_content.project.all_languages.file_types
1494 },
1495 }
1496 .unimplemented(),
1497 ),
1498 metadata: None,
1499 files: USER | LOCAL,
1500 }),
1501 ]);
1502
1503 items.extend([
1504 SettingsPageItem::SectionHeader("Diagnostics"),
1505 SettingsPageItem::SettingItem(SettingItem {
1506 title: "Max Severity",
1507 description: "Which level to use to filter out diagnostics displayed in the editor",
1508 field: Box::new(SettingField {
1509 pick: |settings_content| &settings_content.editor.diagnostics_max_severity,
1510 pick_mut: |settings_content| {
1511 &mut settings_content.editor.diagnostics_max_severity
1512 },
1513 }),
1514 metadata: None,
1515 files: USER,
1516 }),
1517 SettingsPageItem::SettingItem(SettingItem {
1518 title: "Include Warnings",
1519 description: "Whether to show warnings or not by default",
1520 field: Box::new(SettingField {
1521 pick: |settings_content| {
1522 if let Some(diagnostics) = &settings_content.diagnostics {
1523 &diagnostics.include_warnings
1524 } else {
1525 &None
1526 }
1527 },
1528 pick_mut: |settings_content| {
1529 &mut settings_content
1530 .diagnostics
1531 .get_or_insert_default()
1532 .include_warnings
1533 },
1534 }),
1535 metadata: None,
1536 files: USER,
1537 }),
1538 SettingsPageItem::SectionHeader("Inline Diagnostics"),
1539 SettingsPageItem::SettingItem(SettingItem {
1540 title: "Enabled",
1541 description: "Whether to show diagnostics inline or not",
1542 field: Box::new(SettingField {
1543 pick: |settings_content| {
1544 if let Some(diagnostics) = &settings_content.diagnostics {
1545 if let Some(inline) = &diagnostics.inline {
1546 &inline.enabled
1547 } else {
1548 &None
1549 }
1550 } else {
1551 &None
1552 }
1553 },
1554 pick_mut: |settings_content| {
1555 &mut settings_content
1556 .diagnostics
1557 .get_or_insert_default()
1558 .inline
1559 .get_or_insert_default()
1560 .enabled
1561 },
1562 }),
1563 metadata: None,
1564 files: USER,
1565 }),
1566 SettingsPageItem::SettingItem(SettingItem {
1567 title: "Update Debounce",
1568 description: "The delay in milliseconds to show inline diagnostics after the last diagnostic update",
1569 field: Box::new(SettingField {
1570 pick: |settings_content| {
1571 if let Some(diagnostics) = &settings_content.diagnostics {
1572 if let Some(inline) = &diagnostics.inline {
1573 &inline.update_debounce_ms
1574 } else {
1575 &None
1576 }
1577 } else {
1578 &None
1579 }
1580 },
1581 pick_mut: |settings_content| {
1582 &mut settings_content
1583 .diagnostics
1584 .get_or_insert_default()
1585 .inline
1586 .get_or_insert_default()
1587 .update_debounce_ms
1588 },
1589 }),
1590 metadata: None,
1591 files: USER,
1592 }),
1593 SettingsPageItem::SettingItem(SettingItem {
1594 title: "Padding",
1595 description: "The amount of padding between the end of the source line and the start of the inline diagnostic",
1596 field: Box::new(SettingField {
1597 pick: |settings_content| {
1598 if let Some(diagnostics) = &settings_content.diagnostics {
1599 if let Some(inline) = &diagnostics.inline {
1600 &inline.padding
1601 } else {
1602 &None
1603 }
1604 } else {
1605 &None
1606 }
1607 },
1608 pick_mut: |settings_content| {
1609 &mut settings_content
1610 .diagnostics
1611 .get_or_insert_default()
1612 .inline
1613 .get_or_insert_default()
1614 .padding
1615 },
1616 }),
1617 metadata: None,
1618 files: USER,
1619 }),
1620 SettingsPageItem::SettingItem(SettingItem {
1621 title: "Minimum Column",
1622 description: "The minimum column at which to display inline diagnostics",
1623 field: Box::new(SettingField {
1624 pick: |settings_content| {
1625 if let Some(diagnostics) = &settings_content.diagnostics {
1626 if let Some(inline) = &diagnostics.inline {
1627 &inline.min_column
1628 } else {
1629 &None
1630 }
1631 } else {
1632 &None
1633 }
1634 },
1635 pick_mut: |settings_content| {
1636 &mut settings_content
1637 .diagnostics
1638 .get_or_insert_default()
1639 .inline
1640 .get_or_insert_default()
1641 .min_column
1642 },
1643 }),
1644 metadata: None,
1645 files: USER,
1646 }),
1647 SettingsPageItem::SectionHeader("LSP Pull Diagnostics"),
1648 SettingsPageItem::SettingItem(SettingItem {
1649 title: "Enabled",
1650 description: "Whether to pull for language server-powered diagnostics or not",
1651 field: Box::new(SettingField {
1652 pick: |settings_content| {
1653 if let Some(diagnostics) = &settings_content.diagnostics {
1654 if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics {
1655 &lsp_pull.enabled
1656 } else {
1657 &None
1658 }
1659 } else {
1660 &None
1661 }
1662 },
1663 pick_mut: |settings_content| {
1664 &mut settings_content
1665 .diagnostics
1666 .get_or_insert_default()
1667 .lsp_pull_diagnostics
1668 .get_or_insert_default()
1669 .enabled
1670 },
1671 }),
1672 metadata: None,
1673 files: USER,
1674 }),
1675 // todo(settings_ui): Needs unit
1676 SettingsPageItem::SettingItem(SettingItem {
1677 title: "Debounce",
1678 description: "Minimum time to wait before pulling diagnostics from the language server(s)",
1679 field: Box::new(SettingField {
1680 pick: |settings_content| {
1681 if let Some(diagnostics) = &settings_content.diagnostics {
1682 if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics {
1683 &lsp_pull.debounce_ms
1684 } else {
1685 &None
1686 }
1687 } else {
1688 &None
1689 }
1690 },
1691 pick_mut: |settings_content| {
1692 &mut settings_content
1693 .diagnostics
1694 .get_or_insert_default()
1695 .lsp_pull_diagnostics
1696 .get_or_insert_default()
1697 .debounce_ms
1698 },
1699 }),
1700 metadata: None,
1701 files: USER,
1702 }),
1703 SettingsPageItem::SectionHeader("LSP Highlights"),
1704 SettingsPageItem::SettingItem(SettingItem {
1705 title: "Debounce",
1706 description: "The debounce delay before querying highlights from the language",
1707 field: Box::new(SettingField {
1708 pick: |settings_content| &settings_content.editor.lsp_highlight_debounce,
1709 pick_mut: |settings_content| {
1710 &mut settings_content.editor.lsp_highlight_debounce
1711 },
1712 }),
1713 metadata: None,
1714 files: USER,
1715 }),
1716 ]);
1717
1718 // todo(settings_ui): Refresh on extension (un)/installed
1719 // Note that `crates/json_schema_store` solves the same problem, there is probably a way to unify the two
1720 items.push(SettingsPageItem::SectionHeader(LANGUAGES_SECTION_HEADER));
1721 items.extend(all_language_names(cx).into_iter().map(|language_name| {
1722 SettingsPageItem::SubPageLink(SubPageLink {
1723 title: language_name,
1724 files: USER | LOCAL,
1725 render: Arc::new(|this, window, cx| {
1726 this.render_sub_page_items(
1727 language_settings_data()
1728 .iter()
1729 .chain(non_editor_language_settings_data().iter())
1730 .enumerate(),
1731 None,
1732 window,
1733 cx,
1734 )
1735 .into_any_element()
1736 }),
1737 })
1738 }));
1739 items
1740 },
1741 },
1742 SettingsPage {
1743 title: "Search & Files",
1744 items: vec![
1745 SettingsPageItem::SectionHeader("Search"),
1746 SettingsPageItem::SettingItem(SettingItem {
1747 title: "Whole Word",
1748 description: "Search for whole words by default",
1749 field: Box::new(SettingField {
1750 pick: |settings_content| {
1751 if let Some(search) = &settings_content.editor.search {
1752 &search.whole_word
1753 } else {
1754 &None
1755 }
1756 },
1757 pick_mut: |settings_content| {
1758 &mut settings_content
1759 .editor
1760 .search
1761 .get_or_insert_default()
1762 .whole_word
1763 },
1764 }),
1765 metadata: None,
1766 files: USER,
1767 }),
1768 SettingsPageItem::SettingItem(SettingItem {
1769 title: "Case Sensitive",
1770 description: "Search case-sensitively by default",
1771 field: Box::new(SettingField {
1772 pick: |settings_content| {
1773 if let Some(search) = &settings_content.editor.search {
1774 &search.case_sensitive
1775 } else {
1776 &None
1777 }
1778 },
1779 pick_mut: |settings_content| {
1780 &mut settings_content
1781 .editor
1782 .search
1783 .get_or_insert_default()
1784 .case_sensitive
1785 },
1786 }),
1787 metadata: None,
1788 files: USER,
1789 }),
1790 SettingsPageItem::SettingItem(SettingItem {
1791 title: "Use Smartcase Search",
1792 description: "Whether to automatically enable case-sensitive search based on the search query",
1793 field: Box::new(SettingField {
1794 pick: |settings_content| &settings_content.editor.use_smartcase_search,
1795 pick_mut: |settings_content| {
1796 &mut settings_content.editor.use_smartcase_search
1797 },
1798 }),
1799 metadata: None,
1800 files: USER,
1801 }),
1802 SettingsPageItem::SettingItem(SettingItem {
1803 title: "Include Ignored",
1804 description: "Include ignored files in search results by default",
1805 field: Box::new(SettingField {
1806 pick: |settings_content| {
1807 if let Some(search) = &settings_content.editor.search {
1808 &search.include_ignored
1809 } else {
1810 &None
1811 }
1812 },
1813 pick_mut: |settings_content| {
1814 &mut settings_content
1815 .editor
1816 .search
1817 .get_or_insert_default()
1818 .include_ignored
1819 },
1820 }),
1821 metadata: None,
1822 files: USER,
1823 }),
1824 SettingsPageItem::SettingItem(SettingItem {
1825 title: "Regex",
1826 description: "Use regex search by default",
1827 field: Box::new(SettingField {
1828 pick: |settings_content| {
1829 if let Some(search) = &settings_content.editor.search {
1830 &search.regex
1831 } else {
1832 &None
1833 }
1834 },
1835 pick_mut: |settings_content| {
1836 &mut settings_content.editor.search.get_or_insert_default().regex
1837 },
1838 }),
1839 metadata: None,
1840 files: USER,
1841 }),
1842 SettingsPageItem::SettingItem(SettingItem {
1843 title: "Search Wrap",
1844 description: "Whether the editor search results will loop",
1845 field: Box::new(SettingField {
1846 pick: |settings_content| &settings_content.editor.search_wrap,
1847 pick_mut: |settings_content| &mut settings_content.editor.search_wrap,
1848 }),
1849 metadata: None,
1850 files: USER,
1851 }),
1852 SettingsPageItem::SettingItem(SettingItem {
1853 title: "Seed Search Query From Cursor",
1854 description: "When to populate a new search's query based on the text under the cursor",
1855 field: Box::new(SettingField {
1856 pick: |settings_content| {
1857 &settings_content.editor.seed_search_query_from_cursor
1858 },
1859 pick_mut: |settings_content| {
1860 &mut settings_content.editor.seed_search_query_from_cursor
1861 },
1862 }),
1863 metadata: None,
1864 files: USER,
1865 }),
1866 SettingsPageItem::SectionHeader("File Finder"),
1867 // todo: null by default
1868 SettingsPageItem::SettingItem(SettingItem {
1869 title: "Include Ignored in Search",
1870 description: "Use gitignored files when searching",
1871 field: Box::new(
1872 SettingField {
1873 pick: |settings_content| {
1874 if let Some(file_finder) = &settings_content.file_finder {
1875 &file_finder.include_ignored
1876 } else {
1877 &None
1878 }
1879 },
1880 pick_mut: |settings_content| {
1881 &mut settings_content
1882 .file_finder
1883 .get_or_insert_default()
1884 .include_ignored
1885 },
1886 }
1887 .unimplemented(),
1888 ),
1889 metadata: None,
1890 files: USER,
1891 }),
1892 SettingsPageItem::SettingItem(SettingItem {
1893 title: "File Icons",
1894 description: "Show file icons in the file finder",
1895 field: Box::new(SettingField {
1896 pick: |settings_content| {
1897 if let Some(file_finder) = &settings_content.file_finder {
1898 &file_finder.file_icons
1899 } else {
1900 &None
1901 }
1902 },
1903 pick_mut: |settings_content| {
1904 &mut settings_content
1905 .file_finder
1906 .get_or_insert_default()
1907 .file_icons
1908 },
1909 }),
1910 metadata: None,
1911 files: USER,
1912 }),
1913 SettingsPageItem::SettingItem(SettingItem {
1914 title: "Modal Max Width",
1915 description: "Determines how much space the file finder can take up in relation to the available window width",
1916 field: Box::new(SettingField {
1917 pick: |settings_content| {
1918 if let Some(file_finder) = &settings_content.file_finder {
1919 &file_finder.modal_max_width
1920 } else {
1921 &None
1922 }
1923 },
1924 pick_mut: |settings_content| {
1925 &mut settings_content
1926 .file_finder
1927 .get_or_insert_default()
1928 .modal_max_width
1929 },
1930 }),
1931 metadata: None,
1932 files: USER,
1933 }),
1934 SettingsPageItem::SettingItem(SettingItem {
1935 title: "Skip Focus For Active In Search",
1936 description: "Whether the file finder should skip focus for the active file in search results",
1937 field: Box::new(SettingField {
1938 pick: |settings_content| {
1939 if let Some(file_finder) = &settings_content.file_finder {
1940 &file_finder.skip_focus_for_active_in_search
1941 } else {
1942 &None
1943 }
1944 },
1945 pick_mut: |settings_content| {
1946 &mut settings_content
1947 .file_finder
1948 .get_or_insert_default()
1949 .skip_focus_for_active_in_search
1950 },
1951 }),
1952 metadata: None,
1953 files: USER,
1954 }),
1955 SettingsPageItem::SettingItem(SettingItem {
1956 title: "Git Status",
1957 description: "Show the git status in the file finder",
1958 field: Box::new(SettingField {
1959 pick: |settings_content| {
1960 if let Some(file_finder) = &settings_content.file_finder {
1961 &file_finder.git_status
1962 } else {
1963 &None
1964 }
1965 },
1966 pick_mut: |settings_content| {
1967 &mut settings_content
1968 .file_finder
1969 .get_or_insert_default()
1970 .git_status
1971 },
1972 }),
1973 metadata: None,
1974 files: USER,
1975 }),
1976 SettingsPageItem::SectionHeader("File Scan"),
1977 SettingsPageItem::SettingItem(SettingItem {
1978 title: "File Scan Exclusions",
1979 description: "Files or globs of files that will be excluded by Zed entirely. They will be skipped during file scans, file searches, and not be displayed in the project file tree. Takes precedence over \"File Scan Inclusions\"",
1980 field: Box::new(
1981 SettingField {
1982 pick: |settings_content| {
1983 &settings_content.project.worktree.file_scan_exclusions
1984 },
1985 pick_mut: |settings_content| {
1986 &mut settings_content.project.worktree.file_scan_exclusions
1987 },
1988 }
1989 .unimplemented(),
1990 ),
1991 metadata: None,
1992 files: USER,
1993 }),
1994 SettingsPageItem::SettingItem(SettingItem {
1995 title: "File Scan Inclusions",
1996 description: "Files or globs of files that will be included by Zed, even when ignored by git. This is useful for files that are not tracked by git, but are still important to your project. Note that globs that are overly broad can slow down Zed's file scanning. \"File Scan Exclusions\" takes precedence over these inclusions",
1997 field: Box::new(
1998 SettingField {
1999 pick: |settings_content| {
2000 &settings_content.project.worktree.file_scan_exclusions
2001 },
2002 pick_mut: |settings_content| {
2003 &mut settings_content.project.worktree.file_scan_exclusions
2004 },
2005 }
2006 .unimplemented(),
2007 ),
2008 metadata: None,
2009 files: USER,
2010 }),
2011 SettingsPageItem::SettingItem(SettingItem {
2012 title: "Restore File State",
2013 description: "Restore previous file state when reopening",
2014 field: Box::new(SettingField {
2015 pick: |settings_content| &settings_content.workspace.restore_on_file_reopen,
2016 pick_mut: |settings_content| {
2017 &mut settings_content.workspace.restore_on_file_reopen
2018 },
2019 }),
2020 metadata: None,
2021 files: USER,
2022 }),
2023 SettingsPageItem::SettingItem(SettingItem {
2024 title: "Close on File Delete",
2025 description: "Automatically close files that have been deleted",
2026 field: Box::new(SettingField {
2027 pick: |settings_content| &settings_content.workspace.close_on_file_delete,
2028 pick_mut: |settings_content| {
2029 &mut settings_content.workspace.close_on_file_delete
2030 },
2031 }),
2032 metadata: None,
2033 files: USER,
2034 }),
2035 ],
2036 },
2037 SettingsPage {
2038 title: "Window & Layout",
2039 items: vec![
2040 SettingsPageItem::SectionHeader("Status Bar"),
2041 SettingsPageItem::SettingItem(SettingItem {
2042 title: "Project Panel Button",
2043 description: "Show the project panel button in the status bar",
2044 field: Box::new(SettingField {
2045 pick: |settings_content| {
2046 if let Some(project_panel) = &settings_content.project_panel {
2047 &project_panel.button
2048 } else {
2049 &None
2050 }
2051 },
2052 pick_mut: |settings_content| {
2053 &mut settings_content
2054 .project_panel
2055 .get_or_insert_default()
2056 .button
2057 },
2058 }),
2059 metadata: None,
2060 files: USER,
2061 }),
2062 SettingsPageItem::SettingItem(SettingItem {
2063 title: "Active Language Button",
2064 description: "Show the active language button in the status bar",
2065 field: Box::new(SettingField {
2066 pick: |settings_content| {
2067 if let Some(status_bar) = &settings_content.status_bar {
2068 &status_bar.active_language_button
2069 } else {
2070 &None
2071 }
2072 },
2073 pick_mut: |settings_content| {
2074 &mut settings_content
2075 .status_bar
2076 .get_or_insert_default()
2077 .active_language_button
2078 },
2079 }),
2080 metadata: None,
2081 files: USER,
2082 }),
2083 SettingsPageItem::SettingItem(SettingItem {
2084 title: "Cursor Position Button",
2085 description: "Show the cursor position button in the status bar",
2086 field: Box::new(SettingField {
2087 pick: |settings_content| {
2088 if let Some(status_bar) = &settings_content.status_bar {
2089 &status_bar.cursor_position_button
2090 } else {
2091 &None
2092 }
2093 },
2094 pick_mut: |settings_content| {
2095 &mut settings_content
2096 .status_bar
2097 .get_or_insert_default()
2098 .cursor_position_button
2099 },
2100 }),
2101 metadata: None,
2102 files: USER,
2103 }),
2104 SettingsPageItem::SettingItem(SettingItem {
2105 title: "Terminal Button",
2106 description: "Show the terminal button in the status bar",
2107 field: Box::new(SettingField {
2108 pick: |settings_content| {
2109 if let Some(terminal) = &settings_content.terminal {
2110 &terminal.button
2111 } else {
2112 &None
2113 }
2114 },
2115 pick_mut: |settings_content| {
2116 &mut settings_content.terminal.get_or_insert_default().button
2117 },
2118 }),
2119 metadata: None,
2120 files: USER,
2121 }),
2122 SettingsPageItem::SettingItem(SettingItem {
2123 title: "Diagnostics Button",
2124 description: "Show the project diagnostics button in the status bar",
2125 field: Box::new(SettingField {
2126 pick: |settings_content| {
2127 if let Some(diagnostics) = &settings_content.diagnostics {
2128 &diagnostics.button
2129 } else {
2130 &None
2131 }
2132 },
2133 pick_mut: |settings_content| {
2134 &mut settings_content.diagnostics.get_or_insert_default().button
2135 },
2136 }),
2137 metadata: None,
2138 files: USER,
2139 }),
2140 SettingsPageItem::SettingItem(SettingItem {
2141 title: "Project Search Button",
2142 description: "Show the project search button in the status bar",
2143 field: Box::new(SettingField {
2144 pick: |settings_content| {
2145 if let Some(search) = &settings_content.editor.search {
2146 &search.button
2147 } else {
2148 &None
2149 }
2150 },
2151 pick_mut: |settings_content| {
2152 &mut settings_content
2153 .editor
2154 .search
2155 .get_or_insert_default()
2156 .button
2157 },
2158 }),
2159 metadata: None,
2160 files: USER,
2161 }),
2162 SettingsPageItem::SettingItem(SettingItem {
2163 title: "Debugger Button",
2164 description: "Show the debugger button in the status bar",
2165 field: Box::new(SettingField {
2166 pick: |settings_content| {
2167 if let Some(debugger) = &settings_content.debugger {
2168 &debugger.button
2169 } else {
2170 &None
2171 }
2172 },
2173 pick_mut: |settings_content| {
2174 &mut settings_content.debugger.get_or_insert_default().button
2175 },
2176 }),
2177 metadata: None,
2178 files: USER,
2179 }),
2180 SettingsPageItem::SectionHeader("Title Bar"),
2181 SettingsPageItem::SettingItem(SettingItem {
2182 title: "Show Branch Icon",
2183 description: "Show the branch icon beside branch switcher in the titlebar",
2184 field: Box::new(SettingField {
2185 pick: |settings_content| {
2186 if let Some(title_bar) = &settings_content.title_bar {
2187 &title_bar.show_branch_icon
2188 } else {
2189 &None
2190 }
2191 },
2192 pick_mut: |settings_content| {
2193 &mut settings_content
2194 .title_bar
2195 .get_or_insert_default()
2196 .show_branch_icon
2197 },
2198 }),
2199 metadata: None,
2200 files: USER,
2201 }),
2202 SettingsPageItem::SettingItem(SettingItem {
2203 title: "Show Branch Name",
2204 description: "Show the branch name button in the titlebar",
2205 field: Box::new(SettingField {
2206 pick: |settings_content| {
2207 if let Some(title_bar) = &settings_content.title_bar {
2208 &title_bar.show_branch_name
2209 } else {
2210 &None
2211 }
2212 },
2213 pick_mut: |settings_content| {
2214 &mut settings_content
2215 .title_bar
2216 .get_or_insert_default()
2217 .show_branch_name
2218 },
2219 }),
2220 metadata: None,
2221 files: USER,
2222 }),
2223 SettingsPageItem::SettingItem(SettingItem {
2224 title: "Show Project Items",
2225 description: "Show the project host and name in the titlebar",
2226 field: Box::new(SettingField {
2227 pick: |settings_content| {
2228 if let Some(title_bar) = &settings_content.title_bar {
2229 &title_bar.show_project_items
2230 } else {
2231 &None
2232 }
2233 },
2234 pick_mut: |settings_content| {
2235 &mut settings_content
2236 .title_bar
2237 .get_or_insert_default()
2238 .show_project_items
2239 },
2240 }),
2241 metadata: None,
2242 files: USER,
2243 }),
2244 SettingsPageItem::SettingItem(SettingItem {
2245 title: "Show Onboarding Banner",
2246 description: "Show banners announcing new features in the titlebar",
2247 field: Box::new(SettingField {
2248 pick: |settings_content| {
2249 if let Some(title_bar) = &settings_content.title_bar {
2250 &title_bar.show_onboarding_banner
2251 } else {
2252 &None
2253 }
2254 },
2255 pick_mut: |settings_content| {
2256 &mut settings_content
2257 .title_bar
2258 .get_or_insert_default()
2259 .show_onboarding_banner
2260 },
2261 }),
2262 metadata: None,
2263 files: USER,
2264 }),
2265 SettingsPageItem::SettingItem(SettingItem {
2266 title: "Show User Picture",
2267 description: "Show user picture in the titlebar",
2268 field: Box::new(SettingField {
2269 pick: |settings_content| {
2270 if let Some(title_bar) = &settings_content.title_bar {
2271 &title_bar.show_user_picture
2272 } else {
2273 &None
2274 }
2275 },
2276 pick_mut: |settings_content| {
2277 &mut settings_content
2278 .title_bar
2279 .get_or_insert_default()
2280 .show_user_picture
2281 },
2282 }),
2283 metadata: None,
2284 files: USER,
2285 }),
2286 SettingsPageItem::SettingItem(SettingItem {
2287 title: "Show Sign In",
2288 description: "Show the sign in button in the titlebar",
2289 field: Box::new(SettingField {
2290 pick: |settings_content| {
2291 if let Some(title_bar) = &settings_content.title_bar {
2292 &title_bar.show_sign_in
2293 } else {
2294 &None
2295 }
2296 },
2297 pick_mut: |settings_content| {
2298 &mut settings_content
2299 .title_bar
2300 .get_or_insert_default()
2301 .show_sign_in
2302 },
2303 }),
2304 metadata: None,
2305 files: USER,
2306 }),
2307 SettingsPageItem::SettingItem(SettingItem {
2308 title: "Show Menus",
2309 description: "Show the menus in the titlebar",
2310 field: Box::new(SettingField {
2311 pick: |settings_content| {
2312 if let Some(title_bar) = &settings_content.title_bar {
2313 &title_bar.show_menus
2314 } else {
2315 &None
2316 }
2317 },
2318 pick_mut: |settings_content| {
2319 &mut settings_content
2320 .title_bar
2321 .get_or_insert_default()
2322 .show_menus
2323 },
2324 }),
2325 metadata: None,
2326 files: USER,
2327 }),
2328 SettingsPageItem::SectionHeader("Tab Bar"),
2329 SettingsPageItem::SettingItem(SettingItem {
2330 title: "Show Tab Bar",
2331 description: "Show the tab bar in the editor",
2332 field: Box::new(SettingField {
2333 pick: |settings_content| {
2334 if let Some(tab_bar) = &settings_content.tab_bar {
2335 &tab_bar.show
2336 } else {
2337 &None
2338 }
2339 },
2340 pick_mut: |settings_content| {
2341 &mut settings_content.tab_bar.get_or_insert_default().show
2342 },
2343 }),
2344 metadata: None,
2345 files: USER,
2346 }),
2347 SettingsPageItem::SettingItem(SettingItem {
2348 title: "Show Git Status In Tabs",
2349 description: "Show the Git file status on a tab item",
2350 field: Box::new(SettingField {
2351 pick: |settings_content| {
2352 if let Some(tabs) = &settings_content.tabs {
2353 &tabs.git_status
2354 } else {
2355 &None
2356 }
2357 },
2358 pick_mut: |settings_content| {
2359 &mut settings_content.tabs.get_or_insert_default().git_status
2360 },
2361 }),
2362 metadata: None,
2363 files: USER,
2364 }),
2365 SettingsPageItem::SettingItem(SettingItem {
2366 title: "Show File Icons In Tabs",
2367 description: "Show the file icon for a tab",
2368 field: Box::new(SettingField {
2369 pick: |settings_content| {
2370 if let Some(tabs) = &settings_content.tabs {
2371 &tabs.file_icons
2372 } else {
2373 &None
2374 }
2375 },
2376 pick_mut: |settings_content| {
2377 &mut settings_content.tabs.get_or_insert_default().file_icons
2378 },
2379 }),
2380 metadata: None,
2381 files: USER,
2382 }),
2383 SettingsPageItem::SettingItem(SettingItem {
2384 title: "Tab Close Position",
2385 description: "Position of the close button in a tab",
2386 field: Box::new(SettingField {
2387 pick: |settings_content| {
2388 if let Some(tabs) = &settings_content.tabs {
2389 &tabs.close_position
2390 } else {
2391 &None
2392 }
2393 },
2394 pick_mut: |settings_content| {
2395 &mut settings_content.tabs.get_or_insert_default().close_position
2396 },
2397 }),
2398 metadata: None,
2399 files: USER,
2400 }),
2401 SettingsPageItem::SettingItem(SettingItem {
2402 files: USER,
2403 title: "Maximum Tabs",
2404 description: "Maximum open tabs in a pane. Will not close an unsaved tab",
2405 // todo(settings_ui): The default for this value is null and it's use in code
2406 // is complex, so I'm going to come back to this later
2407 field: Box::new(
2408 SettingField {
2409 pick: |settings_content| &settings_content.workspace.max_tabs,
2410 pick_mut: |settings_content| &mut settings_content.workspace.max_tabs,
2411 }
2412 .unimplemented(),
2413 ),
2414 metadata: None,
2415 }),
2416 SettingsPageItem::SettingItem(SettingItem {
2417 title: "Show Navigation History Buttons",
2418 description: "Show the navigation history buttons in the tab bar",
2419 field: Box::new(SettingField {
2420 pick: |settings_content| {
2421 if let Some(tab_bar) = &settings_content.tab_bar {
2422 &tab_bar.show_nav_history_buttons
2423 } else {
2424 &None
2425 }
2426 },
2427 pick_mut: |settings_content| {
2428 &mut settings_content
2429 .tab_bar
2430 .get_or_insert_default()
2431 .show_nav_history_buttons
2432 },
2433 }),
2434 metadata: None,
2435 files: USER,
2436 }),
2437 SettingsPageItem::SectionHeader("Tab Settings"),
2438 SettingsPageItem::SettingItem(SettingItem {
2439 title: "Activate On Close",
2440 description: "What to do after closing the current tab",
2441 field: Box::new(SettingField {
2442 pick: |settings_content| {
2443 if let Some(tabs) = &settings_content.tabs {
2444 &tabs.activate_on_close
2445 } else {
2446 &None
2447 }
2448 },
2449 pick_mut: |settings_content| {
2450 &mut settings_content
2451 .tabs
2452 .get_or_insert_default()
2453 .activate_on_close
2454 },
2455 }),
2456 metadata: None,
2457 files: USER,
2458 }),
2459 SettingsPageItem::SettingItem(SettingItem {
2460 title: "Tab Show Diagnostics",
2461 description: "Which files containing diagnostic errors/warnings to mark in the tabs",
2462 field: Box::new(SettingField {
2463 pick: |settings_content| {
2464 if let Some(tabs) = &settings_content.tabs {
2465 &tabs.show_diagnostics
2466 } else {
2467 &None
2468 }
2469 },
2470 pick_mut: |settings_content| {
2471 &mut settings_content
2472 .tabs
2473 .get_or_insert_default()
2474 .show_diagnostics
2475 },
2476 }),
2477 metadata: None,
2478 files: USER,
2479 }),
2480 SettingsPageItem::SettingItem(SettingItem {
2481 title: "Show Close Button",
2482 description: "Controls the appearance behavior of the tab's close button",
2483 field: Box::new(SettingField {
2484 pick: |settings_content| {
2485 if let Some(tabs) = &settings_content.tabs {
2486 &tabs.show_close_button
2487 } else {
2488 &None
2489 }
2490 },
2491 pick_mut: |settings_content| {
2492 &mut settings_content
2493 .tabs
2494 .get_or_insert_default()
2495 .show_close_button
2496 },
2497 }),
2498 metadata: None,
2499 files: USER,
2500 }),
2501 SettingsPageItem::SectionHeader("Preview Tabs"),
2502 SettingsPageItem::SettingItem(SettingItem {
2503 title: "Preview Tabs Enabled",
2504 description: "Show opened editors as preview tabs",
2505 field: Box::new(SettingField {
2506 pick: |settings_content| {
2507 if let Some(preview_tabs) = &settings_content.preview_tabs {
2508 &preview_tabs.enabled
2509 } else {
2510 &None
2511 }
2512 },
2513 pick_mut: |settings_content| {
2514 &mut settings_content
2515 .preview_tabs
2516 .get_or_insert_default()
2517 .enabled
2518 },
2519 }),
2520 metadata: None,
2521 files: USER,
2522 }),
2523 SettingsPageItem::SettingItem(SettingItem {
2524 title: "Enable Preview From File Finder",
2525 description: "Whether to open tabs in preview mode when selected from the file finder",
2526 field: Box::new(SettingField {
2527 pick: |settings_content| {
2528 if let Some(preview_tabs) = &settings_content.preview_tabs {
2529 &preview_tabs.enable_preview_from_file_finder
2530 } else {
2531 &None
2532 }
2533 },
2534 pick_mut: |settings_content| {
2535 &mut settings_content
2536 .preview_tabs
2537 .get_or_insert_default()
2538 .enable_preview_from_file_finder
2539 },
2540 }),
2541 metadata: None,
2542 files: USER,
2543 }),
2544 SettingsPageItem::SettingItem(SettingItem {
2545 title: "Enable Preview From Code Navigation",
2546 description: "Whether a preview tab gets replaced when code navigation is used to navigate away from the tab",
2547 field: Box::new(SettingField {
2548 pick: |settings_content| {
2549 if let Some(preview_tabs) = &settings_content.preview_tabs {
2550 &preview_tabs.enable_preview_from_code_navigation
2551 } else {
2552 &None
2553 }
2554 },
2555 pick_mut: |settings_content| {
2556 &mut settings_content
2557 .preview_tabs
2558 .get_or_insert_default()
2559 .enable_preview_from_code_navigation
2560 },
2561 }),
2562 metadata: None,
2563 files: USER,
2564 }),
2565 SettingsPageItem::SectionHeader("Layout"),
2566 SettingsPageItem::SettingItem(SettingItem {
2567 title: "Bottom Dock Layout",
2568 description: "Layout mode for the bottom dock",
2569 field: Box::new(SettingField {
2570 pick: |settings_content| &settings_content.workspace.bottom_dock_layout,
2571 pick_mut: |settings_content| {
2572 &mut settings_content.workspace.bottom_dock_layout
2573 },
2574 }),
2575 metadata: None,
2576 files: USER,
2577 }),
2578 SettingsPageItem::SettingItem(SettingItem {
2579 files: USER,
2580 title: "Centered Layout Left Padding",
2581 description: "Left padding for centered layout",
2582 field: Box::new(SettingField {
2583 pick: |settings_content| {
2584 if let Some(centered_layout) =
2585 &settings_content.workspace.centered_layout
2586 {
2587 ¢ered_layout.left_padding
2588 } else {
2589 &None
2590 }
2591 },
2592 pick_mut: |settings_content| {
2593 &mut settings_content
2594 .workspace
2595 .centered_layout
2596 .get_or_insert_default()
2597 .left_padding
2598 },
2599 }),
2600 metadata: None,
2601 }),
2602 SettingsPageItem::SettingItem(SettingItem {
2603 files: USER,
2604 title: "Centered Layout Right Padding",
2605 description: "Right padding for centered layout",
2606 field: Box::new(SettingField {
2607 pick: |settings_content| {
2608 if let Some(centered_layout) =
2609 &settings_content.workspace.centered_layout
2610 {
2611 ¢ered_layout.right_padding
2612 } else {
2613 &None
2614 }
2615 },
2616 pick_mut: |settings_content| {
2617 &mut settings_content
2618 .workspace
2619 .centered_layout
2620 .get_or_insert_default()
2621 .right_padding
2622 },
2623 }),
2624 metadata: None,
2625 }),
2626 SettingsPageItem::SectionHeader("Window"),
2627 // todo(settings_ui): Should we filter by platform?
2628 SettingsPageItem::SettingItem(SettingItem {
2629 title: "Use System Window Tabs",
2630 description: "(macOS only) Whether to allow windows to tab together",
2631 field: Box::new(SettingField {
2632 pick: |settings_content| &settings_content.workspace.use_system_window_tabs,
2633 pick_mut: |settings_content| {
2634 &mut settings_content.workspace.use_system_window_tabs
2635 },
2636 }),
2637 metadata: None,
2638 files: USER,
2639 }),
2640 SettingsPageItem::SectionHeader("Pane Modifiers"),
2641 SettingsPageItem::SettingItem(SettingItem {
2642 title: "Inactive Opacity",
2643 description: "Opacity of inactive panels (0.0 - 1.0)",
2644 field: Box::new(SettingField {
2645 pick: |settings_content| match settings_content
2646 .workspace
2647 .active_pane_modifiers
2648 .as_ref()
2649 {
2650 Some(modifiers) => &modifiers.inactive_opacity,
2651 None => &None,
2652 },
2653 pick_mut: |settings_content| {
2654 &mut settings_content
2655 .workspace
2656 .active_pane_modifiers
2657 .get_or_insert_default()
2658 .inactive_opacity
2659 },
2660 }),
2661 metadata: None,
2662 files: USER,
2663 }),
2664 SettingsPageItem::SettingItem(SettingItem {
2665 title: "Border Size",
2666 description: "Size of the border surrounding the active pane",
2667 field: Box::new(SettingField {
2668 pick: |settings_content| match settings_content
2669 .workspace
2670 .active_pane_modifiers
2671 .as_ref()
2672 {
2673 Some(modifiers) => &modifiers.border_size,
2674 None => &None,
2675 },
2676 pick_mut: |settings_content| {
2677 &mut settings_content
2678 .workspace
2679 .active_pane_modifiers
2680 .get_or_insert_default()
2681 .border_size
2682 },
2683 }),
2684 metadata: None,
2685 files: USER,
2686 }),
2687 SettingsPageItem::SettingItem(SettingItem {
2688 title: "Zoomed Padding",
2689 description: "Show padding for zoomed panes",
2690 field: Box::new(SettingField {
2691 pick: |settings_content| &settings_content.workspace.zoomed_padding,
2692 pick_mut: |settings_content| &mut settings_content.workspace.zoomed_padding,
2693 }),
2694 metadata: None,
2695 files: USER,
2696 }),
2697 SettingsPageItem::SectionHeader("Pane Split Direction"),
2698 SettingsPageItem::SettingItem(SettingItem {
2699 title: "Vertical Split Direction",
2700 description: "Direction to split vertically",
2701 field: Box::new(SettingField {
2702 pick: |settings_content| {
2703 &settings_content.workspace.pane_split_direction_vertical
2704 },
2705 pick_mut: |settings_content| {
2706 &mut settings_content.workspace.pane_split_direction_vertical
2707 },
2708 }),
2709 metadata: None,
2710 files: USER,
2711 }),
2712 SettingsPageItem::SettingItem(SettingItem {
2713 title: "Horizontal Split Direction",
2714 description: "Direction to split horizontally",
2715 field: Box::new(SettingField {
2716 pick: |settings_content| {
2717 &settings_content.workspace.pane_split_direction_horizontal
2718 },
2719 pick_mut: |settings_content| {
2720 &mut settings_content.workspace.pane_split_direction_horizontal
2721 },
2722 }),
2723 metadata: None,
2724 files: USER,
2725 }),
2726 ],
2727 },
2728 SettingsPage {
2729 title: "Panels",
2730 items: vec![
2731 SettingsPageItem::SectionHeader("Project Panel"),
2732 SettingsPageItem::SettingItem(SettingItem {
2733 title: "Project Panel Dock",
2734 description: "Where to dock the project panel",
2735 field: Box::new(SettingField {
2736 pick: |settings_content| {
2737 if let Some(project_panel) = &settings_content.project_panel {
2738 &project_panel.dock
2739 } else {
2740 &None
2741 }
2742 },
2743 pick_mut: |settings_content| {
2744 &mut settings_content.project_panel.get_or_insert_default().dock
2745 },
2746 }),
2747 metadata: None,
2748 files: USER,
2749 }),
2750 SettingsPageItem::SettingItem(SettingItem {
2751 title: "Project Panel Default Width",
2752 description: "Default width of the project panel in pixels",
2753 field: Box::new(SettingField {
2754 pick: |settings_content| {
2755 if let Some(project_panel) = &settings_content.project_panel {
2756 &project_panel.default_width
2757 } else {
2758 &None
2759 }
2760 },
2761 pick_mut: |settings_content| {
2762 &mut settings_content
2763 .project_panel
2764 .get_or_insert_default()
2765 .default_width
2766 },
2767 }),
2768 metadata: None,
2769 files: USER,
2770 }),
2771 SettingsPageItem::SettingItem(SettingItem {
2772 title: "Hide .gitignore",
2773 description: "Whether to hide the gitignore entries in the project panel",
2774 field: Box::new(SettingField {
2775 pick: |settings_content| {
2776 if let Some(project_panel) = &settings_content.project_panel {
2777 &project_panel.hide_gitignore
2778 } else {
2779 &None
2780 }
2781 },
2782 pick_mut: |settings_content| {
2783 &mut settings_content
2784 .project_panel
2785 .get_or_insert_default()
2786 .hide_gitignore
2787 },
2788 }),
2789 metadata: None,
2790 files: USER,
2791 }),
2792 SettingsPageItem::SettingItem(SettingItem {
2793 title: "Entry Spacing",
2794 description: "Spacing between worktree entries in the project panel",
2795 field: Box::new(SettingField {
2796 pick: |settings_content| {
2797 if let Some(project_panel) = &settings_content.project_panel {
2798 &project_panel.entry_spacing
2799 } else {
2800 &None
2801 }
2802 },
2803 pick_mut: |settings_content| {
2804 &mut settings_content
2805 .project_panel
2806 .get_or_insert_default()
2807 .entry_spacing
2808 },
2809 }),
2810 metadata: None,
2811 files: USER,
2812 }),
2813 SettingsPageItem::SettingItem(SettingItem {
2814 title: "File Icons",
2815 description: "Show file icons in the project panel",
2816 field: Box::new(SettingField {
2817 pick: |settings_content| {
2818 if let Some(project_panel) = &settings_content.project_panel {
2819 &project_panel.file_icons
2820 } else {
2821 &None
2822 }
2823 },
2824 pick_mut: |settings_content| {
2825 &mut settings_content
2826 .project_panel
2827 .get_or_insert_default()
2828 .file_icons
2829 },
2830 }),
2831 metadata: None,
2832 files: USER,
2833 }),
2834 SettingsPageItem::SettingItem(SettingItem {
2835 title: "Folder Icons",
2836 description: "Whether to show folder icons or chevrons for directories in the project panel",
2837 field: Box::new(SettingField {
2838 pick: |settings_content| {
2839 if let Some(project_panel) = &settings_content.project_panel {
2840 &project_panel.folder_icons
2841 } else {
2842 &None
2843 }
2844 },
2845 pick_mut: |settings_content| {
2846 &mut settings_content
2847 .project_panel
2848 .get_or_insert_default()
2849 .folder_icons
2850 },
2851 }),
2852 metadata: None,
2853 files: USER,
2854 }),
2855 SettingsPageItem::SettingItem(SettingItem {
2856 title: "Git Status",
2857 description: "Show the git status in the project panel",
2858 field: Box::new(SettingField {
2859 pick: |settings_content| {
2860 if let Some(project_panel) = &settings_content.project_panel {
2861 &project_panel.git_status
2862 } else {
2863 &None
2864 }
2865 },
2866 pick_mut: |settings_content| {
2867 &mut settings_content
2868 .project_panel
2869 .get_or_insert_default()
2870 .git_status
2871 },
2872 }),
2873 metadata: None,
2874 files: USER,
2875 }),
2876 SettingsPageItem::SettingItem(SettingItem {
2877 title: "Indent Size",
2878 description: "Amount of indentation for nested items",
2879 field: Box::new(SettingField {
2880 pick: |settings_content| {
2881 if let Some(project_panel) = &settings_content.project_panel {
2882 &project_panel.indent_size
2883 } else {
2884 &None
2885 }
2886 },
2887 pick_mut: |settings_content| {
2888 &mut settings_content
2889 .project_panel
2890 .get_or_insert_default()
2891 .indent_size
2892 },
2893 }),
2894 metadata: None,
2895 files: USER,
2896 }),
2897 SettingsPageItem::SettingItem(SettingItem {
2898 title: "Auto Reveal Entries",
2899 description: "Whether to reveal entries in the project panel automatically when a corresponding project entry becomes active",
2900 field: Box::new(SettingField {
2901 pick: |settings_content| {
2902 if let Some(project_panel) = &settings_content.project_panel {
2903 &project_panel.auto_reveal_entries
2904 } else {
2905 &None
2906 }
2907 },
2908 pick_mut: |settings_content| {
2909 &mut settings_content
2910 .project_panel
2911 .get_or_insert_default()
2912 .auto_reveal_entries
2913 },
2914 }),
2915 metadata: None,
2916 files: USER,
2917 }),
2918 SettingsPageItem::SettingItem(SettingItem {
2919 title: "Starts Open",
2920 description: "Whether the project panel should open on startup",
2921 field: Box::new(SettingField {
2922 pick: |settings_content| {
2923 if let Some(project_panel) = &settings_content.project_panel {
2924 &project_panel.starts_open
2925 } else {
2926 &None
2927 }
2928 },
2929 pick_mut: |settings_content| {
2930 &mut settings_content
2931 .project_panel
2932 .get_or_insert_default()
2933 .starts_open
2934 },
2935 }),
2936 metadata: None,
2937 files: USER,
2938 }),
2939 SettingsPageItem::SettingItem(SettingItem {
2940 title: "Auto Fold Directories",
2941 description: "Whether to fold directories automatically and show compact folders when a directory has only one subdirectory inside",
2942 field: Box::new(SettingField {
2943 pick: |settings_content| {
2944 if let Some(project_panel) = &settings_content.project_panel {
2945 &project_panel.auto_fold_dirs
2946 } else {
2947 &None
2948 }
2949 },
2950 pick_mut: |settings_content| {
2951 &mut settings_content
2952 .project_panel
2953 .get_or_insert_default()
2954 .auto_fold_dirs
2955 },
2956 }),
2957 metadata: None,
2958 files: USER,
2959 }),
2960 SettingsPageItem::SettingItem(SettingItem {
2961 title: "Scrollbar Show",
2962 description: "Show the scrollbar in the project panel",
2963 field: Box::new(SettingField {
2964 pick: |settings_content| {
2965 if let Some(project_panel) = &settings_content.project_panel
2966 && let Some(scrollbar) = &project_panel.scrollbar
2967 && scrollbar.show.is_some()
2968 {
2969 &scrollbar.show
2970 } else if let Some(scrollbar) = &settings_content.editor.scrollbar {
2971 &scrollbar.show
2972 } else {
2973 &None
2974 }
2975 },
2976 pick_mut: |settings_content| {
2977 &mut settings_content
2978 .project_panel
2979 .get_or_insert_default()
2980 .scrollbar
2981 .get_or_insert_default()
2982 .show
2983 },
2984 }),
2985 metadata: None,
2986 files: USER,
2987 }),
2988 SettingsPageItem::SettingItem(SettingItem {
2989 title: "Show Diagnostics",
2990 description: "Which files containing diagnostic errors/warnings to mark in the project panel",
2991 field: Box::new(SettingField {
2992 pick: |settings_content| {
2993 if let Some(project_panel) = &settings_content.project_panel {
2994 &project_panel.show_diagnostics
2995 } else {
2996 &None
2997 }
2998 },
2999 pick_mut: |settings_content| {
3000 &mut settings_content
3001 .project_panel
3002 .get_or_insert_default()
3003 .show_diagnostics
3004 },
3005 }),
3006 metadata: None,
3007 files: USER,
3008 }),
3009 SettingsPageItem::SettingItem(SettingItem {
3010 title: "Sticky Scroll",
3011 description: "Whether to stick parent directories at top of the project panel",
3012 field: Box::new(SettingField {
3013 pick: |settings_content| {
3014 if let Some(project_panel) = &settings_content.project_panel {
3015 &project_panel.sticky_scroll
3016 } else {
3017 &None
3018 }
3019 },
3020 pick_mut: |settings_content| {
3021 &mut settings_content
3022 .project_panel
3023 .get_or_insert_default()
3024 .sticky_scroll
3025 },
3026 }),
3027 metadata: None,
3028 files: USER,
3029 }),
3030 SettingsPageItem::SettingItem(SettingItem {
3031 files: USER,
3032 title: "Indent Guides Show",
3033 description: "Show indent guides in the project panel",
3034 field: Box::new(
3035 SettingField {
3036 pick: |settings_content| {
3037 if let Some(project_panel) = &settings_content.project_panel {
3038 if let Some(indent_guides) = &project_panel.indent_guides {
3039 &indent_guides.show
3040 } else {
3041 &None
3042 }
3043 } else {
3044 &None
3045 }
3046 },
3047 pick_mut: |settings_content| {
3048 &mut settings_content
3049 .project_panel
3050 .get_or_insert_default()
3051 .indent_guides
3052 .get_or_insert_default()
3053 .show
3054 },
3055 }
3056 .unimplemented(),
3057 ),
3058 metadata: None,
3059 }),
3060 SettingsPageItem::SettingItem(SettingItem {
3061 title: "Drag and Drop",
3062 description: "Whether to enable drag-and-drop operations in the project panel",
3063 field: Box::new(SettingField {
3064 pick: |settings_content| {
3065 if let Some(project_panel) = &settings_content.project_panel {
3066 &project_panel.drag_and_drop
3067 } else {
3068 &None
3069 }
3070 },
3071 pick_mut: |settings_content| {
3072 &mut settings_content
3073 .project_panel
3074 .get_or_insert_default()
3075 .drag_and_drop
3076 },
3077 }),
3078 metadata: None,
3079 files: USER,
3080 }),
3081 SettingsPageItem::SettingItem(SettingItem {
3082 title: "Hide Root",
3083 description: "Whether to hide the root entry when only one folder is open in the window",
3084 field: Box::new(SettingField {
3085 pick: |settings_content| {
3086 if let Some(project_panel) = &settings_content.project_panel {
3087 &project_panel.hide_root
3088 } else {
3089 &None
3090 }
3091 },
3092 pick_mut: |settings_content| {
3093 &mut settings_content
3094 .project_panel
3095 .get_or_insert_default()
3096 .hide_root
3097 },
3098 }),
3099 metadata: None,
3100 files: USER,
3101 }),
3102 SettingsPageItem::SettingItem(SettingItem {
3103 title: "Hide Hidden",
3104 description: "Whether to hide the hidden entries in the project panel",
3105 field: Box::new(SettingField {
3106 pick: |settings_content| {
3107 if let Some(project_panel) = &settings_content.project_panel {
3108 &project_panel.hide_hidden
3109 } else {
3110 &None
3111 }
3112 },
3113 pick_mut: |settings_content| {
3114 &mut settings_content
3115 .project_panel
3116 .get_or_insert_default()
3117 .hide_hidden
3118 },
3119 }),
3120 metadata: None,
3121 files: USER,
3122 }),
3123 SettingsPageItem::SettingItem(SettingItem {
3124 title: "Open File on Paste",
3125 description: "Whether to automatically open files when pasting them in the project panel",
3126 field: Box::new(SettingField {
3127 pick: |settings_content| {
3128 if let Some(project_panel) = &settings_content.project_panel {
3129 &project_panel.open_file_on_paste
3130 } else {
3131 &None
3132 }
3133 },
3134 pick_mut: |settings_content| {
3135 &mut settings_content
3136 .project_panel
3137 .get_or_insert_default()
3138 .open_file_on_paste
3139 },
3140 }),
3141 metadata: None,
3142 files: USER,
3143 }),
3144 SettingsPageItem::SectionHeader("Terminal Panel"),
3145 SettingsPageItem::SettingItem(SettingItem {
3146 title: "Terminal Dock",
3147 description: "Where to dock the terminal panel",
3148 field: Box::new(SettingField {
3149 pick: |settings_content| {
3150 if let Some(terminal) = &settings_content.terminal {
3151 &terminal.dock
3152 } else {
3153 &None
3154 }
3155 },
3156 pick_mut: |settings_content| {
3157 &mut settings_content.terminal.get_or_insert_default().dock
3158 },
3159 }),
3160 metadata: None,
3161 files: USER,
3162 }),
3163 SettingsPageItem::SectionHeader("Outline Panel"),
3164 SettingsPageItem::SettingItem(SettingItem {
3165 title: "Outline Panel Button",
3166 description: "Show the outline panel button in the status bar",
3167 field: Box::new(SettingField {
3168 pick: |settings_content| {
3169 if let Some(outline_panel) = &settings_content.outline_panel {
3170 &outline_panel.button
3171 } else {
3172 &None
3173 }
3174 },
3175 pick_mut: |settings_content| {
3176 &mut settings_content
3177 .outline_panel
3178 .get_or_insert_default()
3179 .button
3180 },
3181 }),
3182 metadata: None,
3183 files: USER,
3184 }),
3185 SettingsPageItem::SettingItem(SettingItem {
3186 title: "Outline Panel Dock",
3187 description: "Where to dock the outline panel",
3188 field: Box::new(SettingField {
3189 pick: |settings_content| {
3190 if let Some(outline_panel) = &settings_content.outline_panel {
3191 &outline_panel.dock
3192 } else {
3193 &None
3194 }
3195 },
3196 pick_mut: |settings_content| {
3197 &mut settings_content.outline_panel.get_or_insert_default().dock
3198 },
3199 }),
3200 metadata: None,
3201 files: USER,
3202 }),
3203 SettingsPageItem::SettingItem(SettingItem {
3204 title: "Outline Panel Default Width",
3205 description: "Default width of the outline panel in pixels",
3206 field: Box::new(SettingField {
3207 pick: |settings_content| {
3208 if let Some(outline_panel) = &settings_content.outline_panel {
3209 &outline_panel.default_width
3210 } else {
3211 &None
3212 }
3213 },
3214 pick_mut: |settings_content| {
3215 &mut settings_content
3216 .outline_panel
3217 .get_or_insert_default()
3218 .default_width
3219 },
3220 }),
3221 metadata: None,
3222 files: USER,
3223 }),
3224 SettingsPageItem::SettingItem(SettingItem {
3225 title: "File Icons",
3226 description: "Show file icons in the outline panel",
3227 field: Box::new(SettingField {
3228 pick: |settings_content| {
3229 if let Some(outline_panel) = &settings_content.outline_panel {
3230 &outline_panel.file_icons
3231 } else {
3232 &None
3233 }
3234 },
3235 pick_mut: |settings_content| {
3236 &mut settings_content
3237 .outline_panel
3238 .get_or_insert_default()
3239 .file_icons
3240 },
3241 }),
3242 metadata: None,
3243 files: USER,
3244 }),
3245 SettingsPageItem::SettingItem(SettingItem {
3246 title: "Folder Icons",
3247 description: "Whether to show folder icons or chevrons for directories in the outline panel",
3248 field: Box::new(SettingField {
3249 pick: |settings_content| {
3250 if let Some(outline_panel) = &settings_content.outline_panel {
3251 &outline_panel.folder_icons
3252 } else {
3253 &None
3254 }
3255 },
3256 pick_mut: |settings_content| {
3257 &mut settings_content
3258 .outline_panel
3259 .get_or_insert_default()
3260 .folder_icons
3261 },
3262 }),
3263 metadata: None,
3264 files: USER,
3265 }),
3266 SettingsPageItem::SettingItem(SettingItem {
3267 title: "Git Status",
3268 description: "Show the git status in the outline panel",
3269 field: Box::new(SettingField {
3270 pick: |settings_content| {
3271 if let Some(outline_panel) = &settings_content.outline_panel {
3272 &outline_panel.git_status
3273 } else {
3274 &None
3275 }
3276 },
3277 pick_mut: |settings_content| {
3278 &mut settings_content
3279 .outline_panel
3280 .get_or_insert_default()
3281 .git_status
3282 },
3283 }),
3284 metadata: None,
3285 files: USER,
3286 }),
3287 SettingsPageItem::SettingItem(SettingItem {
3288 title: "Indent Size",
3289 description: "Amount of indentation for nested items",
3290 field: Box::new(SettingField {
3291 pick: |settings_content| {
3292 if let Some(outline_panel) = &settings_content.outline_panel {
3293 &outline_panel.indent_size
3294 } else {
3295 &None
3296 }
3297 },
3298 pick_mut: |settings_content| {
3299 &mut settings_content
3300 .outline_panel
3301 .get_or_insert_default()
3302 .indent_size
3303 },
3304 }),
3305 metadata: None,
3306 files: USER,
3307 }),
3308 SettingsPageItem::SettingItem(SettingItem {
3309 title: "Auto Reveal Entries",
3310 description: "Whether to reveal when a corresponding outline entry becomes active",
3311 field: Box::new(SettingField {
3312 pick: |settings_content| {
3313 if let Some(outline_panel) = &settings_content.outline_panel {
3314 &outline_panel.auto_reveal_entries
3315 } else {
3316 &None
3317 }
3318 },
3319 pick_mut: |settings_content| {
3320 &mut settings_content
3321 .outline_panel
3322 .get_or_insert_default()
3323 .auto_reveal_entries
3324 },
3325 }),
3326 metadata: None,
3327 files: USER,
3328 }),
3329 SettingsPageItem::SettingItem(SettingItem {
3330 title: "Auto Fold Directories",
3331 description: "Whether to fold directories automatically when a directory contains only one subdirectory",
3332 field: Box::new(SettingField {
3333 pick: |settings_content| {
3334 if let Some(outline_panel) = &settings_content.outline_panel {
3335 &outline_panel.auto_fold_dirs
3336 } else {
3337 &None
3338 }
3339 },
3340 pick_mut: |settings_content| {
3341 &mut settings_content
3342 .outline_panel
3343 .get_or_insert_default()
3344 .auto_fold_dirs
3345 },
3346 }),
3347 metadata: None,
3348 files: USER,
3349 }),
3350 SettingsPageItem::SettingItem(SettingItem {
3351 files: USER,
3352 title: "Indent Guides Show",
3353 description: "When to show indent guides in the outline panel",
3354 field: Box::new(
3355 SettingField {
3356 pick: |settings_content| {
3357 if let Some(outline_panel) = &settings_content.outline_panel {
3358 if let Some(indent_guides) = &outline_panel.indent_guides {
3359 &indent_guides.show
3360 } else {
3361 &None
3362 }
3363 } else {
3364 &None
3365 }
3366 },
3367 pick_mut: |settings_content| {
3368 &mut settings_content
3369 .outline_panel
3370 .get_or_insert_default()
3371 .indent_guides
3372 .get_or_insert_default()
3373 .show
3374 },
3375 }
3376 .unimplemented(),
3377 ),
3378 metadata: None,
3379 }),
3380 SettingsPageItem::SectionHeader("Git Panel"),
3381 SettingsPageItem::SettingItem(SettingItem {
3382 title: "Git Panel Button",
3383 description: "Show the Git panel button in the status bar",
3384 field: Box::new(SettingField {
3385 pick: |settings_content| {
3386 if let Some(git_panel) = &settings_content.git_panel {
3387 &git_panel.button
3388 } else {
3389 &None
3390 }
3391 },
3392 pick_mut: |settings_content| {
3393 &mut settings_content.git_panel.get_or_insert_default().button
3394 },
3395 }),
3396 metadata: None,
3397 files: USER,
3398 }),
3399 SettingsPageItem::SettingItem(SettingItem {
3400 title: "Git Panel Dock",
3401 description: "Where to dock the Git panel",
3402 field: Box::new(SettingField {
3403 pick: |settings_content| {
3404 if let Some(git_panel) = &settings_content.git_panel {
3405 &git_panel.dock
3406 } else {
3407 &None
3408 }
3409 },
3410 pick_mut: |settings_content| {
3411 &mut settings_content.git_panel.get_or_insert_default().dock
3412 },
3413 }),
3414 metadata: None,
3415 files: USER,
3416 }),
3417 SettingsPageItem::SettingItem(SettingItem {
3418 title: "Git Panel Default Width",
3419 description: "Default width of the Git panel in pixels",
3420 field: Box::new(SettingField {
3421 pick: |settings_content| {
3422 if let Some(git_panel) = &settings_content.git_panel {
3423 &git_panel.default_width
3424 } else {
3425 &None
3426 }
3427 },
3428 pick_mut: |settings_content| {
3429 &mut settings_content
3430 .git_panel
3431 .get_or_insert_default()
3432 .default_width
3433 },
3434 }),
3435 metadata: None,
3436 files: USER,
3437 }),
3438 SettingsPageItem::SettingItem(SettingItem {
3439 title: "Git Panel Status Style",
3440 description: "How entry statuses are displayed",
3441 field: Box::new(SettingField {
3442 pick: |settings_content| {
3443 if let Some(git_panel) = &settings_content.git_panel {
3444 &git_panel.status_style
3445 } else {
3446 &None
3447 }
3448 },
3449 pick_mut: |settings_content| {
3450 &mut settings_content
3451 .git_panel
3452 .get_or_insert_default()
3453 .status_style
3454 },
3455 }),
3456 metadata: None,
3457 files: USER,
3458 }),
3459 SettingsPageItem::SettingItem(SettingItem {
3460 title: "Fallback Branch Name",
3461 description: "Default branch name will be when init.defaultBranch is not set in git",
3462 field: Box::new(SettingField {
3463 pick: |settings_content| {
3464 if let Some(git_panel) = &settings_content.git_panel {
3465 &git_panel.fallback_branch_name
3466 } else {
3467 &None
3468 }
3469 },
3470 pick_mut: |settings_content| {
3471 &mut settings_content
3472 .git_panel
3473 .get_or_insert_default()
3474 .fallback_branch_name
3475 },
3476 }),
3477 metadata: None,
3478 files: USER,
3479 }),
3480 SettingsPageItem::SettingItem(SettingItem {
3481 title: "Sort By Path",
3482 description: "Enable to sort entries in the panel by path, disable to sort by status",
3483 field: Box::new(SettingField {
3484 pick: |settings_content| {
3485 if let Some(git_panel) = &settings_content.git_panel {
3486 &git_panel.sort_by_path
3487 } else {
3488 &None
3489 }
3490 },
3491 pick_mut: |settings_content| {
3492 &mut settings_content
3493 .git_panel
3494 .get_or_insert_default()
3495 .sort_by_path
3496 },
3497 }),
3498 metadata: None,
3499 files: USER,
3500 }),
3501 SettingsPageItem::SettingItem(SettingItem {
3502 title: "Collapse Untracked Diff",
3503 description: "Whether to collapse untracked files in the diff panel",
3504 field: Box::new(SettingField {
3505 pick: |settings_content| {
3506 if let Some(git_panel) = &settings_content.git_panel {
3507 &git_panel.collapse_untracked_diff
3508 } else {
3509 &None
3510 }
3511 },
3512 pick_mut: |settings_content| {
3513 &mut settings_content
3514 .git_panel
3515 .get_or_insert_default()
3516 .collapse_untracked_diff
3517 },
3518 }),
3519 metadata: None,
3520 files: USER,
3521 }),
3522 SettingsPageItem::SettingItem(SettingItem {
3523 title: "Scroll Bar",
3524 description: "How and when the scrollbar should be displayed",
3525 field: Box::new(SettingField {
3526 pick: |settings_content| match &settings_content.git_panel {
3527 Some(settings::GitPanelSettingsContent {
3528 scrollbar: Some(scrollbar),
3529 ..
3530 }) => &scrollbar.show,
3531 _ => &None,
3532 },
3533 pick_mut: |settings_content| {
3534 &mut settings_content
3535 .git_panel
3536 .get_or_insert_default()
3537 .scrollbar
3538 .get_or_insert_default()
3539 .show
3540 },
3541 }),
3542 metadata: None,
3543 files: USER,
3544 }),
3545 SettingsPageItem::SectionHeader("Debugger Panel"),
3546 SettingsPageItem::SettingItem(SettingItem {
3547 title: "Debugger Panel Dock",
3548 description: "The dock position of the debug panel",
3549 field: Box::new(SettingField {
3550 pick: |settings_content| {
3551 if let Some(debugger) = &settings_content.debugger {
3552 &debugger.dock
3553 } else {
3554 &None
3555 }
3556 },
3557 pick_mut: |settings_content| {
3558 &mut settings_content.debugger.get_or_insert_default().dock
3559 },
3560 }),
3561 metadata: None,
3562 files: USER,
3563 }),
3564 SettingsPageItem::SectionHeader("Notification Panel"),
3565 SettingsPageItem::SettingItem(SettingItem {
3566 title: "Notification Panel Button",
3567 description: "Show the notification panel button in the status bar",
3568 field: Box::new(SettingField {
3569 pick: |settings_content| {
3570 if let Some(notification_panel) = &settings_content.notification_panel {
3571 ¬ification_panel.button
3572 } else {
3573 &None
3574 }
3575 },
3576 pick_mut: |settings_content| {
3577 &mut settings_content
3578 .notification_panel
3579 .get_or_insert_default()
3580 .button
3581 },
3582 }),
3583 metadata: None,
3584 files: USER,
3585 }),
3586 SettingsPageItem::SettingItem(SettingItem {
3587 title: "Notification Panel Dock",
3588 description: "Where to dock the notification panel",
3589 field: Box::new(SettingField {
3590 pick: |settings_content| {
3591 if let Some(notification_panel) = &settings_content.notification_panel {
3592 ¬ification_panel.dock
3593 } else {
3594 &None
3595 }
3596 },
3597 pick_mut: |settings_content| {
3598 &mut settings_content
3599 .notification_panel
3600 .get_or_insert_default()
3601 .dock
3602 },
3603 }),
3604 metadata: None,
3605 files: USER,
3606 }),
3607 SettingsPageItem::SettingItem(SettingItem {
3608 title: "Notification Panel Default Width",
3609 description: "Default width of the notification panel in pixels",
3610 field: Box::new(SettingField {
3611 pick: |settings_content| {
3612 if let Some(notification_panel) = &settings_content.notification_panel {
3613 ¬ification_panel.default_width
3614 } else {
3615 &None
3616 }
3617 },
3618 pick_mut: |settings_content| {
3619 &mut settings_content
3620 .notification_panel
3621 .get_or_insert_default()
3622 .default_width
3623 },
3624 }),
3625 metadata: None,
3626 files: USER,
3627 }),
3628 SettingsPageItem::SectionHeader("Collaboration Panel"),
3629 SettingsPageItem::SettingItem(SettingItem {
3630 title: "Collaboration Panel Button",
3631 description: "Show the collaboration panel button in the status bar",
3632 field: Box::new(SettingField {
3633 pick: |settings_content| {
3634 if let Some(collaboration_panel) = &settings_content.collaboration_panel
3635 {
3636 &collaboration_panel.button
3637 } else {
3638 &None
3639 }
3640 },
3641 pick_mut: |settings_content| {
3642 &mut settings_content
3643 .collaboration_panel
3644 .get_or_insert_default()
3645 .button
3646 },
3647 }),
3648 metadata: None,
3649 files: USER,
3650 }),
3651 SettingsPageItem::SettingItem(SettingItem {
3652 title: "Collaboration Panel Dock",
3653 description: "Where to dock the collaboration panel",
3654 field: Box::new(SettingField {
3655 pick: |settings_content| {
3656 if let Some(collaboration_panel) = &settings_content.collaboration_panel
3657 {
3658 &collaboration_panel.dock
3659 } else {
3660 &None
3661 }
3662 },
3663 pick_mut: |settings_content| {
3664 &mut settings_content
3665 .collaboration_panel
3666 .get_or_insert_default()
3667 .dock
3668 },
3669 }),
3670 metadata: None,
3671 files: USER,
3672 }),
3673 SettingsPageItem::SettingItem(SettingItem {
3674 title: "Collaboration Panel Default Width",
3675 description: "Default width of the collaboration panel in pixels",
3676 field: Box::new(SettingField {
3677 pick: |settings_content| {
3678 if let Some(collaboration_panel) = &settings_content.collaboration_panel
3679 {
3680 &collaboration_panel.default_width
3681 } else {
3682 &None
3683 }
3684 },
3685 pick_mut: |settings_content| {
3686 &mut settings_content
3687 .collaboration_panel
3688 .get_or_insert_default()
3689 .default_width
3690 },
3691 }),
3692 metadata: None,
3693 files: USER,
3694 }),
3695 SettingsPageItem::SectionHeader("Agent Panel"),
3696 SettingsPageItem::SettingItem(SettingItem {
3697 title: "Agent Panel Button",
3698 description: "Whether to show the agent panel button in the status bar",
3699 field: Box::new(SettingField {
3700 pick: |settings_content| {
3701 if let Some(agent) = &settings_content.agent {
3702 &agent.button
3703 } else {
3704 &None
3705 }
3706 },
3707 pick_mut: |settings_content| {
3708 &mut settings_content.agent.get_or_insert_default().button
3709 },
3710 }),
3711 metadata: None,
3712 files: USER,
3713 }),
3714 SettingsPageItem::SettingItem(SettingItem {
3715 title: "Agent Panel Dock",
3716 description: "Where to dock the agent panel.",
3717 field: Box::new(SettingField {
3718 pick: |settings_content| {
3719 if let Some(agent) = &settings_content.agent {
3720 &agent.dock
3721 } else {
3722 &None
3723 }
3724 },
3725 pick_mut: |settings_content| {
3726 &mut settings_content.agent.get_or_insert_default().dock
3727 },
3728 }),
3729 metadata: None,
3730 files: USER,
3731 }),
3732 SettingsPageItem::SettingItem(SettingItem {
3733 title: "Agent Panel Default Width",
3734 description: "Default width when the agent panel is docked to the left or right",
3735 field: Box::new(SettingField {
3736 pick: |settings_content| {
3737 if let Some(agent) = &settings_content.agent {
3738 &agent.default_width
3739 } else {
3740 &None
3741 }
3742 },
3743 pick_mut: |settings_content| {
3744 &mut settings_content.agent.get_or_insert_default().default_width
3745 },
3746 }),
3747 metadata: None,
3748 files: USER,
3749 }),
3750 SettingsPageItem::SettingItem(SettingItem {
3751 title: "Agent Panel Default Height",
3752 description: "Default height when the agent panel is docked to the bottom",
3753 field: Box::new(SettingField {
3754 pick: |settings_content| {
3755 if let Some(agent) = &settings_content.agent {
3756 &agent.default_height
3757 } else {
3758 &None
3759 }
3760 },
3761 pick_mut: |settings_content| {
3762 &mut settings_content
3763 .agent
3764 .get_or_insert_default()
3765 .default_height
3766 },
3767 }),
3768 metadata: None,
3769 files: USER,
3770 }),
3771 ],
3772 },
3773 SettingsPage {
3774 title: "Debugger",
3775 items: vec![
3776 SettingsPageItem::SectionHeader("General"),
3777 SettingsPageItem::SettingItem(SettingItem {
3778 title: "Stepping Granularity",
3779 description: "Determines the stepping granularity for debug operations",
3780 field: Box::new(SettingField {
3781 pick: |settings_content| {
3782 if let Some(debugger) = &settings_content.debugger {
3783 &debugger.stepping_granularity
3784 } else {
3785 &None
3786 }
3787 },
3788 pick_mut: |settings_content| {
3789 &mut settings_content
3790 .debugger
3791 .get_or_insert_default()
3792 .stepping_granularity
3793 },
3794 }),
3795 metadata: None,
3796 files: USER,
3797 }),
3798 SettingsPageItem::SettingItem(SettingItem {
3799 title: "Save Breakpoints",
3800 description: "Whether breakpoints should be reused across Zed sessions",
3801 field: Box::new(SettingField {
3802 pick: |settings_content| {
3803 if let Some(debugger) = &settings_content.debugger {
3804 &debugger.save_breakpoints
3805 } else {
3806 &None
3807 }
3808 },
3809 pick_mut: |settings_content| {
3810 &mut settings_content
3811 .debugger
3812 .get_or_insert_default()
3813 .save_breakpoints
3814 },
3815 }),
3816 metadata: None,
3817 files: USER,
3818 }),
3819 SettingsPageItem::SettingItem(SettingItem {
3820 title: "Timeout",
3821 description: "Time in milliseconds until timeout error when connecting to a TCP debug adapter",
3822 field: Box::new(SettingField {
3823 pick: |settings_content| {
3824 if let Some(debugger) = &settings_content.debugger {
3825 &debugger.timeout
3826 } else {
3827 &None
3828 }
3829 },
3830 pick_mut: |settings_content| {
3831 &mut settings_content.debugger.get_or_insert_default().timeout
3832 },
3833 }),
3834 metadata: None,
3835 files: USER,
3836 }),
3837 SettingsPageItem::SettingItem(SettingItem {
3838 title: "Log DAP Communications",
3839 description: "Whether to log messages between active debug adapters and Zed",
3840 field: Box::new(SettingField {
3841 pick: |settings_content| {
3842 if let Some(debugger) = &settings_content.debugger {
3843 &debugger.log_dap_communications
3844 } else {
3845 &None
3846 }
3847 },
3848 pick_mut: |settings_content| {
3849 &mut settings_content
3850 .debugger
3851 .get_or_insert_default()
3852 .log_dap_communications
3853 },
3854 }),
3855 metadata: None,
3856 files: USER,
3857 }),
3858 SettingsPageItem::SettingItem(SettingItem {
3859 title: "Format DAP Log Messages",
3860 description: "Whether to format DAP messages when adding them to debug adapter logger",
3861 field: Box::new(SettingField {
3862 pick: |settings_content| {
3863 if let Some(debugger) = &settings_content.debugger {
3864 &debugger.format_dap_log_messages
3865 } else {
3866 &None
3867 }
3868 },
3869 pick_mut: |settings_content| {
3870 &mut settings_content
3871 .debugger
3872 .get_or_insert_default()
3873 .format_dap_log_messages
3874 },
3875 }),
3876 metadata: None,
3877 files: USER,
3878 }),
3879 ],
3880 },
3881 SettingsPage {
3882 title: "Terminal",
3883 items: vec![
3884 SettingsPageItem::SectionHeader("Environment"),
3885 SettingsPageItem::SettingItem(SettingItem {
3886 title: "Shell",
3887 description: "What shell to use when opening a terminal",
3888 field: Box::new(
3889 SettingField {
3890 pick: |settings_content| {
3891 if let Some(terminal) = &settings_content.terminal {
3892 &terminal.project.shell
3893 } else {
3894 &None
3895 }
3896 },
3897 pick_mut: |settings_content| {
3898 &mut settings_content
3899 .terminal
3900 .get_or_insert_default()
3901 .project
3902 .shell
3903 },
3904 }
3905 .unimplemented(),
3906 ),
3907 metadata: None,
3908 files: USER | LOCAL,
3909 }),
3910 SettingsPageItem::SettingItem(SettingItem {
3911 title: "Working Directory",
3912 description: "What working directory to use when launching the terminal",
3913 field: Box::new(
3914 SettingField {
3915 pick: |settings_content| {
3916 if let Some(terminal) = &settings_content.terminal {
3917 &terminal.project.working_directory
3918 } else {
3919 &None
3920 }
3921 },
3922 pick_mut: |settings_content| {
3923 &mut settings_content
3924 .terminal
3925 .get_or_insert_default()
3926 .project
3927 .working_directory
3928 },
3929 }
3930 .unimplemented(),
3931 ),
3932 metadata: None,
3933 files: USER | LOCAL,
3934 }),
3935 SettingsPageItem::SettingItem(SettingItem {
3936 title: "Environment Variables",
3937 description: "Key-value pairs to add to the terminal's environment",
3938 field: Box::new(
3939 SettingField {
3940 pick: |settings_content| {
3941 if let Some(terminal) = &settings_content.terminal {
3942 &terminal.project.env
3943 } else {
3944 &None
3945 }
3946 },
3947 pick_mut: |settings_content| {
3948 &mut settings_content
3949 .terminal
3950 .get_or_insert_default()
3951 .project
3952 .env
3953 },
3954 }
3955 .unimplemented(),
3956 ),
3957 metadata: None,
3958 files: USER | LOCAL,
3959 }),
3960 SettingsPageItem::SettingItem(SettingItem {
3961 title: "Detect Virtual Environment",
3962 description: "Activates the python virtual environment, if one is found, in the terminal's working directory",
3963 field: Box::new(
3964 SettingField {
3965 pick: |settings_content| {
3966 if let Some(terminal) = &settings_content.terminal {
3967 &terminal.project.detect_venv
3968 } else {
3969 &None
3970 }
3971 },
3972 pick_mut: |settings_content| {
3973 &mut settings_content
3974 .terminal
3975 .get_or_insert_default()
3976 .project
3977 .detect_venv
3978 },
3979 }
3980 .unimplemented(),
3981 ),
3982 metadata: None,
3983 files: USER | LOCAL,
3984 }),
3985 SettingsPageItem::SectionHeader("Font"),
3986 SettingsPageItem::SettingItem(SettingItem {
3987 title: "Font Size",
3988 description: "Font size for terminal text. If not set, defaults to buffer font size",
3989 field: Box::new(SettingField {
3990 pick: |settings_content| {
3991 if let Some(terminal) = &settings_content.terminal
3992 && terminal.font_size.is_some()
3993 {
3994 &terminal.font_size
3995 } else if settings_content.theme.buffer_font_size.is_some() {
3996 &settings_content.theme.buffer_font_size
3997 } else {
3998 &None
3999 }
4000 },
4001 pick_mut: |settings_content| {
4002 &mut settings_content.terminal.get_or_insert_default().font_size
4003 },
4004 }),
4005 metadata: None,
4006 files: USER,
4007 }),
4008 SettingsPageItem::SettingItem(SettingItem {
4009 title: "Font Family",
4010 description: "Font family for terminal text. If not set, defaults to buffer font family",
4011 field: Box::new(SettingField {
4012 pick: |settings_content| {
4013 if let Some(terminal) = &settings_content.terminal
4014 && terminal.font_family.is_some()
4015 {
4016 &terminal.font_family
4017 } else if settings_content.theme.buffer_font_family.is_some() {
4018 &settings_content.theme.buffer_font_family
4019 } else {
4020 &None
4021 }
4022 },
4023 pick_mut: |settings_content| {
4024 &mut settings_content
4025 .terminal
4026 .get_or_insert_default()
4027 .font_family
4028 },
4029 }),
4030 metadata: None,
4031 files: USER,
4032 }),
4033 SettingsPageItem::SettingItem(SettingItem {
4034 title: "Font Fallbacks",
4035 description: "Font fallbacks for terminal text. If not set, defaults to buffer font fallbacks",
4036 field: Box::new(
4037 SettingField {
4038 pick: |settings_content| {
4039 if let Some(terminal) = &settings_content.terminal {
4040 &terminal.font_fallbacks
4041 } else {
4042 &None
4043 }
4044 },
4045 pick_mut: |settings_content| {
4046 &mut settings_content
4047 .terminal
4048 .get_or_insert_default()
4049 .font_fallbacks
4050 },
4051 }
4052 .unimplemented(),
4053 ),
4054 metadata: None,
4055 files: USER,
4056 }),
4057 SettingsPageItem::SettingItem(SettingItem {
4058 title: "Font Weight",
4059 description: "Font weight for terminal text in CSS weight units (100-900)",
4060 field: Box::new(SettingField {
4061 pick: |settings_content| {
4062 if let Some(terminal) = &settings_content.terminal {
4063 &terminal.font_weight
4064 } else {
4065 &None
4066 }
4067 },
4068 pick_mut: |settings_content| {
4069 &mut settings_content
4070 .terminal
4071 .get_or_insert_default()
4072 .font_weight
4073 },
4074 }),
4075 metadata: None,
4076 files: USER,
4077 }),
4078 SettingsPageItem::SettingItem(SettingItem {
4079 title: "Font Features",
4080 description: "Font features for terminal text",
4081 field: Box::new(
4082 SettingField {
4083 pick: |settings_content| {
4084 if let Some(terminal) = &settings_content.terminal {
4085 &terminal.font_features
4086 } else {
4087 &None
4088 }
4089 },
4090 pick_mut: |settings_content| {
4091 &mut settings_content
4092 .terminal
4093 .get_or_insert_default()
4094 .font_features
4095 },
4096 }
4097 .unimplemented(),
4098 ),
4099 metadata: None,
4100 files: USER,
4101 }),
4102 SettingsPageItem::SectionHeader("Display Settings"),
4103 SettingsPageItem::SettingItem(SettingItem {
4104 title: "Line Height",
4105 description: "Line height for terminal text",
4106 field: Box::new(
4107 SettingField {
4108 pick: |settings_content| {
4109 if let Some(terminal) = &settings_content.terminal {
4110 &terminal.line_height
4111 } else {
4112 &None
4113 }
4114 },
4115 pick_mut: |settings_content| {
4116 &mut settings_content
4117 .terminal
4118 .get_or_insert_default()
4119 .line_height
4120 },
4121 }
4122 .unimplemented(),
4123 ),
4124 metadata: None,
4125 files: USER,
4126 }),
4127 SettingsPageItem::SettingItem(SettingItem {
4128 title: "Cursor Shape",
4129 description: "Default cursor shape for the terminal (bar, block, underline, or hollow)",
4130 field: Box::new(SettingField {
4131 pick: |settings_content| {
4132 if let Some(terminal) = &settings_content.terminal {
4133 &terminal.cursor_shape
4134 } else {
4135 &None
4136 }
4137 },
4138 pick_mut: |settings_content| {
4139 &mut settings_content
4140 .terminal
4141 .get_or_insert_default()
4142 .cursor_shape
4143 },
4144 }),
4145 metadata: None,
4146 files: USER,
4147 }),
4148 SettingsPageItem::SettingItem(SettingItem {
4149 title: "Cursor Blinking",
4150 description: "Sets the cursor blinking behavior in the terminal",
4151 field: Box::new(SettingField {
4152 pick: |settings_content| {
4153 if let Some(terminal) = &settings_content.terminal {
4154 &terminal.blinking
4155 } else {
4156 &None
4157 }
4158 },
4159 pick_mut: |settings_content| {
4160 &mut settings_content.terminal.get_or_insert_default().blinking
4161 },
4162 }),
4163 metadata: None,
4164 files: USER,
4165 }),
4166 SettingsPageItem::SettingItem(SettingItem {
4167 title: "Alternate Scroll",
4168 description: "Whether Alternate Scroll mode is active by default (converts mouse scroll to arrow keys in apps like vim)",
4169 field: Box::new(SettingField {
4170 pick: |settings_content| {
4171 if let Some(terminal) = &settings_content.terminal {
4172 &terminal.alternate_scroll
4173 } else {
4174 &None
4175 }
4176 },
4177 pick_mut: |settings_content| {
4178 &mut settings_content
4179 .terminal
4180 .get_or_insert_default()
4181 .alternate_scroll
4182 },
4183 }),
4184 metadata: None,
4185 files: USER,
4186 }),
4187 SettingsPageItem::SettingItem(SettingItem {
4188 title: "Minimum Contrast",
4189 description: "The minimum APCA perceptual contrast between foreground and background colors (0-106)",
4190 field: Box::new(SettingField {
4191 pick: |settings_content| {
4192 if let Some(terminal) = &settings_content.terminal {
4193 &terminal.minimum_contrast
4194 } else {
4195 &None
4196 }
4197 },
4198 pick_mut: |settings_content| {
4199 &mut settings_content
4200 .terminal
4201 .get_or_insert_default()
4202 .minimum_contrast
4203 },
4204 }),
4205 metadata: None,
4206 files: USER,
4207 }),
4208 SettingsPageItem::SectionHeader("Behavior Settings"),
4209 SettingsPageItem::SettingItem(SettingItem {
4210 title: "Option As Meta",
4211 description: "Whether the option key behaves as the meta key",
4212 field: Box::new(SettingField {
4213 pick: |settings_content| {
4214 if let Some(terminal) = &settings_content.terminal {
4215 &terminal.option_as_meta
4216 } else {
4217 &None
4218 }
4219 },
4220 pick_mut: |settings_content| {
4221 &mut settings_content
4222 .terminal
4223 .get_or_insert_default()
4224 .option_as_meta
4225 },
4226 }),
4227 metadata: None,
4228 files: USER,
4229 }),
4230 SettingsPageItem::SettingItem(SettingItem {
4231 title: "Copy On Select",
4232 description: "Whether selecting text in the terminal automatically copies to the system clipboard",
4233 field: Box::new(SettingField {
4234 pick: |settings_content| {
4235 if let Some(terminal) = &settings_content.terminal {
4236 &terminal.copy_on_select
4237 } else {
4238 &None
4239 }
4240 },
4241 pick_mut: |settings_content| {
4242 &mut settings_content
4243 .terminal
4244 .get_or_insert_default()
4245 .copy_on_select
4246 },
4247 }),
4248 metadata: None,
4249 files: USER,
4250 }),
4251 SettingsPageItem::SettingItem(SettingItem {
4252 title: "Keep Selection On Copy",
4253 description: "Whether to keep the text selection after copying it to the clipboard",
4254 field: Box::new(SettingField {
4255 pick: |settings_content| {
4256 if let Some(terminal) = &settings_content.terminal {
4257 &terminal.keep_selection_on_copy
4258 } else {
4259 &None
4260 }
4261 },
4262 pick_mut: |settings_content| {
4263 &mut settings_content
4264 .terminal
4265 .get_or_insert_default()
4266 .keep_selection_on_copy
4267 },
4268 }),
4269 metadata: None,
4270 files: USER,
4271 }),
4272 SettingsPageItem::SectionHeader("Layout Settings"),
4273 SettingsPageItem::SettingItem(SettingItem {
4274 title: "Default Width",
4275 description: "Default width when the terminal is docked to the left or right (in pixels)",
4276 field: Box::new(SettingField {
4277 pick: |settings_content| {
4278 if let Some(terminal) = &settings_content.terminal {
4279 &terminal.default_width
4280 } else {
4281 &None
4282 }
4283 },
4284 pick_mut: |settings_content| {
4285 &mut settings_content
4286 .terminal
4287 .get_or_insert_default()
4288 .default_width
4289 },
4290 }),
4291 metadata: None,
4292 files: USER,
4293 }),
4294 SettingsPageItem::SettingItem(SettingItem {
4295 title: "Default Height",
4296 description: "Default height when the terminal is docked to the bottom (in pixels)",
4297 field: Box::new(SettingField {
4298 pick: |settings_content| {
4299 if let Some(terminal) = &settings_content.terminal {
4300 &terminal.default_height
4301 } else {
4302 &None
4303 }
4304 },
4305 pick_mut: |settings_content| {
4306 &mut settings_content
4307 .terminal
4308 .get_or_insert_default()
4309 .default_height
4310 },
4311 }),
4312 metadata: None,
4313 files: USER,
4314 }),
4315 SettingsPageItem::SectionHeader("Advanced Settings"),
4316 SettingsPageItem::SettingItem(SettingItem {
4317 title: "Max Scroll History Lines",
4318 description: "Maximum number of lines to keep in scrollback history (max: 100,000; 0 disables scrolling)",
4319 field: Box::new(SettingField {
4320 pick: |settings_content| {
4321 if let Some(terminal) = &settings_content.terminal {
4322 &terminal.max_scroll_history_lines
4323 } else {
4324 &None
4325 }
4326 },
4327 pick_mut: |settings_content| {
4328 &mut settings_content
4329 .terminal
4330 .get_or_insert_default()
4331 .max_scroll_history_lines
4332 },
4333 }),
4334 metadata: None,
4335 files: USER,
4336 }),
4337 SettingsPageItem::SectionHeader("Toolbar"),
4338 SettingsPageItem::SettingItem(SettingItem {
4339 title: "Breadcrumbs",
4340 description: "Display the terminal title in breadcrumbs inside the terminal pane",
4341 field: Box::new(SettingField {
4342 pick: |settings_content| {
4343 if let Some(terminal) = &settings_content.terminal {
4344 if let Some(toolbar) = &terminal.toolbar {
4345 &toolbar.breadcrumbs
4346 } else {
4347 &None
4348 }
4349 } else {
4350 &None
4351 }
4352 },
4353 pick_mut: |settings_content| {
4354 &mut settings_content
4355 .terminal
4356 .get_or_insert_default()
4357 .toolbar
4358 .get_or_insert_default()
4359 .breadcrumbs
4360 },
4361 }),
4362 metadata: None,
4363 files: USER,
4364 }),
4365 SettingsPageItem::SectionHeader("Scrollbar"),
4366 SettingsPageItem::SettingItem(SettingItem {
4367 title: "Show Scrollbar",
4368 description: "When to show the scrollbar in the terminal",
4369 field: Box::new(SettingField {
4370 pick: |settings_content| {
4371 if let Some(terminal) = &settings_content.terminal
4372 && let Some(scrollbar) = &terminal.scrollbar
4373 && scrollbar.show.is_some()
4374 {
4375 &scrollbar.show
4376 } else if let Some(scrollbar) = &settings_content.editor.scrollbar {
4377 &scrollbar.show
4378 } else {
4379 &None
4380 }
4381 },
4382 pick_mut: |settings_content| {
4383 &mut settings_content
4384 .terminal
4385 .get_or_insert_default()
4386 .scrollbar
4387 .get_or_insert_default()
4388 .show
4389 },
4390 }),
4391 metadata: None,
4392 files: USER,
4393 }),
4394 ],
4395 },
4396 SettingsPage {
4397 title: "Version Control",
4398 items: vec![
4399 SettingsPageItem::SectionHeader("Git Gutter"),
4400 SettingsPageItem::SettingItem(SettingItem {
4401 title: "Visibilility",
4402 description: "Control whether git status is shown in the editor's gutter",
4403 field: Box::new(SettingField {
4404 pick: |settings_content| {
4405 if let Some(git) = &settings_content.git {
4406 &git.git_gutter
4407 } else {
4408 &None
4409 }
4410 },
4411 pick_mut: |settings_content| {
4412 &mut settings_content.git.get_or_insert_default().git_gutter
4413 },
4414 }),
4415 metadata: None,
4416 files: USER,
4417 }),
4418 // todo(settings_ui): Figure out the right default for this value in default.json
4419 SettingsPageItem::SettingItem(SettingItem {
4420 title: "Debounce",
4421 description: "Debounce threshold in milliseconds after which changes are reflected in the git gutter",
4422 field: Box::new(SettingField {
4423 pick: |settings_content| {
4424 if let Some(git) = &settings_content.git {
4425 &git.gutter_debounce
4426 } else {
4427 &None
4428 }
4429 },
4430 pick_mut: |settings_content| {
4431 &mut settings_content.git.get_or_insert_default().gutter_debounce
4432 },
4433 }),
4434 metadata: None,
4435 files: USER,
4436 }),
4437 SettingsPageItem::SectionHeader("Inline Git Blame"),
4438 SettingsPageItem::SettingItem(SettingItem {
4439 title: "Enabled",
4440 description: "Whether or not to show git blame data inline in the currently focused line",
4441 field: Box::new(SettingField {
4442 pick: |settings_content| {
4443 if let Some(git) = &settings_content.git {
4444 if let Some(inline_blame) = &git.inline_blame {
4445 &inline_blame.enabled
4446 } else {
4447 &None
4448 }
4449 } else {
4450 &None
4451 }
4452 },
4453 pick_mut: |settings_content| {
4454 &mut settings_content
4455 .git
4456 .get_or_insert_default()
4457 .inline_blame
4458 .get_or_insert_default()
4459 .enabled
4460 },
4461 }),
4462 metadata: None,
4463 files: USER,
4464 }),
4465 SettingsPageItem::SettingItem(SettingItem {
4466 title: "Delay",
4467 description: "The delay after which the inline blame information is shown",
4468 field: Box::new(SettingField {
4469 pick: |settings_content| {
4470 if let Some(git) = &settings_content.git {
4471 if let Some(inline_blame) = &git.inline_blame {
4472 &inline_blame.delay_ms
4473 } else {
4474 &None
4475 }
4476 } else {
4477 &None
4478 }
4479 },
4480 pick_mut: |settings_content| {
4481 &mut settings_content
4482 .git
4483 .get_or_insert_default()
4484 .inline_blame
4485 .get_or_insert_default()
4486 .delay_ms
4487 },
4488 }),
4489 metadata: None,
4490 files: USER,
4491 }),
4492 SettingsPageItem::SettingItem(SettingItem {
4493 title: "Padding",
4494 description: "Padding between the end of the source line and the start of the inline blame in columns",
4495 field: Box::new(SettingField {
4496 pick: |settings_content| {
4497 if let Some(git) = &settings_content.git {
4498 if let Some(inline_blame) = &git.inline_blame {
4499 &inline_blame.padding
4500 } else {
4501 &None
4502 }
4503 } else {
4504 &None
4505 }
4506 },
4507 pick_mut: |settings_content| {
4508 &mut settings_content
4509 .git
4510 .get_or_insert_default()
4511 .inline_blame
4512 .get_or_insert_default()
4513 .padding
4514 },
4515 }),
4516 metadata: None,
4517 files: USER,
4518 }),
4519 SettingsPageItem::SettingItem(SettingItem {
4520 title: "Minimum Column",
4521 description: "The minimum column number at which to show the inline blame information",
4522 field: Box::new(SettingField {
4523 pick: |settings_content| match &settings_content.git {
4524 Some(settings::GitSettings {
4525 inline_blame: Some(inline_blame),
4526 ..
4527 }) => &inline_blame.min_column,
4528 _ => &None,
4529 },
4530 pick_mut: |settings_content| {
4531 &mut settings_content
4532 .git
4533 .get_or_insert_default()
4534 .inline_blame
4535 .get_or_insert_default()
4536 .min_column
4537 },
4538 }),
4539 metadata: None,
4540 files: USER,
4541 }),
4542 SettingsPageItem::SettingItem(SettingItem {
4543 title: "Show Commit Summary",
4544 description: "Show commit summary as part of the inline blame",
4545 field: Box::new(SettingField {
4546 pick: |settings_content| {
4547 if let Some(git) = &settings_content.git {
4548 if let Some(inline_blame) = &git.inline_blame {
4549 &inline_blame.show_commit_summary
4550 } else {
4551 &None
4552 }
4553 } else {
4554 &None
4555 }
4556 },
4557 pick_mut: |settings_content| {
4558 &mut settings_content
4559 .git
4560 .get_or_insert_default()
4561 .inline_blame
4562 .get_or_insert_default()
4563 .show_commit_summary
4564 },
4565 }),
4566 metadata: None,
4567 files: USER,
4568 }),
4569 SettingsPageItem::SectionHeader("Git Blame View"),
4570 SettingsPageItem::SettingItem(SettingItem {
4571 title: "Show Avatar",
4572 description: "Show the avatar of the author of the commit",
4573 field: Box::new(SettingField {
4574 pick: |settings_content| {
4575 if let Some(git) = &settings_content.git {
4576 if let Some(blame) = &git.blame {
4577 &blame.show_avatar
4578 } else {
4579 &None
4580 }
4581 } else {
4582 &None
4583 }
4584 },
4585 pick_mut: |settings_content| {
4586 &mut settings_content
4587 .git
4588 .get_or_insert_default()
4589 .blame
4590 .get_or_insert_default()
4591 .show_avatar
4592 },
4593 }),
4594 metadata: None,
4595 files: USER,
4596 }),
4597 SettingsPageItem::SectionHeader("Branch Picker"),
4598 SettingsPageItem::SettingItem(SettingItem {
4599 title: "Show Author Name",
4600 description: "Show author name as part of the commit information in branch picker",
4601 field: Box::new(SettingField {
4602 pick: |settings_content| {
4603 if let Some(git) = &settings_content.git {
4604 if let Some(branch_picker) = &git.branch_picker {
4605 &branch_picker.show_author_name
4606 } else {
4607 &None
4608 }
4609 } else {
4610 &None
4611 }
4612 },
4613 pick_mut: |settings_content| {
4614 &mut settings_content
4615 .git
4616 .get_or_insert_default()
4617 .branch_picker
4618 .get_or_insert_default()
4619 .show_author_name
4620 },
4621 }),
4622 metadata: None,
4623 files: USER,
4624 }),
4625 SettingsPageItem::SectionHeader("Git Hunks"),
4626 SettingsPageItem::SettingItem(SettingItem {
4627 title: "Hunk Style",
4628 description: "How git hunks are displayed visually in the editor",
4629 field: Box::new(SettingField {
4630 pick: |settings_content| {
4631 if let Some(git) = &settings_content.git {
4632 &git.hunk_style
4633 } else {
4634 &None
4635 }
4636 },
4637 pick_mut: |settings_content| {
4638 &mut settings_content.git.get_or_insert_default().hunk_style
4639 },
4640 }),
4641 metadata: None,
4642 files: USER,
4643 }),
4644 ],
4645 },
4646 SettingsPage {
4647 title: "Collaboration",
4648 items: vec![
4649 SettingsPageItem::SectionHeader("Calls"),
4650 SettingsPageItem::SettingItem(SettingItem {
4651 title: "Mute On Join",
4652 description: "Whether the microphone should be muted when joining a channel or a call",
4653 field: Box::new(SettingField {
4654 pick: |settings_content| {
4655 if let Some(calls) = &settings_content.calls {
4656 &calls.mute_on_join
4657 } else {
4658 &None
4659 }
4660 },
4661 pick_mut: |settings_content| {
4662 &mut settings_content.calls.get_or_insert_default().mute_on_join
4663 },
4664 }),
4665 metadata: None,
4666 files: USER,
4667 }),
4668 SettingsPageItem::SettingItem(SettingItem {
4669 title: "Share On Join",
4670 description: "Whether your current project should be shared when joining an empty channel",
4671 field: Box::new(SettingField {
4672 pick: |settings_content| {
4673 if let Some(calls) = &settings_content.calls {
4674 &calls.share_on_join
4675 } else {
4676 &None
4677 }
4678 },
4679 pick_mut: |settings_content| {
4680 &mut settings_content.calls.get_or_insert_default().share_on_join
4681 },
4682 }),
4683 metadata: None,
4684 files: USER,
4685 }),
4686 SettingsPageItem::SectionHeader("Experimental"),
4687 SettingsPageItem::SettingItem(SettingItem {
4688 title: "Rodio Audio",
4689 description: "Opt into the new audio system",
4690 field: Box::new(SettingField {
4691 pick: |settings_content| {
4692 if let Some(audio) = &settings_content.audio {
4693 &audio.rodio_audio
4694 } else {
4695 &None
4696 }
4697 },
4698 pick_mut: |settings_content| {
4699 &mut settings_content.audio.get_or_insert_default().rodio_audio
4700 },
4701 }),
4702 metadata: None,
4703 files: USER,
4704 }),
4705 SettingsPageItem::SettingItem(SettingItem {
4706 title: "Auto Microphone Volume",
4707 description: "Automatically adjust microphone volume (requires Rodio Audio)",
4708 field: Box::new(SettingField {
4709 pick: |settings_content| {
4710 if let Some(audio) = &settings_content.audio {
4711 &audio.auto_microphone_volume
4712 } else {
4713 &None
4714 }
4715 },
4716 pick_mut: |settings_content| {
4717 &mut settings_content
4718 .audio
4719 .get_or_insert_default()
4720 .auto_microphone_volume
4721 },
4722 }),
4723 metadata: None,
4724 files: USER,
4725 }),
4726 SettingsPageItem::SettingItem(SettingItem {
4727 title: "Auto Speaker Volume",
4728 description: "Automatically adjust volume of other call members (requires Rodio Audio)",
4729 field: Box::new(SettingField {
4730 pick: |settings_content| {
4731 if let Some(audio) = &settings_content.audio {
4732 &audio.auto_speaker_volume
4733 } else {
4734 &None
4735 }
4736 },
4737 pick_mut: |settings_content| {
4738 &mut settings_content
4739 .audio
4740 .get_or_insert_default()
4741 .auto_speaker_volume
4742 },
4743 }),
4744 metadata: None,
4745 files: USER,
4746 }),
4747 SettingsPageItem::SettingItem(SettingItem {
4748 title: "Denoise",
4749 description: "Remove background noises (requires Rodio Audio)",
4750 field: Box::new(SettingField {
4751 pick: |settings_content| {
4752 if let Some(audio) = &settings_content.audio {
4753 &audio.denoise
4754 } else {
4755 &None
4756 }
4757 },
4758 pick_mut: |settings_content| {
4759 &mut settings_content.audio.get_or_insert_default().denoise
4760 },
4761 }),
4762 metadata: None,
4763 files: USER,
4764 }),
4765 SettingsPageItem::SettingItem(SettingItem {
4766 title: "Legacy Audio Compatible",
4767 description: "Use audio parameters compatible with previous versions (requires Rodio Audio)",
4768 field: Box::new(SettingField {
4769 pick: |settings_content| {
4770 if let Some(audio) = &settings_content.audio {
4771 &audio.legacy_audio_compatible
4772 } else {
4773 &None
4774 }
4775 },
4776 pick_mut: |settings_content| {
4777 &mut settings_content
4778 .audio
4779 .get_or_insert_default()
4780 .legacy_audio_compatible
4781 },
4782 }),
4783 metadata: None,
4784 files: USER,
4785 }),
4786 ],
4787 },
4788 SettingsPage {
4789 title: "AI",
4790 items: vec![
4791 SettingsPageItem::SectionHeader("General"),
4792 SettingsPageItem::SettingItem(SettingItem {
4793 title: "Disable AI",
4794 description: "Whether to disable all AI features in Zed",
4795 field: Box::new(SettingField {
4796 pick: |settings_content| &settings_content.disable_ai,
4797 pick_mut: |settings_content| &mut settings_content.disable_ai,
4798 }),
4799 metadata: None,
4800 files: USER,
4801 }),
4802 SettingsPageItem::SectionHeader("Agent Configuration"),
4803 SettingsPageItem::SettingItem(SettingItem {
4804 title: "Always Allow Tool Actions",
4805 description: "When enabled, the agent can run potentially destructive actions without asking for your confirmation. This setting has no effect on external agents.",
4806 field: Box::new(SettingField {
4807 pick: |settings_content| {
4808 if let Some(agent) = &settings_content.agent {
4809 &agent.always_allow_tool_actions
4810 } else {
4811 &None
4812 }
4813 },
4814 pick_mut: |settings_content| {
4815 &mut settings_content
4816 .agent
4817 .get_or_insert_default()
4818 .always_allow_tool_actions
4819 },
4820 }),
4821 metadata: None,
4822 files: USER,
4823 }),
4824 SettingsPageItem::SettingItem(SettingItem {
4825 title: "Single File Review",
4826 description: "When enabled, agent edits will also be displayed in single-file buffers for review",
4827 field: Box::new(SettingField {
4828 pick: |settings_content| {
4829 if let Some(agent) = &settings_content.agent {
4830 &agent.single_file_review
4831 } else {
4832 &None
4833 }
4834 },
4835 pick_mut: |settings_content| {
4836 &mut settings_content
4837 .agent
4838 .get_or_insert_default()
4839 .single_file_review
4840 },
4841 }),
4842 metadata: None,
4843 files: USER,
4844 }),
4845 SettingsPageItem::SettingItem(SettingItem {
4846 title: "Enable Feedback",
4847 description: "Show voting thumbs up/down icon buttons for feedback on agent edits",
4848 field: Box::new(SettingField {
4849 pick: |settings_content| {
4850 if let Some(agent) = &settings_content.agent {
4851 &agent.enable_feedback
4852 } else {
4853 &None
4854 }
4855 },
4856 pick_mut: |settings_content| {
4857 &mut settings_content
4858 .agent
4859 .get_or_insert_default()
4860 .enable_feedback
4861 },
4862 }),
4863 metadata: None,
4864 files: USER,
4865 }),
4866 SettingsPageItem::SettingItem(SettingItem {
4867 title: "Notify When Agent Waiting",
4868 description: "Where to show notifications when the agent has completed its response or needs confirmation before running a tool action",
4869 field: Box::new(SettingField {
4870 pick: |settings_content| {
4871 if let Some(agent) = &settings_content.agent {
4872 &agent.notify_when_agent_waiting
4873 } else {
4874 &None
4875 }
4876 },
4877 pick_mut: |settings_content| {
4878 &mut settings_content
4879 .agent
4880 .get_or_insert_default()
4881 .notify_when_agent_waiting
4882 },
4883 }),
4884 metadata: None,
4885 files: USER,
4886 }),
4887 SettingsPageItem::SettingItem(SettingItem {
4888 title: "Play Sound When Agent Done",
4889 description: "Whether to play a sound when the agent has either completed its response, or needs user input",
4890 field: Box::new(SettingField {
4891 pick: |settings_content| {
4892 if let Some(agent) = &settings_content.agent {
4893 &agent.play_sound_when_agent_done
4894 } else {
4895 &None
4896 }
4897 },
4898 pick_mut: |settings_content| {
4899 &mut settings_content
4900 .agent
4901 .get_or_insert_default()
4902 .play_sound_when_agent_done
4903 },
4904 }),
4905 metadata: None,
4906 files: USER,
4907 }),
4908 SettingsPageItem::SettingItem(SettingItem {
4909 title: "Expand Edit Card",
4910 description: "Whether to have edit cards in the agent panel expanded, showing a preview of the diff",
4911 field: Box::new(SettingField {
4912 pick: |settings_content| {
4913 if let Some(agent) = &settings_content.agent {
4914 &agent.expand_edit_card
4915 } else {
4916 &None
4917 }
4918 },
4919 pick_mut: |settings_content| {
4920 &mut settings_content
4921 .agent
4922 .get_or_insert_default()
4923 .expand_edit_card
4924 },
4925 }),
4926 metadata: None,
4927 files: USER,
4928 }),
4929 SettingsPageItem::SettingItem(SettingItem {
4930 title: "Expand Terminal Card",
4931 description: "Whether to have terminal cards in the agent panel expanded, showing the whole command output",
4932 field: Box::new(SettingField {
4933 pick: |settings_content| {
4934 if let Some(agent) = &settings_content.agent {
4935 &agent.expand_terminal_card
4936 } else {
4937 &None
4938 }
4939 },
4940 pick_mut: |settings_content| {
4941 &mut settings_content
4942 .agent
4943 .get_or_insert_default()
4944 .expand_terminal_card
4945 },
4946 }),
4947 metadata: None,
4948 files: USER,
4949 }),
4950 SettingsPageItem::SettingItem(SettingItem {
4951 title: "Use Modifier To Send",
4952 description: "Whether to always use cmd-enter (or ctrl-enter on Linux or Windows) to send messages",
4953 field: Box::new(SettingField {
4954 pick: |settings_content| {
4955 if let Some(agent) = &settings_content.agent {
4956 &agent.use_modifier_to_send
4957 } else {
4958 &None
4959 }
4960 },
4961 pick_mut: |settings_content| {
4962 &mut settings_content
4963 .agent
4964 .get_or_insert_default()
4965 .use_modifier_to_send
4966 },
4967 }),
4968 metadata: None,
4969 files: USER,
4970 }),
4971 SettingsPageItem::SettingItem(SettingItem {
4972 title: "Message Editor Min Lines",
4973 description: "Minimum number of lines to display in the agent message editor",
4974 field: Box::new(SettingField {
4975 pick: |settings_content| {
4976 if let Some(agent) = &settings_content.agent {
4977 &agent.message_editor_min_lines
4978 } else {
4979 &None
4980 }
4981 },
4982 pick_mut: |settings_content| {
4983 &mut settings_content
4984 .agent
4985 .get_or_insert_default()
4986 .message_editor_min_lines
4987 },
4988 }),
4989 metadata: None,
4990 files: USER,
4991 }),
4992 ],
4993 },
4994 SettingsPage {
4995 title: "Network",
4996 items: vec![
4997 SettingsPageItem::SectionHeader("Network"),
4998 // todo(settings_ui): Proxy needs a default
4999 SettingsPageItem::SettingItem(SettingItem {
5000 title: "Proxy",
5001 description: "The proxy to use for network requests",
5002 field: Box::new(
5003 SettingField {
5004 pick: |settings_content| &settings_content.proxy,
5005 pick_mut: |settings_content| &mut settings_content.proxy,
5006 }
5007 .unimplemented(),
5008 ),
5009 metadata: Some(Box::new(SettingsFieldMetadata {
5010 placeholder: Some("socks5h://localhost:10808"),
5011 ..Default::default()
5012 })),
5013 files: USER,
5014 }),
5015 SettingsPageItem::SettingItem(SettingItem {
5016 title: "Server URL",
5017 description: "The URL of the Zed server to connect to",
5018 field: Box::new(SettingField {
5019 pick: |settings_content| &settings_content.server_url,
5020 pick_mut: |settings_content| &mut settings_content.server_url,
5021 }),
5022 metadata: Some(Box::new(SettingsFieldMetadata {
5023 placeholder: Some("https://zed.dev"),
5024 ..Default::default()
5025 })),
5026 files: USER,
5027 }),
5028 ],
5029 },
5030 ]
5031}
5032
5033const LANGUAGES_SECTION_HEADER: &'static str = "Languages";
5034
5035fn current_language() -> Option<SharedString> {
5036 sub_page_stack().iter().find_map(|page| {
5037 (page.section_header == LANGUAGES_SECTION_HEADER).then(|| page.link.title.clone())
5038 })
5039}
5040
5041fn language_settings_field<T>(
5042 settings_content: &SettingsContent,
5043 get: fn(&LanguageSettingsContent) -> &Option<T>,
5044) -> &Option<T> {
5045 let all_languages = &settings_content.project.all_languages;
5046 if let Some(current_language_name) = current_language() {
5047 if let Some(current_language) = all_languages.languages.0.get(¤t_language_name) {
5048 let value = get(current_language);
5049 if value.is_some() {
5050 return value;
5051 }
5052 }
5053 }
5054 let default_value = get(&all_languages.defaults);
5055 return default_value;
5056}
5057
5058fn language_settings_field_mut<T>(
5059 settings_content: &mut SettingsContent,
5060 get: fn(&mut LanguageSettingsContent) -> &mut Option<T>,
5061) -> &mut Option<T> {
5062 let all_languages = &mut settings_content.project.all_languages;
5063 let language_content = if let Some(current_language) = current_language() {
5064 all_languages
5065 .languages
5066 .0
5067 .entry(current_language)
5068 .or_default()
5069 } else {
5070 &mut all_languages.defaults
5071 };
5072 return get(language_content);
5073}
5074
5075fn language_settings_data() -> Vec<SettingsPageItem> {
5076 let mut items = vec![
5077 SettingsPageItem::SectionHeader("Indentation"),
5078 SettingsPageItem::SettingItem(SettingItem {
5079 title: "Tab Size",
5080 description: "How many columns a tab should occupy",
5081 field: Box::new(SettingField {
5082 pick: |settings_content| {
5083 language_settings_field(settings_content, |language| &language.tab_size)
5084 },
5085 pick_mut: |settings_content| {
5086 language_settings_field_mut(settings_content, |language| &mut language.tab_size)
5087 },
5088 }),
5089 metadata: None,
5090 files: USER | LOCAL,
5091 }),
5092 SettingsPageItem::SettingItem(SettingItem {
5093 title: "Hard Tabs",
5094 description: "Whether to indent lines using tab characters, as opposed to multiple spaces",
5095 field: Box::new(SettingField {
5096 pick: |settings_content| {
5097 language_settings_field(settings_content, |language| &language.hard_tabs)
5098 },
5099 pick_mut: |settings_content| {
5100 language_settings_field_mut(settings_content, |language| {
5101 &mut language.hard_tabs
5102 })
5103 },
5104 }),
5105 metadata: None,
5106 files: USER | LOCAL,
5107 }),
5108 SettingsPageItem::SettingItem(SettingItem {
5109 title: "Auto Indent",
5110 description: "Whether indentation should be adjusted based on the context whilst typing",
5111 field: Box::new(SettingField {
5112 pick: |settings_content| {
5113 language_settings_field(settings_content, |language| &language.auto_indent)
5114 },
5115 pick_mut: |settings_content| {
5116 language_settings_field_mut(settings_content, |language| {
5117 &mut language.auto_indent
5118 })
5119 },
5120 }),
5121 metadata: None,
5122 files: USER | LOCAL,
5123 }),
5124 SettingsPageItem::SettingItem(SettingItem {
5125 title: "Auto Indent On Paste",
5126 description: "Whether indentation of pasted content should be adjusted based on the context",
5127 field: Box::new(SettingField {
5128 pick: |settings_content| {
5129 language_settings_field(settings_content, |language| {
5130 &language.auto_indent_on_paste
5131 })
5132 },
5133 pick_mut: |settings_content| {
5134 language_settings_field_mut(settings_content, |language| {
5135 &mut language.auto_indent_on_paste
5136 })
5137 },
5138 }),
5139 metadata: None,
5140 files: USER | LOCAL,
5141 }),
5142 SettingsPageItem::SectionHeader("Wrapping"),
5143 SettingsPageItem::SettingItem(SettingItem {
5144 title: "Soft Wrap",
5145 description: "How to soft-wrap long lines of text",
5146 field: Box::new(SettingField {
5147 pick: |settings_content| {
5148 language_settings_field(settings_content, |language| &language.soft_wrap)
5149 },
5150 pick_mut: |settings_content| {
5151 language_settings_field_mut(settings_content, |language| {
5152 &mut language.soft_wrap
5153 })
5154 },
5155 }),
5156 metadata: None,
5157 files: USER | LOCAL,
5158 }),
5159 SettingsPageItem::SettingItem(SettingItem {
5160 title: "Show Wrap Guides",
5161 description: "Show wrap guides in the editor",
5162 field: Box::new(SettingField {
5163 pick: |settings_content| {
5164 language_settings_field(settings_content, |language| &language.show_wrap_guides)
5165 },
5166 pick_mut: |settings_content| {
5167 language_settings_field_mut(settings_content, |language| {
5168 &mut language.show_wrap_guides
5169 })
5170 },
5171 }),
5172 metadata: None,
5173 files: USER | LOCAL,
5174 }),
5175 SettingsPageItem::SettingItem(SettingItem {
5176 title: "Preferred Line Length",
5177 description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled",
5178 field: Box::new(SettingField {
5179 pick: |settings_content| {
5180 language_settings_field(settings_content, |language| {
5181 &language.preferred_line_length
5182 })
5183 },
5184 pick_mut: |settings_content| {
5185 language_settings_field_mut(settings_content, |language| {
5186 &mut language.preferred_line_length
5187 })
5188 },
5189 }),
5190 metadata: None,
5191 files: USER | LOCAL,
5192 }),
5193 SettingsPageItem::SettingItem(SettingItem {
5194 title: "Wrap Guides",
5195 description: "Character counts at which to show wrap guides in the editor",
5196 field: Box::new(
5197 SettingField {
5198 pick: |settings_content| {
5199 language_settings_field(settings_content, |language| &language.wrap_guides)
5200 },
5201 pick_mut: |settings_content| {
5202 language_settings_field_mut(settings_content, |language| {
5203 &mut language.wrap_guides
5204 })
5205 },
5206 }
5207 .unimplemented(),
5208 ),
5209 metadata: None,
5210 files: USER | LOCAL,
5211 }),
5212 SettingsPageItem::SettingItem(SettingItem {
5213 title: "Allow Rewrap",
5214 description: "Controls where the `editor::Rewrap` action is allowed for this language",
5215 field: Box::new(SettingField {
5216 pick: |settings_content| {
5217 language_settings_field(settings_content, |language| &language.allow_rewrap)
5218 },
5219 pick_mut: |settings_content| {
5220 language_settings_field_mut(settings_content, |language| {
5221 &mut language.allow_rewrap
5222 })
5223 },
5224 }),
5225 metadata: None,
5226 files: USER | LOCAL,
5227 }),
5228 SettingsPageItem::SectionHeader("Indent Guides"),
5229 SettingsPageItem::SettingItem(SettingItem {
5230 title: "Enabled",
5231 description: "Display indent guides in the editor",
5232 field: Box::new(SettingField {
5233 pick: |settings_content| {
5234 language_settings_field(settings_content, |language| {
5235 if let Some(indent_guides) = &language.indent_guides {
5236 &indent_guides.enabled
5237 } else {
5238 &None
5239 }
5240 })
5241 },
5242 pick_mut: |settings_content| {
5243 language_settings_field_mut(settings_content, |language| {
5244 &mut language.indent_guides.get_or_insert_default().enabled
5245 })
5246 },
5247 }),
5248 metadata: None,
5249 files: USER | LOCAL,
5250 }),
5251 SettingsPageItem::SettingItem(SettingItem {
5252 title: "Line Width",
5253 description: "The width of the indent guides in pixels, between 1 and 10",
5254 field: Box::new(SettingField {
5255 pick: |settings_content| {
5256 language_settings_field(settings_content, |language| {
5257 if let Some(indent_guides) = &language.indent_guides {
5258 &indent_guides.line_width
5259 } else {
5260 &None
5261 }
5262 })
5263 },
5264 pick_mut: |settings_content| {
5265 language_settings_field_mut(settings_content, |language| {
5266 &mut language.indent_guides.get_or_insert_default().line_width
5267 })
5268 },
5269 }),
5270 metadata: None,
5271 files: USER | LOCAL,
5272 }),
5273 SettingsPageItem::SettingItem(SettingItem {
5274 title: "Active Line Width",
5275 description: "The width of the active indent guide in pixels, between 1 and 10",
5276 field: Box::new(SettingField {
5277 pick: |settings_content| {
5278 language_settings_field(settings_content, |language| {
5279 if let Some(indent_guides) = &language.indent_guides {
5280 &indent_guides.active_line_width
5281 } else {
5282 &None
5283 }
5284 })
5285 },
5286 pick_mut: |settings_content| {
5287 language_settings_field_mut(settings_content, |language| {
5288 &mut language
5289 .indent_guides
5290 .get_or_insert_default()
5291 .active_line_width
5292 })
5293 },
5294 }),
5295 metadata: None,
5296 files: USER | LOCAL,
5297 }),
5298 SettingsPageItem::SettingItem(SettingItem {
5299 title: "Coloring",
5300 description: "Determines how indent guides are colored",
5301 field: Box::new(SettingField {
5302 pick: |settings_content| {
5303 language_settings_field(settings_content, |language| {
5304 if let Some(indent_guides) = &language.indent_guides {
5305 &indent_guides.coloring
5306 } else {
5307 &None
5308 }
5309 })
5310 },
5311 pick_mut: |settings_content| {
5312 language_settings_field_mut(settings_content, |language| {
5313 &mut language.indent_guides.get_or_insert_default().coloring
5314 })
5315 },
5316 }),
5317 metadata: None,
5318 files: USER | LOCAL,
5319 }),
5320 SettingsPageItem::SettingItem(SettingItem {
5321 title: "Background Coloring",
5322 description: "Determines how indent guide backgrounds are colored",
5323 field: Box::new(SettingField {
5324 pick: |settings_content| {
5325 language_settings_field(settings_content, |language| {
5326 if let Some(indent_guides) = &language.indent_guides {
5327 &indent_guides.background_coloring
5328 } else {
5329 &None
5330 }
5331 })
5332 },
5333 pick_mut: |settings_content| {
5334 language_settings_field_mut(settings_content, |language| {
5335 &mut language
5336 .indent_guides
5337 .get_or_insert_default()
5338 .background_coloring
5339 })
5340 },
5341 }),
5342 metadata: None,
5343 files: USER | LOCAL,
5344 }),
5345 SettingsPageItem::SectionHeader("Formatting"),
5346 SettingsPageItem::SettingItem(SettingItem {
5347 title: "Format On Save",
5348 description: "Whether or not to perform a buffer format before saving",
5349 field: Box::new(
5350 // TODO(settings_ui): this setting should just be a bool
5351 SettingField {
5352 pick: |settings_content| {
5353 language_settings_field(settings_content, |language| {
5354 &language.format_on_save
5355 })
5356 },
5357 pick_mut: |settings_content| {
5358 language_settings_field_mut(settings_content, |language| {
5359 &mut language.format_on_save
5360 })
5361 },
5362 },
5363 ),
5364 metadata: None,
5365 files: USER | LOCAL,
5366 }),
5367 SettingsPageItem::SettingItem(SettingItem {
5368 title: "Remove Trailing Whitespace On Save",
5369 description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it",
5370 field: Box::new(SettingField {
5371 pick: |settings_content| {
5372 language_settings_field(settings_content, |language| {
5373 &language.remove_trailing_whitespace_on_save
5374 })
5375 },
5376 pick_mut: |settings_content| {
5377 language_settings_field_mut(settings_content, |language| {
5378 &mut language.remove_trailing_whitespace_on_save
5379 })
5380 },
5381 }),
5382 metadata: None,
5383 files: USER | LOCAL,
5384 }),
5385 SettingsPageItem::SettingItem(SettingItem {
5386 title: "Ensure Final Newline On Save",
5387 description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it",
5388 field: Box::new(SettingField {
5389 pick: |settings_content| {
5390 language_settings_field(settings_content, |language| {
5391 &language.ensure_final_newline_on_save
5392 })
5393 },
5394 pick_mut: |settings_content| {
5395 language_settings_field_mut(settings_content, |language| {
5396 &mut language.ensure_final_newline_on_save
5397 })
5398 },
5399 }),
5400 metadata: None,
5401 files: USER | LOCAL,
5402 }),
5403 SettingsPageItem::SettingItem(SettingItem {
5404 title: "Formatter",
5405 description: "How to perform a buffer format",
5406 field: Box::new(
5407 SettingField {
5408 pick: |settings_content| {
5409 language_settings_field(settings_content, |language| &language.formatter)
5410 },
5411 pick_mut: |settings_content| {
5412 language_settings_field_mut(settings_content, |language| {
5413 &mut language.formatter
5414 })
5415 },
5416 }
5417 .unimplemented(),
5418 ),
5419 metadata: None,
5420 files: USER | LOCAL,
5421 }),
5422 SettingsPageItem::SettingItem(SettingItem {
5423 title: "Use On Type Format",
5424 description: "Whether to use additional LSP queries to format (and amend) the code after every \"trigger\" symbol input, defined by LSP server capabilities",
5425 field: Box::new(SettingField {
5426 pick: |settings_content| {
5427 language_settings_field(settings_content, |language| {
5428 &language.use_on_type_format
5429 })
5430 },
5431 pick_mut: |settings_content| {
5432 language_settings_field_mut(settings_content, |language| {
5433 &mut language.use_on_type_format
5434 })
5435 },
5436 }),
5437 metadata: None,
5438 files: USER | LOCAL,
5439 }),
5440 SettingsPageItem::SectionHeader("Autoclose"),
5441 SettingsPageItem::SettingItem(SettingItem {
5442 title: "Use Autoclose",
5443 description: "Whether to automatically type closing characters for you. For example, when you type (, Zed will automatically add a closing ) at the correct position",
5444 field: Box::new(SettingField {
5445 pick: |settings_content| {
5446 language_settings_field(settings_content, |language| &language.use_autoclose)
5447 },
5448 pick_mut: |settings_content| {
5449 language_settings_field_mut(settings_content, |language| {
5450 &mut language.use_autoclose
5451 })
5452 },
5453 }),
5454 metadata: None,
5455 files: USER | LOCAL,
5456 }),
5457 SettingsPageItem::SettingItem(SettingItem {
5458 title: "Use Auto Surround",
5459 description: "Whether to automatically surround text with characters for you. For example, when you select text and type (, Zed will automatically surround text with ()",
5460 field: Box::new(SettingField {
5461 pick: |settings_content| {
5462 language_settings_field(settings_content, |language| {
5463 &language.use_auto_surround
5464 })
5465 },
5466 pick_mut: |settings_content| {
5467 language_settings_field_mut(settings_content, |language| {
5468 &mut language.use_auto_surround
5469 })
5470 },
5471 }),
5472 metadata: None,
5473 files: USER | LOCAL,
5474 }),
5475 SettingsPageItem::SettingItem(SettingItem {
5476 title: "Always Treat Brackets As Autoclosed",
5477 description: "Controls whether the closing characters are always skipped over and auto-removed no matter how they were inserted",
5478 field: Box::new(SettingField {
5479 pick: |settings_content| {
5480 language_settings_field(settings_content, |language| {
5481 &language.always_treat_brackets_as_autoclosed
5482 })
5483 },
5484 pick_mut: |settings_content| {
5485 language_settings_field_mut(settings_content, |language| {
5486 &mut language.always_treat_brackets_as_autoclosed
5487 })
5488 },
5489 }),
5490 metadata: None,
5491 files: USER | LOCAL,
5492 }),
5493 SettingsPageItem::SettingItem(SettingItem {
5494 title: "Jsx Tag Auto Close",
5495 description: "Whether to automatically close JSX tags",
5496 field: Box::new(SettingField {
5497 // TODO(settings_ui): this setting should just be a bool
5498 pick: |settings_content| {
5499 language_settings_field(settings_content, |language| {
5500 match language.jsx_tag_auto_close.as_ref() {
5501 Some(s) => &s.enabled,
5502 None => &None,
5503 }
5504 })
5505 },
5506 pick_mut: |settings_content| {
5507 language_settings_field_mut(settings_content, |language| {
5508 &mut language.jsx_tag_auto_close.get_or_insert_default().enabled
5509 })
5510 },
5511 }),
5512 metadata: None,
5513 files: USER | LOCAL,
5514 }),
5515 SettingsPageItem::SectionHeader("Edit Predictions"),
5516 SettingsPageItem::SettingItem(SettingItem {
5517 title: "Show Edit Predictions",
5518 description: "Controls whether edit predictions are shown immediately (true) or manually by triggering `editor::ShowEditPrediction` (false)",
5519 field: Box::new(SettingField {
5520 pick: |settings_content| {
5521 language_settings_field(settings_content, |language| {
5522 &language.show_edit_predictions
5523 })
5524 },
5525 pick_mut: |settings_content| {
5526 language_settings_field_mut(settings_content, |language| {
5527 &mut language.show_edit_predictions
5528 })
5529 },
5530 }),
5531 metadata: None,
5532 files: USER | LOCAL,
5533 }),
5534 SettingsPageItem::SettingItem(SettingItem {
5535 title: "Edit Predictions Disabled In",
5536 description: "Controls whether edit predictions are shown in the given language scopes",
5537 field: Box::new(
5538 SettingField {
5539 pick: |settings_content| {
5540 language_settings_field(settings_content, |language| {
5541 &language.edit_predictions_disabled_in
5542 })
5543 },
5544 pick_mut: |settings_content| {
5545 language_settings_field_mut(settings_content, |language| {
5546 &mut language.edit_predictions_disabled_in
5547 })
5548 },
5549 }
5550 .unimplemented(),
5551 ),
5552 metadata: None,
5553 files: USER | LOCAL,
5554 }),
5555 SettingsPageItem::SectionHeader("Whitespace"),
5556 SettingsPageItem::SettingItem(SettingItem {
5557 title: "Show Whitespaces",
5558 description: "Whether to show tabs and spaces in the editor",
5559 field: Box::new(SettingField {
5560 pick: |settings_content| {
5561 language_settings_field(settings_content, |language| &language.show_whitespaces)
5562 },
5563 pick_mut: |settings_content| {
5564 language_settings_field_mut(settings_content, |language| {
5565 &mut language.show_whitespaces
5566 })
5567 },
5568 }),
5569 metadata: None,
5570 files: USER | LOCAL,
5571 }),
5572 SettingsPageItem::SettingItem(SettingItem {
5573 title: "Space Whitespace Indicator",
5574 description: "Visible character used to render space characters when show_whitespaces is enabled (default: \"•\")",
5575 field: Box::new(
5576 SettingField {
5577 pick: |settings_content| {
5578 language_settings_field(settings_content, |language| {
5579 if let Some(whitespace_map) = &language.whitespace_map {
5580 &whitespace_map.space
5581 } else {
5582 &None
5583 }
5584 })
5585 },
5586 pick_mut: |settings_content| {
5587 language_settings_field_mut(settings_content, |language| {
5588 &mut language.whitespace_map.get_or_insert_default().space
5589 })
5590 },
5591 }
5592 .unimplemented(),
5593 ),
5594 metadata: None,
5595 files: USER | LOCAL,
5596 }),
5597 SettingsPageItem::SettingItem(SettingItem {
5598 title: "Tab Whitespace Indicator",
5599 description: "Visible character used to render tab characters when show_whitespaces is enabled (default: \"→\")",
5600 field: Box::new(
5601 SettingField {
5602 pick: |settings_content| {
5603 language_settings_field(settings_content, |language| {
5604 if let Some(whitespace_map) = &language.whitespace_map {
5605 &whitespace_map.tab
5606 } else {
5607 &None
5608 }
5609 })
5610 },
5611 pick_mut: |settings_content| {
5612 language_settings_field_mut(settings_content, |language| {
5613 &mut language.whitespace_map.get_or_insert_default().tab
5614 })
5615 },
5616 }
5617 .unimplemented(),
5618 ),
5619 metadata: None,
5620 files: USER | LOCAL,
5621 }),
5622 SettingsPageItem::SectionHeader("Completions"),
5623 SettingsPageItem::SettingItem(SettingItem {
5624 title: "Show Completions On Input",
5625 description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it",
5626 field: Box::new(SettingField {
5627 pick: |settings_content| {
5628 language_settings_field(settings_content, |language| {
5629 &language.show_completions_on_input
5630 })
5631 },
5632 pick_mut: |settings_content| {
5633 language_settings_field_mut(settings_content, |language| {
5634 &mut language.show_completions_on_input
5635 })
5636 },
5637 }),
5638 metadata: None,
5639 files: USER | LOCAL,
5640 }),
5641 SettingsPageItem::SettingItem(SettingItem {
5642 title: "Show Completion Documentation",
5643 description: "Whether to display inline and alongside documentation for items in the completions menu",
5644 field: Box::new(SettingField {
5645 pick: |settings_content| {
5646 language_settings_field(settings_content, |language| {
5647 &language.show_completion_documentation
5648 })
5649 },
5650 pick_mut: |settings_content| {
5651 language_settings_field_mut(settings_content, |language| {
5652 &mut language.show_completion_documentation
5653 })
5654 },
5655 }),
5656 metadata: None,
5657 files: USER | LOCAL,
5658 }),
5659 SettingsPageItem::SettingItem(SettingItem {
5660 title: "Words",
5661 description: "Controls how words are completed",
5662 field: Box::new(SettingField {
5663 pick: |settings_content| {
5664 language_settings_field(settings_content, |language| {
5665 if let Some(completions) = &language.completions {
5666 &completions.words
5667 } else {
5668 &None
5669 }
5670 })
5671 },
5672 pick_mut: |settings_content| {
5673 language_settings_field_mut(settings_content, |language| {
5674 &mut language.completions.get_or_insert_default().words
5675 })
5676 },
5677 }),
5678 metadata: None,
5679 files: USER | LOCAL,
5680 }),
5681 SettingsPageItem::SettingItem(SettingItem {
5682 title: "Words Min Length",
5683 description: "How many characters has to be in the completions query to automatically show the words-based completions",
5684 field: Box::new(SettingField {
5685 pick: |settings_content| {
5686 language_settings_field(settings_content, |language| {
5687 if let Some(completions) = &language.completions {
5688 &completions.words_min_length
5689 } else {
5690 &None
5691 }
5692 })
5693 },
5694 pick_mut: |settings_content| {
5695 language_settings_field_mut(settings_content, |language| {
5696 &mut language
5697 .completions
5698 .get_or_insert_default()
5699 .words_min_length
5700 })
5701 },
5702 }),
5703 metadata: None,
5704 files: USER | LOCAL,
5705 }),
5706 SettingsPageItem::SectionHeader("Inlay Hints"),
5707 SettingsPageItem::SettingItem(SettingItem {
5708 title: "Enabled",
5709 description: "Global switch to toggle hints on and off",
5710 field: Box::new(SettingField {
5711 pick: |settings_content| {
5712 language_settings_field(settings_content, |language| {
5713 if let Some(inlay_hints) = &language.inlay_hints {
5714 &inlay_hints.enabled
5715 } else {
5716 &None
5717 }
5718 })
5719 },
5720 pick_mut: |settings_content| {
5721 language_settings_field_mut(settings_content, |language| {
5722 &mut language.inlay_hints.get_or_insert_default().enabled
5723 })
5724 },
5725 }),
5726 metadata: None,
5727 files: USER | LOCAL,
5728 }),
5729 SettingsPageItem::SettingItem(SettingItem {
5730 title: "Show Value Hints",
5731 description: "Global switch to toggle inline values on and off when debugging",
5732 field: Box::new(SettingField {
5733 pick: |settings_content| {
5734 language_settings_field(settings_content, |language| {
5735 if let Some(inlay_hints) = &language.inlay_hints {
5736 &inlay_hints.show_value_hints
5737 } else {
5738 &None
5739 }
5740 })
5741 },
5742 pick_mut: |settings_content| {
5743 language_settings_field_mut(settings_content, |language| {
5744 &mut language
5745 .inlay_hints
5746 .get_or_insert_default()
5747 .show_value_hints
5748 })
5749 },
5750 }),
5751 metadata: None,
5752 files: USER | LOCAL,
5753 }),
5754 SettingsPageItem::SettingItem(SettingItem {
5755 title: "Show Type Hints",
5756 description: "Whether type hints should be shown",
5757 field: Box::new(SettingField {
5758 pick: |settings_content| {
5759 language_settings_field(settings_content, |language| {
5760 if let Some(inlay_hints) = &language.inlay_hints {
5761 &inlay_hints.show_type_hints
5762 } else {
5763 &None
5764 }
5765 })
5766 },
5767 pick_mut: |settings_content| {
5768 language_settings_field_mut(settings_content, |language| {
5769 &mut language.inlay_hints.get_or_insert_default().show_type_hints
5770 })
5771 },
5772 }),
5773 metadata: None,
5774 files: USER | LOCAL,
5775 }),
5776 SettingsPageItem::SettingItem(SettingItem {
5777 title: "Show Parameter Hints",
5778 description: "Whether parameter hints should be shown",
5779 field: Box::new(SettingField {
5780 pick: |settings_content| {
5781 language_settings_field(settings_content, |language| {
5782 if let Some(inlay_hints) = &language.inlay_hints {
5783 &inlay_hints.show_parameter_hints
5784 } else {
5785 &None
5786 }
5787 })
5788 },
5789 pick_mut: |settings_content| {
5790 language_settings_field_mut(settings_content, |language| {
5791 &mut language
5792 .inlay_hints
5793 .get_or_insert_default()
5794 .show_parameter_hints
5795 })
5796 },
5797 }),
5798 metadata: None,
5799 files: USER | LOCAL,
5800 }),
5801 SettingsPageItem::SettingItem(SettingItem {
5802 title: "Show Other Hints",
5803 description: "Whether other hints should be shown",
5804 field: Box::new(SettingField {
5805 pick: |settings_content| {
5806 language_settings_field(settings_content, |language| {
5807 if let Some(inlay_hints) = &language.inlay_hints {
5808 &inlay_hints.show_other_hints
5809 } else {
5810 &None
5811 }
5812 })
5813 },
5814 pick_mut: |settings_content| {
5815 language_settings_field_mut(settings_content, |language| {
5816 &mut language
5817 .inlay_hints
5818 .get_or_insert_default()
5819 .show_other_hints
5820 })
5821 },
5822 }),
5823 metadata: None,
5824 files: USER | LOCAL,
5825 }),
5826 SettingsPageItem::SettingItem(SettingItem {
5827 title: "Show Background",
5828 description: "Show a background for inlay hints",
5829 field: Box::new(SettingField {
5830 pick: |settings_content| {
5831 language_settings_field(settings_content, |language| {
5832 if let Some(inlay_hints) = &language.inlay_hints {
5833 &inlay_hints.show_background
5834 } else {
5835 &None
5836 }
5837 })
5838 },
5839 pick_mut: |settings_content| {
5840 language_settings_field_mut(settings_content, |language| {
5841 &mut language.inlay_hints.get_or_insert_default().show_background
5842 })
5843 },
5844 }),
5845 metadata: None,
5846 files: USER | LOCAL,
5847 }),
5848 SettingsPageItem::SettingItem(SettingItem {
5849 title: "Edit Debounce Ms",
5850 description: "Whether or not to debounce inlay hints updates after buffer edits (set to 0 to disable debouncing)",
5851 field: Box::new(SettingField {
5852 pick: |settings_content| {
5853 language_settings_field(settings_content, |language| {
5854 if let Some(inlay_hints) = &language.inlay_hints {
5855 &inlay_hints.edit_debounce_ms
5856 } else {
5857 &None
5858 }
5859 })
5860 },
5861 pick_mut: |settings_content| {
5862 language_settings_field_mut(settings_content, |language| {
5863 &mut language
5864 .inlay_hints
5865 .get_or_insert_default()
5866 .edit_debounce_ms
5867 })
5868 },
5869 }),
5870 metadata: None,
5871 files: USER | LOCAL,
5872 }),
5873 SettingsPageItem::SettingItem(SettingItem {
5874 title: "Scroll Debounce Ms",
5875 description: "Whether or not to debounce inlay hints updates after buffer scrolls (set to 0 to disable debouncing)",
5876 field: Box::new(SettingField {
5877 pick: |settings_content| {
5878 language_settings_field(settings_content, |language| {
5879 if let Some(inlay_hints) = &language.inlay_hints {
5880 &inlay_hints.scroll_debounce_ms
5881 } else {
5882 &None
5883 }
5884 })
5885 },
5886 pick_mut: |settings_content| {
5887 language_settings_field_mut(settings_content, |language| {
5888 &mut language
5889 .inlay_hints
5890 .get_or_insert_default()
5891 .scroll_debounce_ms
5892 })
5893 },
5894 }),
5895 metadata: None,
5896 files: USER | LOCAL,
5897 }),
5898 SettingsPageItem::SettingItem(SettingItem {
5899 title: "Toggle On Modifiers Press",
5900 description: "Toggles inlay hints (hides or shows) when the user presses the modifiers specified",
5901 field: Box::new(
5902 SettingField {
5903 pick: |settings_content| {
5904 language_settings_field(settings_content, |language| {
5905 if let Some(inlay_hints) = &language.inlay_hints {
5906 &inlay_hints.toggle_on_modifiers_press
5907 } else {
5908 &None
5909 }
5910 })
5911 },
5912 pick_mut: |settings_content| {
5913 language_settings_field_mut(settings_content, |language| {
5914 &mut language
5915 .inlay_hints
5916 .get_or_insert_default()
5917 .toggle_on_modifiers_press
5918 })
5919 },
5920 }
5921 .unimplemented(),
5922 ),
5923 metadata: None,
5924 files: USER | LOCAL,
5925 }),
5926 ];
5927 if current_language().is_none() {
5928 items.push(SettingsPageItem::SettingItem(SettingItem {
5929 title: "LSP Document Colors",
5930 description: "How to render LSP color previews in the editor",
5931 field: Box::new(SettingField {
5932 pick: |settings_content| &settings_content.editor.lsp_document_colors,
5933 pick_mut: |settings_content| &mut settings_content.editor.lsp_document_colors,
5934 }),
5935 metadata: None,
5936 files: USER,
5937 }))
5938 }
5939 items.extend([
5940 SettingsPageItem::SectionHeader("Tasks"),
5941 SettingsPageItem::SettingItem(SettingItem {
5942 title: "Enabled",
5943 description: "Whether tasks are enabled for this language",
5944 field: Box::new(SettingField {
5945 pick: |settings_content| {
5946 language_settings_field(settings_content, |language| {
5947 if let Some(tasks) = &language.tasks {
5948 &tasks.enabled
5949 } else {
5950 &None
5951 }
5952 })
5953 },
5954 pick_mut: |settings_content| {
5955 language_settings_field_mut(settings_content, |language| {
5956 &mut language.tasks.get_or_insert_default().enabled
5957 })
5958 },
5959 }),
5960 metadata: None,
5961 files: USER | LOCAL,
5962 }),
5963 SettingsPageItem::SettingItem(SettingItem {
5964 title: "Variables",
5965 description: "Extra task variables to set for a particular language",
5966 field: Box::new(
5967 SettingField {
5968 pick: |settings_content| {
5969 language_settings_field(settings_content, |language| {
5970 if let Some(tasks) = &language.tasks {
5971 &tasks.variables
5972 } else {
5973 &None
5974 }
5975 })
5976 },
5977 pick_mut: |settings_content| {
5978 language_settings_field_mut(settings_content, |language| {
5979 &mut language.tasks.get_or_insert_default().variables
5980 })
5981 },
5982 }
5983 .unimplemented(),
5984 ),
5985 metadata: None,
5986 files: USER | LOCAL,
5987 }),
5988 SettingsPageItem::SettingItem(SettingItem {
5989 title: "Prefer LSP",
5990 description: "Use LSP tasks over Zed language extension tasks",
5991 field: Box::new(SettingField {
5992 pick: |settings_content| {
5993 language_settings_field(settings_content, |language| {
5994 if let Some(tasks) = &language.tasks {
5995 &tasks.prefer_lsp
5996 } else {
5997 &None
5998 }
5999 })
6000 },
6001 pick_mut: |settings_content| {
6002 language_settings_field_mut(settings_content, |language| {
6003 &mut language.tasks.get_or_insert_default().prefer_lsp
6004 })
6005 },
6006 }),
6007 metadata: None,
6008 files: USER | LOCAL,
6009 }),
6010 SettingsPageItem::SectionHeader("Miscellaneous"),
6011 SettingsPageItem::SettingItem(SettingItem {
6012 title: "Debuggers",
6013 description: "Preferred debuggers for this language",
6014 field: Box::new(
6015 SettingField {
6016 pick: |settings_content| {
6017 language_settings_field(settings_content, |language| &language.debuggers)
6018 },
6019 pick_mut: |settings_content| {
6020 language_settings_field_mut(settings_content, |language| {
6021 &mut language.debuggers
6022 })
6023 },
6024 }
6025 .unimplemented(),
6026 ),
6027 metadata: None,
6028 files: USER | LOCAL,
6029 }),
6030 SettingsPageItem::SettingItem(SettingItem {
6031 title: "Middle Click Paste",
6032 description: "Enable middle-click paste on Linux",
6033 field: Box::new(SettingField {
6034 pick: |settings_content| &settings_content.editor.middle_click_paste,
6035 pick_mut: |settings_content| &mut settings_content.editor.middle_click_paste,
6036 }),
6037 metadata: None,
6038 files: USER,
6039 }),
6040 SettingsPageItem::SettingItem(SettingItem {
6041 title: "Extend Comment On Newline",
6042 description: "Whether to start a new line with a comment when a previous line is a comment as well",
6043 field: Box::new(SettingField {
6044 pick: |settings_content| {
6045 language_settings_field(settings_content, |language| {
6046 &language.extend_comment_on_newline
6047 })
6048 },
6049 pick_mut: |settings_content| {
6050 language_settings_field_mut(settings_content, |language| {
6051 &mut language.extend_comment_on_newline
6052 })
6053 },
6054 }),
6055 metadata: None,
6056 files: USER | LOCAL,
6057 }),
6058 ]);
6059
6060 if current_language().is_none() {
6061 items.extend([
6062 SettingsPageItem::SettingItem(SettingItem {
6063 title: "Image Viewer",
6064 description: "The unit for image file sizes",
6065 field: Box::new(SettingField {
6066 pick: |settings_content| {
6067 if let Some(image_viewer) = settings_content.image_viewer.as_ref() {
6068 &image_viewer.unit
6069 } else {
6070 &None
6071 }
6072 },
6073 pick_mut: |settings_content| {
6074 &mut settings_content.image_viewer.get_or_insert_default().unit
6075 },
6076 }),
6077 metadata: None,
6078 files: USER,
6079 }),
6080 SettingsPageItem::SettingItem(SettingItem {
6081 title: "Auto Replace Emoji Shortcode",
6082 description: "Whether to automatically replace emoji shortcodes with emoji characters",
6083 field: Box::new(SettingField {
6084 pick: |settings_content| {
6085 if let Some(message_editor) = settings_content.message_editor.as_ref() {
6086 &message_editor.auto_replace_emoji_shortcode
6087 } else {
6088 &None
6089 }
6090 },
6091 pick_mut: |settings_content| {
6092 &mut settings_content.message_editor.get_or_insert_default().auto_replace_emoji_shortcode
6093 },
6094 }),
6095 metadata: None,
6096 files: USER,
6097 }),
6098 SettingsPageItem::SettingItem(SettingItem {
6099 title: "Drop Size Target",
6100 description: "Relative size of the drop target in the editor that will open dropped file as a split pane",
6101 field: Box::new(SettingField {
6102 pick: |settings_content| {
6103 &settings_content.workspace.drop_target_size
6104 },
6105 pick_mut: |settings_content| {
6106 &mut settings_content.workspace.drop_target_size
6107 },
6108 }),
6109 metadata: None,
6110 files: USER,
6111 }),
6112 ]);
6113 }
6114 items
6115}
6116
6117/// LanguageSettings items that should be included in the "Languages & Tools" page
6118/// not the "Editor" page
6119fn non_editor_language_settings_data() -> Vec<SettingsPageItem> {
6120 vec![
6121 SettingsPageItem::SectionHeader("LSP"),
6122 SettingsPageItem::SettingItem(SettingItem {
6123 title: "Enable Language Server",
6124 description: "Whether to use language servers to provide code intelligence",
6125 field: Box::new(SettingField {
6126 pick: |settings_content| {
6127 language_settings_field(settings_content, |language| {
6128 &language.enable_language_server
6129 })
6130 },
6131 pick_mut: |settings_content| {
6132 language_settings_field_mut(settings_content, |language| {
6133 &mut language.enable_language_server
6134 })
6135 },
6136 }),
6137 metadata: None,
6138 files: USER | LOCAL,
6139 }),
6140 SettingsPageItem::SettingItem(SettingItem {
6141 title: "Language Servers",
6142 description: "The list of language servers to use (or disable) for this language",
6143 field: Box::new(
6144 SettingField {
6145 pick: |settings_content| {
6146 language_settings_field(settings_content, |language| {
6147 &language.language_servers
6148 })
6149 },
6150 pick_mut: |settings_content| {
6151 language_settings_field_mut(settings_content, |language| {
6152 &mut language.language_servers
6153 })
6154 },
6155 }
6156 .unimplemented(),
6157 ),
6158 metadata: None,
6159 files: USER | LOCAL,
6160 }),
6161 SettingsPageItem::SettingItem(SettingItem {
6162 title: "Linked Edits",
6163 description: "Whether to perform linked edits of associated ranges, if the LS supports it. For example, when editing opening <html> tag, the contents of the closing </html> tag will be edited as well",
6164 field: Box::new(SettingField {
6165 pick: |settings_content| {
6166 language_settings_field(settings_content, |language| &language.linked_edits)
6167 },
6168 pick_mut: |settings_content| {
6169 language_settings_field_mut(settings_content, |language| {
6170 &mut language.linked_edits
6171 })
6172 },
6173 }),
6174 metadata: None,
6175 files: USER | LOCAL,
6176 }),
6177 SettingsPageItem::SettingItem(SettingItem {
6178 title: "Go To Definition Fallback",
6179 description: "Whether to follow-up empty go to definition responses from the language server",
6180 field: Box::new(SettingField {
6181 pick: |settings_content| &settings_content.editor.go_to_definition_fallback,
6182 pick_mut: |settings_content| &mut settings_content.editor.go_to_definition_fallback,
6183 }),
6184 metadata: None,
6185 files: USER,
6186 }),
6187 SettingsPageItem::SectionHeader("LSP Completions"),
6188 SettingsPageItem::SettingItem(SettingItem {
6189 title: "Enabled",
6190 description: "Whether to fetch LSP completions or not",
6191 field: Box::new(SettingField {
6192 pick: |settings_content| {
6193 language_settings_field(settings_content, |language| {
6194 if let Some(completions) = &language.completions {
6195 &completions.lsp
6196 } else {
6197 &None
6198 }
6199 })
6200 },
6201 pick_mut: |settings_content| {
6202 language_settings_field_mut(settings_content, |language| {
6203 &mut language.completions.get_or_insert_default().lsp
6204 })
6205 },
6206 }),
6207 metadata: None,
6208 files: USER | LOCAL,
6209 }),
6210 SettingsPageItem::SettingItem(SettingItem {
6211 title: "Fetch Timeout (milliseconds)",
6212 description: "When fetching LSP completions, determines how long to wait for a response of a particular server (set to 0 to wait indefinitely)",
6213 field: Box::new(SettingField {
6214 pick: |settings_content| {
6215 language_settings_field(settings_content, |language| {
6216 if let Some(completions) = &language.completions {
6217 &completions.lsp_fetch_timeout_ms
6218 } else {
6219 &None
6220 }
6221 })
6222 },
6223 pick_mut: |settings_content| {
6224 language_settings_field_mut(settings_content, |language| {
6225 &mut language
6226 .completions
6227 .get_or_insert_default()
6228 .lsp_fetch_timeout_ms
6229 })
6230 },
6231 }),
6232 metadata: None,
6233 files: USER | LOCAL,
6234 }),
6235 SettingsPageItem::SettingItem(SettingItem {
6236 title: "Insert Mode",
6237 description: "Controls how LSP completions are inserted",
6238 field: Box::new(SettingField {
6239 pick: |settings_content| {
6240 language_settings_field(settings_content, |language| {
6241 if let Some(completions) = &language.completions {
6242 &completions.lsp_insert_mode
6243 } else {
6244 &None
6245 }
6246 })
6247 },
6248 pick_mut: |settings_content| {
6249 language_settings_field_mut(settings_content, |language| {
6250 &mut language.completions.get_or_insert_default().lsp_insert_mode
6251 })
6252 },
6253 }),
6254 metadata: None,
6255 files: USER | LOCAL,
6256 }),
6257 SettingsPageItem::SectionHeader("Debuggers"),
6258 SettingsPageItem::SettingItem(SettingItem {
6259 title: "Debuggers",
6260 description: "Preferred debuggers for this language",
6261 field: Box::new(
6262 SettingField {
6263 pick: |settings_content| {
6264 language_settings_field(settings_content, |language| &language.debuggers)
6265 },
6266 pick_mut: |settings_content| {
6267 language_settings_field_mut(settings_content, |language| {
6268 &mut language.debuggers
6269 })
6270 },
6271 }
6272 .unimplemented(),
6273 ),
6274 metadata: None,
6275 files: USER | LOCAL,
6276 }),
6277 SettingsPageItem::SectionHeader("Prettier"),
6278 SettingsPageItem::SettingItem(SettingItem {
6279 title: "Allowed",
6280 description: "Enables or disables formatting with Prettier for a given language",
6281 field: Box::new(SettingField {
6282 pick: |settings_content| {
6283 language_settings_field(settings_content, |language| {
6284 if let Some(prettier) = &language.prettier {
6285 &prettier.allowed
6286 } else {
6287 &None
6288 }
6289 })
6290 },
6291 pick_mut: |settings_content| {
6292 language_settings_field_mut(settings_content, |language| {
6293 &mut language.prettier.get_or_insert_default().allowed
6294 })
6295 },
6296 }),
6297 metadata: None,
6298 files: USER | LOCAL,
6299 }),
6300 SettingsPageItem::SettingItem(SettingItem {
6301 title: "Parser",
6302 description: "Forces Prettier integration to use a specific parser name when formatting files with the language",
6303 field: Box::new(SettingField {
6304 pick: |settings_content| {
6305 language_settings_field(settings_content, |language| {
6306 if let Some(prettier) = &language.prettier {
6307 &prettier.parser
6308 } else {
6309 &None
6310 }
6311 })
6312 },
6313 pick_mut: |settings_content| {
6314 language_settings_field_mut(settings_content, |language| {
6315 &mut language.prettier.get_or_insert_default().parser
6316 })
6317 },
6318 }),
6319 metadata: None,
6320 files: USER | LOCAL,
6321 }),
6322 SettingsPageItem::SettingItem(SettingItem {
6323 title: "Plugins",
6324 description: "Forces Prettier integration to use specific plugins when formatting files with the language",
6325 field: Box::new(
6326 SettingField {
6327 pick: |settings_content| {
6328 language_settings_field(settings_content, |language| {
6329 if let Some(prettier) = &language.prettier {
6330 &prettier.plugins
6331 } else {
6332 &None
6333 }
6334 })
6335 },
6336 pick_mut: |settings_content| {
6337 language_settings_field_mut(settings_content, |language| {
6338 &mut language.prettier.get_or_insert_default().plugins
6339 })
6340 },
6341 }
6342 .unimplemented(),
6343 ),
6344 metadata: None,
6345 files: USER | LOCAL,
6346 }),
6347 SettingsPageItem::SettingItem(SettingItem {
6348 title: "Options",
6349 description: "Default Prettier options, in the format as in package.json section for Prettier",
6350 field: Box::new(
6351 SettingField {
6352 pick: |settings_content| {
6353 language_settings_field(settings_content, |language| {
6354 if let Some(prettier) = &language.prettier {
6355 &prettier.options
6356 } else {
6357 &None
6358 }
6359 })
6360 },
6361 pick_mut: |settings_content| {
6362 language_settings_field_mut(settings_content, |language| {
6363 &mut language.prettier.get_or_insert_default().options
6364 })
6365 },
6366 }
6367 .unimplemented(),
6368 ),
6369 metadata: None,
6370 files: USER | LOCAL,
6371 }),
6372 ]
6373}