1use gpui::App;
2use language::CursorShape;
3use project::project_settings::DiagnosticSeverity;
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6use settings::{Settings, SettingsSources, VsCodeSettings};
7use util::serde::default_true;
8
9/// Imports from the VSCode settings at
10/// https://code.visualstudio.com/docs/reference/default-settings
11#[derive(Deserialize, Clone)]
12pub struct EditorSettings {
13 pub cursor_blink: bool,
14 pub cursor_shape: Option<CursorShape>,
15 pub current_line_highlight: CurrentLineHighlight,
16 pub selection_highlight: bool,
17 pub lsp_highlight_debounce: u64,
18 pub hover_popover_enabled: bool,
19 pub hover_popover_delay: u64,
20 pub toolbar: Toolbar,
21 pub scrollbar: Scrollbar,
22 pub minimap: Minimap,
23 pub gutter: Gutter,
24 pub scroll_beyond_last_line: ScrollBeyondLastLine,
25 pub vertical_scroll_margin: f32,
26 pub autoscroll_on_clicks: bool,
27 pub horizontal_scroll_margin: f32,
28 pub scroll_sensitivity: f32,
29 pub fast_scroll_sensitivity: f32,
30 pub relative_line_numbers: bool,
31 pub seed_search_query_from_cursor: SeedQuerySetting,
32 pub use_smartcase_search: bool,
33 pub multi_cursor_modifier: MultiCursorModifier,
34 pub redact_private_values: bool,
35 pub expand_excerpt_lines: u32,
36 pub middle_click_paste: bool,
37 #[serde(default)]
38 pub double_click_in_multibuffer: DoubleClickInMultibuffer,
39 pub search_wrap: bool,
40 #[serde(default)]
41 pub search: SearchSettings,
42 pub auto_signature_help: bool,
43 pub show_signature_help_after_edits: bool,
44 #[serde(default)]
45 pub go_to_definition_fallback: GoToDefinitionFallback,
46 pub jupyter: Jupyter,
47 pub hide_mouse: Option<HideMouseMode>,
48 pub snippet_sort_order: SnippetSortOrder,
49 #[serde(default)]
50 pub diagnostics_max_severity: Option<DiagnosticSeverity>,
51 pub inline_code_actions: bool,
52 pub drag_and_drop_selection: bool,
53 pub lsp_document_colors: DocumentColorsRenderMode,
54}
55
56/// How to render LSP `textDocument/documentColor` colors in the editor.
57#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
58#[serde(rename_all = "snake_case")]
59pub enum DocumentColorsRenderMode {
60 /// Do not query and render document colors.
61 None,
62 /// Render document colors as inlay hints near the color text.
63 #[default]
64 Inlay,
65 /// Draw a border around the color text.
66 Border,
67 /// Draw a background behind the color text.
68 Background,
69}
70
71#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
72#[serde(rename_all = "snake_case")]
73pub enum CurrentLineHighlight {
74 // Don't highlight the current line.
75 None,
76 // Highlight the gutter area.
77 Gutter,
78 // Highlight the editor area.
79 Line,
80 // Highlight the full line.
81 All,
82}
83
84/// When to populate a new search's query based on the text under the cursor.
85#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
86#[serde(rename_all = "snake_case")]
87pub enum SeedQuerySetting {
88 /// Always populate the search query with the word under the cursor.
89 Always,
90 /// Only populate the search query when there is text selected.
91 Selection,
92 /// Never populate the search query
93 Never,
94}
95
96/// What to do when multibuffer is double clicked in some of its excerpts (parts of singleton buffers).
97#[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
98#[serde(rename_all = "snake_case")]
99pub enum DoubleClickInMultibuffer {
100 /// Behave as a regular buffer and select the whole word.
101 #[default]
102 Select,
103 /// Open the excerpt clicked as a new buffer in the new tab, if no `alt` modifier was pressed during double click.
104 /// Otherwise, behave as a regular buffer and select the whole word.
105 Open,
106}
107
108#[derive(Debug, Clone, Deserialize)]
109pub struct Jupyter {
110 /// Whether the Jupyter feature is enabled.
111 ///
112 /// Default: true
113 pub enabled: bool,
114}
115
116#[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
117#[serde(rename_all = "snake_case")]
118pub struct JupyterContent {
119 /// Whether the Jupyter feature is enabled.
120 ///
121 /// Default: true
122 pub enabled: Option<bool>,
123}
124
125#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
126pub struct Toolbar {
127 pub breadcrumbs: bool,
128 pub quick_actions: bool,
129 pub selections_menu: bool,
130 pub agent_review: bool,
131 pub code_actions: bool,
132}
133
134#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
135pub struct Scrollbar {
136 pub show: ShowScrollbar,
137 pub git_diff: bool,
138 pub selected_text: bool,
139 pub selected_symbol: bool,
140 pub search_results: bool,
141 pub diagnostics: ScrollbarDiagnostics,
142 pub cursors: bool,
143 pub axes: ScrollbarAxes,
144}
145
146#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
147pub struct Minimap {
148 pub show: ShowMinimap,
149 pub display_in: DisplayIn,
150 pub thumb: MinimapThumb,
151 pub thumb_border: MinimapThumbBorder,
152 pub current_line_highlight: Option<CurrentLineHighlight>,
153}
154
155impl Minimap {
156 pub fn minimap_enabled(&self) -> bool {
157 self.show != ShowMinimap::Never
158 }
159
160 #[inline]
161 pub fn on_active_editor(&self) -> bool {
162 self.display_in == DisplayIn::ActiveEditor
163 }
164
165 pub fn with_show_override(self) -> Self {
166 Self {
167 show: ShowMinimap::Always,
168 ..self
169 }
170 }
171}
172
173#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
174pub struct Gutter {
175 pub min_line_number_digits: usize,
176 pub line_numbers: bool,
177 pub runnables: bool,
178 pub breakpoints: bool,
179 pub folds: bool,
180}
181
182/// When to show the scrollbar in the editor.
183///
184/// Default: auto
185#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
186#[serde(rename_all = "snake_case")]
187pub enum ShowScrollbar {
188 /// Show the scrollbar if there's important information or
189 /// follow the system's configured behavior.
190 Auto,
191 /// Match the system's configured behavior.
192 System,
193 /// Always show the scrollbar.
194 Always,
195 /// Never show the scrollbar.
196 Never,
197}
198
199/// When to show the minimap in the editor.
200///
201/// Default: never
202#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
203#[serde(rename_all = "snake_case")]
204pub enum ShowMinimap {
205 /// Follow the visibility of the scrollbar.
206 Auto,
207 /// Always show the minimap.
208 Always,
209 /// Never show the minimap.
210 #[default]
211 Never,
212}
213
214/// Where to show the minimap in the editor.
215///
216/// Default: all_editors
217#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
218#[serde(rename_all = "snake_case")]
219pub enum DisplayIn {
220 /// Show on all open editors.
221 AllEditors,
222 /// Show the minimap on the active editor only.
223 #[default]
224 ActiveEditor,
225}
226
227/// When to show the minimap thumb.
228///
229/// Default: always
230#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
231#[serde(rename_all = "snake_case")]
232pub enum MinimapThumb {
233 /// Show the minimap thumb only when the mouse is hovering over the minimap.
234 Hover,
235 /// Always show the minimap thumb.
236 #[default]
237 Always,
238}
239
240/// Defines the border style for the minimap's scrollbar thumb.
241///
242/// Default: left_open
243#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
244#[serde(rename_all = "snake_case")]
245pub enum MinimapThumbBorder {
246 /// Displays a border on all sides of the thumb.
247 Full,
248 /// Displays a border on all sides except the left side of the thumb.
249 #[default]
250 LeftOpen,
251 /// Displays a border on all sides except the right side of the thumb.
252 RightOpen,
253 /// Displays a border only on the left side of the thumb.
254 LeftOnly,
255 /// Displays the thumb without any border.
256 None,
257}
258
259/// Forcefully enable or disable the scrollbar for each axis
260#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
261#[serde(rename_all = "lowercase")]
262pub struct ScrollbarAxes {
263 /// When false, forcefully disables the horizontal scrollbar. Otherwise, obey other settings.
264 ///
265 /// Default: true
266 pub horizontal: bool,
267
268 /// When false, forcefully disables the vertical scrollbar. Otherwise, obey other settings.
269 ///
270 /// Default: true
271 pub vertical: bool,
272}
273
274/// Which diagnostic indicators to show in the scrollbar.
275///
276/// Default: all
277#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
278#[serde(rename_all = "lowercase")]
279pub enum ScrollbarDiagnostics {
280 /// Show all diagnostic levels: hint, information, warnings, error.
281 All,
282 /// Show only the following diagnostic levels: information, warning, error.
283 Information,
284 /// Show only the following diagnostic levels: warning, error.
285 Warning,
286 /// Show only the following diagnostic level: error.
287 Error,
288 /// Do not show diagnostics.
289 None,
290}
291
292/// The key to use for adding multiple cursors
293///
294/// Default: alt
295#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
296#[serde(rename_all = "snake_case")]
297pub enum MultiCursorModifier {
298 Alt,
299 #[serde(alias = "cmd", alias = "ctrl")]
300 CmdOrCtrl,
301}
302
303/// Whether the editor will scroll beyond the last line.
304///
305/// Default: one_page
306#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
307#[serde(rename_all = "snake_case")]
308pub enum ScrollBeyondLastLine {
309 /// The editor will not scroll beyond the last line.
310 Off,
311
312 /// The editor will scroll beyond the last line by one page.
313 OnePage,
314
315 /// The editor will scroll beyond the last line by the same number of lines as vertical_scroll_margin.
316 VerticalScrollMargin,
317}
318
319/// Default options for buffer and project search items.
320#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
321pub struct SearchSettings {
322 /// Whether to show the project search button in the status bar.
323 #[serde(default = "default_true")]
324 pub button: bool,
325 #[serde(default)]
326 pub whole_word: bool,
327 #[serde(default)]
328 pub case_sensitive: bool,
329 #[serde(default)]
330 pub include_ignored: bool,
331 #[serde(default)]
332 pub regex: bool,
333}
334
335/// What to do when go to definition yields no results.
336#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
337#[serde(rename_all = "snake_case")]
338pub enum GoToDefinitionFallback {
339 /// Disables the fallback.
340 None,
341 /// Looks up references of the same symbol instead.
342 #[default]
343 FindAllReferences,
344}
345
346/// Determines when the mouse cursor should be hidden in an editor or input box.
347///
348/// Default: on_typing_and_movement
349#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
350#[serde(rename_all = "snake_case")]
351pub enum HideMouseMode {
352 /// Never hide the mouse cursor
353 Never,
354 /// Hide only when typing
355 OnTyping,
356 /// Hide on both typing and cursor movement
357 #[default]
358 OnTypingAndMovement,
359}
360
361/// Determines how snippets are sorted relative to other completion items.
362///
363/// Default: inline
364#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
365#[serde(rename_all = "snake_case")]
366pub enum SnippetSortOrder {
367 /// Place snippets at the top of the completion list
368 Top,
369 /// Sort snippets normally using the default comparison logic
370 #[default]
371 Inline,
372 /// Place snippets at the bottom of the completion list
373 Bottom,
374}
375
376#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
377#[schemars(deny_unknown_fields)]
378pub struct EditorSettingsContent {
379 /// Whether the cursor blinks in the editor.
380 ///
381 /// Default: true
382 pub cursor_blink: Option<bool>,
383 /// Cursor shape for the default editor.
384 /// Can be "bar", "block", "underline", or "hollow".
385 ///
386 /// Default: None
387 pub cursor_shape: Option<CursorShape>,
388 /// Determines when the mouse cursor should be hidden in an editor or input box.
389 ///
390 /// Default: on_typing_and_movement
391 pub hide_mouse: Option<HideMouseMode>,
392 /// Determines how snippets are sorted relative to other completion items.
393 ///
394 /// Default: inline
395 pub snippet_sort_order: Option<SnippetSortOrder>,
396 /// How to highlight the current line in the editor.
397 ///
398 /// Default: all
399 pub current_line_highlight: Option<CurrentLineHighlight>,
400 /// Whether to highlight all occurrences of the selected text in an editor.
401 ///
402 /// Default: true
403 pub selection_highlight: Option<bool>,
404 /// The debounce delay before querying highlights from the language
405 /// server based on the current cursor location.
406 ///
407 /// Default: 75
408 pub lsp_highlight_debounce: Option<u64>,
409 /// Whether to show the informational hover box when moving the mouse
410 /// over symbols in the editor.
411 ///
412 /// Default: true
413 pub hover_popover_enabled: Option<bool>,
414 /// Time to wait in milliseconds before showing the informational hover box.
415 ///
416 /// Default: 300
417 pub hover_popover_delay: Option<u64>,
418 /// Toolbar related settings
419 pub toolbar: Option<ToolbarContent>,
420 /// Scrollbar related settings
421 pub scrollbar: Option<ScrollbarContent>,
422 /// Minimap related settings
423 pub minimap: Option<MinimapContent>,
424 /// Gutter related settings
425 pub gutter: Option<GutterContent>,
426 /// Whether the editor will scroll beyond the last line.
427 ///
428 /// Default: one_page
429 pub scroll_beyond_last_line: Option<ScrollBeyondLastLine>,
430 /// The number of lines to keep above/below the cursor when auto-scrolling.
431 ///
432 /// Default: 3.
433 pub vertical_scroll_margin: Option<f32>,
434 /// Whether to scroll when clicking near the edge of the visible text area.
435 ///
436 /// Default: false
437 pub autoscroll_on_clicks: Option<bool>,
438 /// The number of characters to keep on either side when scrolling with the mouse.
439 ///
440 /// Default: 5.
441 pub horizontal_scroll_margin: Option<f32>,
442 /// Scroll sensitivity multiplier. This multiplier is applied
443 /// to both the horizontal and vertical delta values while scrolling.
444 ///
445 /// Default: 1.0
446 pub scroll_sensitivity: Option<f32>,
447 /// Scroll sensitivity multiplier for fast scrolling. This multiplier is applied
448 /// to both the horizontal and vertical delta values while scrolling. Fast scrolling
449 /// happens when a user holds the alt or option key while scrolling.
450 ///
451 /// Default: 4.0
452 pub fast_scroll_sensitivity: Option<f32>,
453 /// Whether the line numbers on editors gutter are relative or not.
454 ///
455 /// Default: false
456 pub relative_line_numbers: Option<bool>,
457 /// When to populate a new search's query based on the text under the cursor.
458 ///
459 /// Default: always
460 pub seed_search_query_from_cursor: Option<SeedQuerySetting>,
461 pub use_smartcase_search: Option<bool>,
462 /// Determines the modifier to be used to add multiple cursors with the mouse. The open hover link mouse gestures will adapt such that it do not conflict with the multicursor modifier.
463 ///
464 /// Default: alt
465 pub multi_cursor_modifier: Option<MultiCursorModifier>,
466 /// Hide the values of variables in `private` files, as defined by the
467 /// private_files setting. This only changes the visual representation,
468 /// the values are still present in the file and can be selected / copied / pasted
469 ///
470 /// Default: false
471 pub redact_private_values: Option<bool>,
472
473 /// How many lines to expand the multibuffer excerpts by default
474 ///
475 /// Default: 3
476 pub expand_excerpt_lines: Option<u32>,
477
478 /// Whether to enable middle-click paste on Linux
479 ///
480 /// Default: true
481 pub middle_click_paste: Option<bool>,
482
483 /// What to do when multibuffer is double clicked in some of its excerpts
484 /// (parts of singleton buffers).
485 ///
486 /// Default: select
487 pub double_click_in_multibuffer: Option<DoubleClickInMultibuffer>,
488 /// Whether the editor search results will loop
489 ///
490 /// Default: true
491 pub search_wrap: Option<bool>,
492
493 /// Defaults to use when opening a new buffer and project search items.
494 ///
495 /// Default: nothing is enabled
496 pub search: Option<SearchSettings>,
497
498 /// Whether to automatically show a signature help pop-up or not.
499 ///
500 /// Default: false
501 pub auto_signature_help: Option<bool>,
502
503 /// Whether to show the signature help pop-up after completions or bracket pairs inserted.
504 ///
505 /// Default: false
506 pub show_signature_help_after_edits: Option<bool>,
507
508 /// Whether to follow-up empty go to definition responses from the language server or not.
509 /// `FindAllReferences` allows to look up references of the same symbol instead.
510 /// `None` disables the fallback.
511 ///
512 /// Default: FindAllReferences
513 pub go_to_definition_fallback: Option<GoToDefinitionFallback>,
514
515 /// Jupyter REPL settings.
516 pub jupyter: Option<JupyterContent>,
517
518 /// Which level to use to filter out diagnostics displayed in the editor.
519 ///
520 /// Affects the editor rendering only, and does not interrupt
521 /// the functionality of diagnostics fetching and project diagnostics editor.
522 /// Which files containing diagnostic errors/warnings to mark in the tabs.
523 /// Diagnostics are only shown when file icons are also active.
524 ///
525 /// Shows all diagnostics if not specified.
526 ///
527 /// Default: warning
528 #[serde(default)]
529 pub diagnostics_max_severity: Option<DiagnosticSeverity>,
530
531 /// Whether to show code action button at start of buffer line.
532 ///
533 /// Default: true
534 pub inline_code_actions: Option<bool>,
535
536 /// Whether to allow drag and drop text selection in buffer.
537 ///
538 /// Default: true
539 pub drag_and_drop_selection: Option<bool>,
540
541 /// How to render LSP `textDocument/documentColor` colors in the editor.
542 ///
543 /// Default: [`DocumentColorsRenderMode::Inlay`]
544 pub lsp_document_colors: Option<DocumentColorsRenderMode>,
545}
546
547// Toolbar related settings
548#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
549pub struct ToolbarContent {
550 /// Whether to display breadcrumbs in the editor toolbar.
551 ///
552 /// Default: true
553 pub breadcrumbs: Option<bool>,
554 /// Whether to display quick action buttons in the editor toolbar.
555 ///
556 /// Default: true
557 pub quick_actions: Option<bool>,
558 /// Whether to show the selections menu in the editor toolbar.
559 ///
560 /// Default: true
561 pub selections_menu: Option<bool>,
562 /// Whether to display Agent review buttons in the editor toolbar.
563 /// Only applicable while reviewing a file edited by the Agent.
564 ///
565 /// Default: true
566 pub agent_review: Option<bool>,
567 /// Whether to display code action buttons in the editor toolbar.
568 ///
569 /// Default: false
570 pub code_actions: Option<bool>,
571}
572
573/// Scrollbar related settings
574#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)]
575pub struct ScrollbarContent {
576 /// When to show the scrollbar in the editor.
577 ///
578 /// Default: auto
579 pub show: Option<ShowScrollbar>,
580 /// Whether to show git diff indicators in the scrollbar.
581 ///
582 /// Default: true
583 pub git_diff: Option<bool>,
584 /// Whether to show buffer search result indicators in the scrollbar.
585 ///
586 /// Default: true
587 pub search_results: Option<bool>,
588 /// Whether to show selected text occurrences in the scrollbar.
589 ///
590 /// Default: true
591 pub selected_text: Option<bool>,
592 /// Whether to show selected symbol occurrences in the scrollbar.
593 ///
594 /// Default: true
595 pub selected_symbol: Option<bool>,
596 /// Which diagnostic indicators to show in the scrollbar:
597 ///
598 /// Default: all
599 pub diagnostics: Option<ScrollbarDiagnostics>,
600 /// Whether to show cursor positions in the scrollbar.
601 ///
602 /// Default: true
603 pub cursors: Option<bool>,
604 /// Forcefully enable or disable the scrollbar for each axis
605 pub axes: Option<ScrollbarAxesContent>,
606}
607
608/// Minimap related settings
609#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
610pub struct MinimapContent {
611 /// When to show the minimap in the editor.
612 ///
613 /// Default: never
614 pub show: Option<ShowMinimap>,
615
616 /// Where to show the minimap in the editor.
617 ///
618 /// Default: [`DisplayIn::ActiveEditor`]
619 pub display_in: Option<DisplayIn>,
620
621 /// When to show the minimap thumb.
622 ///
623 /// Default: always
624 pub thumb: Option<MinimapThumb>,
625
626 /// Defines the border style for the minimap's scrollbar thumb.
627 ///
628 /// Default: left_open
629 pub thumb_border: Option<MinimapThumbBorder>,
630
631 /// How to highlight the current line in the minimap.
632 ///
633 /// Default: inherits editor line highlights setting
634 pub current_line_highlight: Option<Option<CurrentLineHighlight>>,
635}
636
637/// Forcefully enable or disable the scrollbar for each axis
638#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)]
639pub struct ScrollbarAxesContent {
640 /// When false, forcefully disables the horizontal scrollbar. Otherwise, obey other settings.
641 ///
642 /// Default: true
643 horizontal: Option<bool>,
644
645 /// When false, forcefully disables the vertical scrollbar. Otherwise, obey other settings.
646 ///
647 /// Default: true
648 vertical: Option<bool>,
649}
650
651/// Gutter related settings
652#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
653pub struct GutterContent {
654 /// Whether to show line numbers in the gutter.
655 ///
656 /// Default: true
657 pub line_numbers: Option<bool>,
658 /// Minimum number of characters to reserve space for in the gutter.
659 ///
660 /// Default: 4
661 pub min_line_number_digits: Option<usize>,
662 /// Whether to show runnable buttons in the gutter.
663 ///
664 /// Default: true
665 pub runnables: Option<bool>,
666 /// Whether to show breakpoints in the gutter.
667 ///
668 /// Default: true
669 pub breakpoints: Option<bool>,
670 /// Whether to show fold buttons in the gutter.
671 ///
672 /// Default: true
673 pub folds: Option<bool>,
674}
675
676impl EditorSettings {
677 pub fn jupyter_enabled(cx: &App) -> bool {
678 EditorSettings::get_global(cx).jupyter.enabled
679 }
680}
681
682impl Settings for EditorSettings {
683 const KEY: Option<&'static str> = None;
684
685 type FileContent = EditorSettingsContent;
686
687 fn load(sources: SettingsSources<Self::FileContent>, _: &mut App) -> anyhow::Result<Self> {
688 sources.json_merge()
689 }
690
691 fn import_from_vscode(vscode: &VsCodeSettings, current: &mut Self::FileContent) {
692 vscode.enum_setting(
693 "editor.cursorBlinking",
694 &mut current.cursor_blink,
695 |s| match s {
696 "blink" | "phase" | "expand" | "smooth" => Some(true),
697 "solid" => Some(false),
698 _ => None,
699 },
700 );
701 vscode.enum_setting(
702 "editor.cursorStyle",
703 &mut current.cursor_shape,
704 |s| match s {
705 "block" => Some(CursorShape::Block),
706 "block-outline" => Some(CursorShape::Hollow),
707 "line" | "line-thin" => Some(CursorShape::Bar),
708 "underline" | "underline-thin" => Some(CursorShape::Underline),
709 _ => None,
710 },
711 );
712
713 vscode.enum_setting(
714 "editor.renderLineHighlight",
715 &mut current.current_line_highlight,
716 |s| match s {
717 "gutter" => Some(CurrentLineHighlight::Gutter),
718 "line" => Some(CurrentLineHighlight::Line),
719 "all" => Some(CurrentLineHighlight::All),
720 _ => None,
721 },
722 );
723
724 vscode.bool_setting(
725 "editor.selectionHighlight",
726 &mut current.selection_highlight,
727 );
728 vscode.bool_setting("editor.hover.enabled", &mut current.hover_popover_enabled);
729 vscode.u64_setting("editor.hover.delay", &mut current.hover_popover_delay);
730
731 let mut gutter = GutterContent::default();
732 vscode.enum_setting(
733 "editor.showFoldingControls",
734 &mut gutter.folds,
735 |s| match s {
736 "always" | "mouseover" => Some(true),
737 "never" => Some(false),
738 _ => None,
739 },
740 );
741 vscode.enum_setting(
742 "editor.lineNumbers",
743 &mut gutter.line_numbers,
744 |s| match s {
745 "on" | "relative" => Some(true),
746 "off" => Some(false),
747 _ => None,
748 },
749 );
750 if let Some(old_gutter) = current.gutter.as_mut() {
751 if gutter.folds.is_some() {
752 old_gutter.folds = gutter.folds
753 }
754 if gutter.line_numbers.is_some() {
755 old_gutter.line_numbers = gutter.line_numbers
756 }
757 } else {
758 if gutter != GutterContent::default() {
759 current.gutter = Some(gutter)
760 }
761 }
762 if let Some(b) = vscode.read_bool("editor.scrollBeyondLastLine") {
763 current.scroll_beyond_last_line = Some(if b {
764 ScrollBeyondLastLine::OnePage
765 } else {
766 ScrollBeyondLastLine::Off
767 })
768 }
769
770 let mut scrollbar_axes = ScrollbarAxesContent::default();
771 vscode.enum_setting(
772 "editor.scrollbar.horizontal",
773 &mut scrollbar_axes.horizontal,
774 |s| match s {
775 "auto" | "visible" => Some(true),
776 "hidden" => Some(false),
777 _ => None,
778 },
779 );
780 vscode.enum_setting(
781 "editor.scrollbar.vertical",
782 &mut scrollbar_axes.horizontal,
783 |s| match s {
784 "auto" | "visible" => Some(true),
785 "hidden" => Some(false),
786 _ => None,
787 },
788 );
789
790 if scrollbar_axes != ScrollbarAxesContent::default() {
791 let scrollbar_settings = current.scrollbar.get_or_insert_default();
792 let axes_settings = scrollbar_settings.axes.get_or_insert_default();
793
794 if let Some(vertical) = scrollbar_axes.vertical {
795 axes_settings.vertical = Some(vertical);
796 }
797 if let Some(horizontal) = scrollbar_axes.horizontal {
798 axes_settings.horizontal = Some(horizontal);
799 }
800 }
801
802 // TODO: check if this does the int->float conversion?
803 vscode.f32_setting(
804 "editor.cursorSurroundingLines",
805 &mut current.vertical_scroll_margin,
806 );
807 vscode.f32_setting(
808 "editor.mouseWheelScrollSensitivity",
809 &mut current.scroll_sensitivity,
810 );
811 vscode.f32_setting(
812 "editor.fastScrollSensitivity",
813 &mut current.fast_scroll_sensitivity,
814 );
815 if Some("relative") == vscode.read_string("editor.lineNumbers") {
816 current.relative_line_numbers = Some(true);
817 }
818
819 vscode.enum_setting(
820 "editor.find.seedSearchStringFromSelection",
821 &mut current.seed_search_query_from_cursor,
822 |s| match s {
823 "always" => Some(SeedQuerySetting::Always),
824 "selection" => Some(SeedQuerySetting::Selection),
825 "never" => Some(SeedQuerySetting::Never),
826 _ => None,
827 },
828 );
829 vscode.bool_setting("search.smartCase", &mut current.use_smartcase_search);
830 vscode.enum_setting(
831 "editor.multiCursorModifier",
832 &mut current.multi_cursor_modifier,
833 |s| match s {
834 "ctrlCmd" => Some(MultiCursorModifier::CmdOrCtrl),
835 "alt" => Some(MultiCursorModifier::Alt),
836 _ => None,
837 },
838 );
839
840 vscode.bool_setting(
841 "editor.parameterHints.enabled",
842 &mut current.auto_signature_help,
843 );
844 vscode.bool_setting(
845 "editor.parameterHints.enabled",
846 &mut current.show_signature_help_after_edits,
847 );
848
849 if let Some(use_ignored) = vscode.read_bool("search.useIgnoreFiles") {
850 let search = current.search.get_or_insert_default();
851 search.include_ignored = use_ignored;
852 }
853
854 let mut minimap = MinimapContent::default();
855 let minimap_enabled = vscode.read_bool("editor.minimap.enabled").unwrap_or(true);
856 let autohide = vscode.read_bool("editor.minimap.autohide");
857 if minimap_enabled {
858 if let Some(false) = autohide {
859 minimap.show = Some(ShowMinimap::Always);
860 } else {
861 minimap.show = Some(ShowMinimap::Auto);
862 }
863 } else {
864 minimap.show = Some(ShowMinimap::Never);
865 }
866
867 vscode.enum_setting(
868 "editor.minimap.showSlider",
869 &mut minimap.thumb,
870 |s| match s {
871 "always" => Some(MinimapThumb::Always),
872 "mouseover" => Some(MinimapThumb::Hover),
873 _ => None,
874 },
875 );
876
877 if minimap != MinimapContent::default() {
878 current.minimap = Some(minimap)
879 }
880 }
881}