1use gpui::AppContext;
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4use settings::{Settings, SettingsSources};
5
6#[derive(Deserialize, Clone)]
7pub struct EditorSettings {
8 pub cursor_blink: bool,
9 pub hover_popover_enabled: bool,
10 pub show_completions_on_input: bool,
11 pub show_completion_documentation: bool,
12 pub completion_documentation_secondary_query_debounce: u64,
13 pub use_on_type_format: bool,
14 pub toolbar: Toolbar,
15 pub scrollbar: Scrollbar,
16 pub gutter: Gutter,
17 pub vertical_scroll_margin: f32,
18 pub relative_line_numbers: bool,
19 pub seed_search_query_from_cursor: SeedQuerySetting,
20 pub multi_cursor_modifier: MultiCursorModifier,
21 pub redact_private_values: bool,
22 #[serde(default)]
23 pub double_click_in_multibuffer: DoubleClickInMultibuffer,
24}
25
26/// When to populate a new search's query based on the text under the cursor.
27#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
28#[serde(rename_all = "snake_case")]
29pub enum SeedQuerySetting {
30 /// Always populate the search query with the word under the cursor.
31 Always,
32 /// Only populate the search query when there is text selected.
33 Selection,
34 /// Never populate the search query
35 Never,
36}
37
38/// What to do when multibuffer is double clicked in some of its excerpts (parts of singleton buffers).
39#[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
40#[serde(rename_all = "snake_case")]
41pub enum DoubleClickInMultibuffer {
42 /// Behave as a regular buffer and select the whole word.
43 #[default]
44 Select,
45 /// Open the excerpt clicked as a new buffer in the new tab, if no `alt` modifier was pressed during double click.
46 /// Otherwise, behave as a regular buffer and select the whole word.
47 Open,
48}
49
50#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
51pub struct Toolbar {
52 pub breadcrumbs: bool,
53 pub quick_actions: bool,
54}
55
56#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
57pub struct Scrollbar {
58 pub show: ShowScrollbar,
59 pub git_diff: bool,
60 pub selections: bool,
61 pub symbols_selections: bool,
62 pub diagnostics: bool,
63}
64
65#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
66pub struct Gutter {
67 pub line_numbers: bool,
68 pub code_actions: bool,
69 pub folds: bool,
70}
71
72/// When to show the scrollbar in the editor.
73///
74/// Default: auto
75#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
76#[serde(rename_all = "snake_case")]
77pub enum ShowScrollbar {
78 /// Show the scrollbar if there's important information or
79 /// follow the system's configured behavior.
80 Auto,
81 /// Match the system's configured behavior.
82 System,
83 /// Always show the scrollbar.
84 Always,
85 /// Never show the scrollbar.
86 Never,
87}
88
89/// The key to use for adding multiple cursors
90///
91/// Default: alt
92#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
93#[serde(rename_all = "snake_case")]
94pub enum MultiCursorModifier {
95 Alt,
96 #[serde(alias = "cmd", alias = "ctrl")]
97 CmdOrCtrl,
98}
99
100#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
101pub struct EditorSettingsContent {
102 /// Whether the cursor blinks in the editor.
103 ///
104 /// Default: true
105 pub cursor_blink: Option<bool>,
106 /// Whether to show the informational hover box when moving the mouse
107 /// over symbols in the editor.
108 ///
109 /// Default: true
110 pub hover_popover_enabled: Option<bool>,
111 /// Whether to pop the completions menu while typing in an editor without
112 /// explicitly requesting it.
113 ///
114 /// Default: true
115 pub show_completions_on_input: Option<bool>,
116 /// Whether to display inline and alongside documentation for items in the
117 /// completions menu.
118 ///
119 /// Default: true
120 pub show_completion_documentation: Option<bool>,
121 /// The debounce delay before re-querying the language server for completion
122 /// documentation when not included in original completion list.
123 ///
124 /// Default: 300 ms
125 pub completion_documentation_secondary_query_debounce: Option<u64>,
126 /// Whether to use additional LSP queries to format (and amend) the code after
127 /// every "trigger" symbol input, defined by LSP server capabilities.
128 ///
129 /// Default: true
130 pub use_on_type_format: Option<bool>,
131 /// Toolbar related settings
132 pub toolbar: Option<ToolbarContent>,
133 /// Scrollbar related settings
134 pub scrollbar: Option<ScrollbarContent>,
135 /// Gutter related settings
136 pub gutter: Option<GutterContent>,
137 /// The number of lines to keep above/below the cursor when auto-scrolling.
138 ///
139 /// Default: 3.
140 pub vertical_scroll_margin: Option<f32>,
141 /// Whether the line numbers on editors gutter are relative or not.
142 ///
143 /// Default: false
144 pub relative_line_numbers: Option<bool>,
145 /// When to populate a new search's query based on the text under the cursor.
146 ///
147 /// Default: always
148 pub seed_search_query_from_cursor: Option<SeedQuerySetting>,
149 /// The key to use for adding multiple cursors
150 ///
151 /// Default: alt
152 pub multi_cursor_modifier: Option<MultiCursorModifier>,
153 /// Hide the values of variables in `private` files, as defined by the
154 /// private_files setting. This only changes the visual representation,
155 /// the values are still present in the file and can be selected / copied / pasted
156 ///
157 /// Default: false
158 pub redact_private_values: Option<bool>,
159
160 /// What to do when multibuffer is double clicked in some of its excerpts
161 /// (parts of singleton buffers).
162 ///
163 /// Default: select
164 pub double_click_in_multibuffer: Option<DoubleClickInMultibuffer>,
165}
166
167// Toolbar related settings
168#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
169pub struct ToolbarContent {
170 /// Whether to display breadcrumbs in the editor toolbar.
171 ///
172 /// Default: true
173 pub breadcrumbs: Option<bool>,
174 /// Whether to display quik action buttons in the editor toolbar.
175 ///
176 /// Default: true
177 pub quick_actions: Option<bool>,
178}
179
180/// Scrollbar related settings
181#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
182pub struct ScrollbarContent {
183 /// When to show the scrollbar in the editor.
184 ///
185 /// Default: auto
186 pub show: Option<ShowScrollbar>,
187 /// Whether to show git diff indicators in the scrollbar.
188 ///
189 /// Default: true
190 pub git_diff: Option<bool>,
191 /// Whether to show buffer search result markers in the scrollbar.
192 ///
193 /// Default: true
194 pub selections: Option<bool>,
195 /// Whether to show symbols highlighted markers in the scrollbar.
196 ///
197 /// Default: true
198 pub symbols_selections: Option<bool>,
199 /// Whether to show diagnostic indicators in the scrollbar.
200 ///
201 /// Default: true
202 pub diagnostics: Option<bool>,
203}
204
205/// Gutter related settings
206#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
207pub struct GutterContent {
208 /// Whether to show line numbers in the gutter.
209 ///
210 /// Default: true
211 pub line_numbers: Option<bool>,
212 /// Whether to show code action buttons in the gutter.
213 ///
214 /// Default: true
215 pub code_actions: Option<bool>,
216 /// Whether to show fold buttons in the gutter.
217 ///
218 /// Default: true
219 pub folds: Option<bool>,
220}
221
222impl Settings for EditorSettings {
223 const KEY: Option<&'static str> = None;
224
225 type FileContent = EditorSettingsContent;
226
227 fn load(
228 sources: SettingsSources<Self::FileContent>,
229 _: &mut AppContext,
230 ) -> anyhow::Result<Self> {
231 sources.json_merge()
232 }
233}