1use core::num;
2
3use gpui::App;
4use language::CursorShape;
5use project::project_settings::DiagnosticSeverity;
6pub use settings::{
7 CurrentLineHighlight, DelayMs, DisplayIn, DocumentColorsRenderMode, DoubleClickInMultibuffer,
8 GoToDefinitionFallback, HideMouseMode, MinimapThumb, MinimapThumbBorder, MultiCursorModifier,
9 ScrollBeyondLastLine, ScrollbarDiagnostics, SeedQuerySetting, ShowMinimap, SnippetSortOrder,
10};
11use settings::{RelativeLineNumbers, Settings};
12use ui::scrollbars::{ScrollbarVisibility, ShowScrollbar};
13
14/// Imports from the VSCode settings at
15/// https://code.visualstudio.com/docs/reference/default-settings
16#[derive(Clone)]
17pub struct EditorSettings {
18 pub cursor_blink: bool,
19 pub cursor_shape: Option<CursorShape>,
20 pub current_line_highlight: CurrentLineHighlight,
21 pub selection_highlight: bool,
22 pub rounded_selection: bool,
23 pub lsp_highlight_debounce: DelayMs,
24 pub hover_popover_enabled: bool,
25 pub hover_popover_delay: DelayMs,
26 pub toolbar: Toolbar,
27 pub scrollbar: Scrollbar,
28 pub minimap: Minimap,
29 pub gutter: Gutter,
30 pub scroll_beyond_last_line: ScrollBeyondLastLine,
31 pub vertical_scroll_margin: f64,
32 pub autoscroll_on_clicks: bool,
33 pub horizontal_scroll_margin: f32,
34 pub scroll_sensitivity: f32,
35 pub fast_scroll_sensitivity: f32,
36 pub relative_line_numbers: RelativeLineNumbers,
37 pub seed_search_query_from_cursor: SeedQuerySetting,
38 pub use_smartcase_search: bool,
39 pub multi_cursor_modifier: MultiCursorModifier,
40 pub redact_private_values: bool,
41 pub expand_excerpt_lines: u32,
42 pub excerpt_context_lines: u32,
43 pub middle_click_paste: bool,
44 pub double_click_in_multibuffer: DoubleClickInMultibuffer,
45 pub search_wrap: bool,
46 pub search: SearchSettings,
47 pub auto_signature_help: bool,
48 pub show_signature_help_after_edits: bool,
49 pub go_to_definition_fallback: GoToDefinitionFallback,
50 pub jupyter: Jupyter,
51 pub hide_mouse: Option<HideMouseMode>,
52 pub snippet_sort_order: SnippetSortOrder,
53 pub diagnostics_max_severity: Option<DiagnosticSeverity>,
54 pub inline_code_actions: bool,
55 pub drag_and_drop_selection: DragAndDropSelection,
56 pub lsp_document_colors: DocumentColorsRenderMode,
57 pub minimum_contrast_for_highlights: f32,
58 pub completion_menu_scrollbar: ShowScrollbar,
59}
60#[derive(Debug, Clone)]
61pub struct Jupyter {
62 /// Whether the Jupyter feature is enabled.
63 ///
64 /// Default: true
65 pub enabled: bool,
66}
67
68#[derive(Clone, Debug, PartialEq, Eq)]
69pub struct Toolbar {
70 pub breadcrumbs: bool,
71 pub quick_actions: bool,
72 pub selections_menu: bool,
73 pub agent_review: bool,
74 pub code_actions: bool,
75}
76
77#[derive(Copy, Clone, Debug, PartialEq, Eq)]
78pub struct Scrollbar {
79 pub show: ShowScrollbar,
80 pub git_diff: bool,
81 pub selected_text: bool,
82 pub selected_symbol: bool,
83 pub search_results: bool,
84 pub diagnostics: ScrollbarDiagnostics,
85 pub cursors: bool,
86 pub axes: ScrollbarAxes,
87}
88
89#[derive(Copy, Clone, Debug, PartialEq)]
90pub struct Minimap {
91 pub show: ShowMinimap,
92 pub display_in: DisplayIn,
93 pub thumb: MinimapThumb,
94 pub thumb_border: MinimapThumbBorder,
95 pub current_line_highlight: Option<CurrentLineHighlight>,
96 pub max_width_columns: num::NonZeroU32,
97}
98
99impl Minimap {
100 pub fn minimap_enabled(&self) -> bool {
101 self.show != ShowMinimap::Never
102 }
103
104 #[inline]
105 pub fn on_active_editor(&self) -> bool {
106 self.display_in == DisplayIn::ActiveEditor
107 }
108
109 pub fn with_show_override(self) -> Self {
110 Self {
111 show: ShowMinimap::Always,
112 ..self
113 }
114 }
115}
116
117#[derive(Copy, Clone, Debug, PartialEq, Eq)]
118pub struct Gutter {
119 pub min_line_number_digits: usize,
120 pub line_numbers: bool,
121 pub runnables: bool,
122 pub breakpoints: bool,
123 pub folds: bool,
124}
125
126/// Forcefully enable or disable the scrollbar for each axis
127#[derive(Copy, Clone, Debug, PartialEq, Eq)]
128pub struct ScrollbarAxes {
129 /// When false, forcefully disables the horizontal scrollbar. Otherwise, obey other settings.
130 ///
131 /// Default: true
132 pub horizontal: bool,
133
134 /// When false, forcefully disables the vertical scrollbar. Otherwise, obey other settings.
135 ///
136 /// Default: true
137 pub vertical: bool,
138}
139
140/// Whether to allow drag and drop text selection in buffer.
141#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
142pub struct DragAndDropSelection {
143 /// When true, enables drag and drop text selection in buffer.
144 ///
145 /// Default: true
146 pub enabled: bool,
147
148 /// The delay in milliseconds that must elapse before drag and drop is allowed. Otherwise, a new text selection is created.
149 ///
150 /// Default: 300
151 pub delay: DelayMs,
152}
153
154/// Default options for buffer and project search items.
155#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
156pub struct SearchSettings {
157 /// Whether to show the project search button in the status bar.
158 pub button: bool,
159 pub whole_word: bool,
160 pub case_sensitive: bool,
161 pub include_ignored: bool,
162 pub regex: bool,
163 pub center_on_match: bool,
164}
165
166impl EditorSettings {
167 pub fn jupyter_enabled(cx: &App) -> bool {
168 EditorSettings::get_global(cx).jupyter.enabled
169 }
170}
171
172impl ScrollbarVisibility for EditorSettings {
173 fn visibility(&self, _cx: &App) -> ShowScrollbar {
174 self.scrollbar.show
175 }
176}
177
178impl Settings for EditorSettings {
179 fn from_settings(content: &settings::SettingsContent) -> Self {
180 let editor = content.editor.clone();
181 let scrollbar = editor.scrollbar.unwrap();
182 let minimap = editor.minimap.unwrap();
183 let gutter = editor.gutter.unwrap();
184 let axes = scrollbar.axes.unwrap();
185 let toolbar = editor.toolbar.unwrap();
186 let search = editor.search.unwrap();
187 let drag_and_drop_selection = editor.drag_and_drop_selection.unwrap();
188 Self {
189 cursor_blink: editor.cursor_blink.unwrap(),
190 cursor_shape: editor.cursor_shape.map(Into::into),
191 current_line_highlight: editor.current_line_highlight.unwrap(),
192 selection_highlight: editor.selection_highlight.unwrap(),
193 rounded_selection: editor.rounded_selection.unwrap(),
194 lsp_highlight_debounce: editor.lsp_highlight_debounce.unwrap(),
195 hover_popover_enabled: editor.hover_popover_enabled.unwrap(),
196 hover_popover_delay: editor.hover_popover_delay.unwrap(),
197 toolbar: Toolbar {
198 breadcrumbs: toolbar.breadcrumbs.unwrap(),
199 quick_actions: toolbar.quick_actions.unwrap(),
200 selections_menu: toolbar.selections_menu.unwrap(),
201 agent_review: toolbar.agent_review.unwrap(),
202 code_actions: toolbar.code_actions.unwrap(),
203 },
204 scrollbar: Scrollbar {
205 show: scrollbar.show.map(Into::into).unwrap(),
206 git_diff: scrollbar.git_diff.unwrap(),
207 selected_text: scrollbar.selected_text.unwrap(),
208 selected_symbol: scrollbar.selected_symbol.unwrap(),
209 search_results: scrollbar.search_results.unwrap(),
210 diagnostics: scrollbar.diagnostics.unwrap(),
211 cursors: scrollbar.cursors.unwrap(),
212 axes: ScrollbarAxes {
213 horizontal: axes.horizontal.unwrap(),
214 vertical: axes.vertical.unwrap(),
215 },
216 },
217 minimap: Minimap {
218 show: minimap.show.unwrap(),
219 display_in: minimap.display_in.unwrap(),
220 thumb: minimap.thumb.unwrap(),
221 thumb_border: minimap.thumb_border.unwrap(),
222 current_line_highlight: minimap.current_line_highlight,
223 max_width_columns: minimap.max_width_columns.unwrap(),
224 },
225 gutter: Gutter {
226 min_line_number_digits: gutter.min_line_number_digits.unwrap(),
227 line_numbers: gutter.line_numbers.unwrap(),
228 runnables: gutter.runnables.unwrap(),
229 breakpoints: gutter.breakpoints.unwrap(),
230 folds: gutter.folds.unwrap(),
231 },
232 scroll_beyond_last_line: editor.scroll_beyond_last_line.unwrap(),
233 vertical_scroll_margin: editor.vertical_scroll_margin.unwrap() as f64,
234 autoscroll_on_clicks: editor.autoscroll_on_clicks.unwrap(),
235 horizontal_scroll_margin: editor.horizontal_scroll_margin.unwrap(),
236 scroll_sensitivity: editor.scroll_sensitivity.unwrap(),
237 fast_scroll_sensitivity: editor.fast_scroll_sensitivity.unwrap(),
238 relative_line_numbers: editor.relative_line_numbers.unwrap(),
239 seed_search_query_from_cursor: editor.seed_search_query_from_cursor.unwrap(),
240 use_smartcase_search: editor.use_smartcase_search.unwrap(),
241 multi_cursor_modifier: editor.multi_cursor_modifier.unwrap(),
242 redact_private_values: editor.redact_private_values.unwrap(),
243 expand_excerpt_lines: editor.expand_excerpt_lines.unwrap(),
244 excerpt_context_lines: editor.excerpt_context_lines.unwrap(),
245 middle_click_paste: editor.middle_click_paste.unwrap(),
246 double_click_in_multibuffer: editor.double_click_in_multibuffer.unwrap(),
247 search_wrap: editor.search_wrap.unwrap(),
248 search: SearchSettings {
249 button: search.button.unwrap(),
250 whole_word: search.whole_word.unwrap(),
251 case_sensitive: search.case_sensitive.unwrap(),
252 include_ignored: search.include_ignored.unwrap(),
253 regex: search.regex.unwrap(),
254 center_on_match: search.center_on_match.unwrap(),
255 },
256 auto_signature_help: editor.auto_signature_help.unwrap(),
257 show_signature_help_after_edits: editor.show_signature_help_after_edits.unwrap(),
258 go_to_definition_fallback: editor.go_to_definition_fallback.unwrap(),
259 jupyter: Jupyter {
260 enabled: editor.jupyter.unwrap().enabled.unwrap(),
261 },
262 hide_mouse: editor.hide_mouse,
263 snippet_sort_order: editor.snippet_sort_order.unwrap(),
264 diagnostics_max_severity: editor.diagnostics_max_severity.map(Into::into),
265 inline_code_actions: editor.inline_code_actions.unwrap(),
266 drag_and_drop_selection: DragAndDropSelection {
267 enabled: drag_and_drop_selection.enabled.unwrap(),
268 delay: drag_and_drop_selection.delay.unwrap(),
269 },
270 lsp_document_colors: editor.lsp_document_colors.unwrap(),
271 minimum_contrast_for_highlights: editor.minimum_contrast_for_highlights.unwrap().0,
272 completion_menu_scrollbar: editor.completion_menu_scrollbar.map(Into::into).unwrap(),
273 }
274 }
275}