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