1mod agent;
2mod editor;
3mod extension;
4mod fallible_options;
5mod language;
6mod language_model;
7pub mod merge_from;
8mod project;
9mod serde_helper;
10mod terminal;
11mod theme;
12mod workspace;
13
14pub use agent::*;
15pub use editor::*;
16pub use extension::*;
17pub use fallible_options::*;
18pub use language::*;
19pub use language_model::*;
20pub use merge_from::MergeFrom as MergeFromTrait;
21pub use project::*;
22use serde::de::DeserializeOwned;
23pub use serde_helper::{
24 serialize_f32_with_two_decimal_places, serialize_optional_f32_with_two_decimal_places,
25};
26use settings_json::parse_json_with_comments;
27pub use terminal::*;
28pub use theme::*;
29pub use workspace::*;
30
31use collections::{HashMap, IndexMap};
32use schemars::JsonSchema;
33use serde::{Deserialize, Serialize};
34use settings_macros::{MergeFrom, with_fallible_options};
35use std::collections::BTreeSet;
36use std::sync::Arc;
37pub use util::serde::default_true;
38
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub enum ParseStatus {
41 /// Settings were parsed successfully
42 Success,
43 /// Settings failed to parse
44 Failed { error: String },
45}
46
47#[with_fallible_options]
48#[derive(Debug, PartialEq, Default, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)]
49pub struct SettingsContent {
50 #[serde(flatten)]
51 pub project: ProjectSettingsContent,
52
53 #[serde(flatten)]
54 pub theme: Box<ThemeSettingsContent>,
55
56 #[serde(flatten)]
57 pub extension: ExtensionSettingsContent,
58
59 #[serde(flatten)]
60 pub workspace: WorkspaceSettingsContent,
61
62 #[serde(flatten)]
63 pub editor: EditorSettingsContent,
64
65 #[serde(flatten)]
66 pub remote: RemoteSettingsContent,
67
68 /// Settings related to the file finder.
69 pub file_finder: Option<FileFinderSettingsContent>,
70
71 pub git_panel: Option<GitPanelSettingsContent>,
72
73 pub tabs: Option<ItemSettingsContent>,
74 pub tab_bar: Option<TabBarSettingsContent>,
75 pub status_bar: Option<StatusBarSettingsContent>,
76
77 pub preview_tabs: Option<PreviewTabsSettingsContent>,
78
79 pub agent: Option<AgentSettingsContent>,
80 pub agent_servers: Option<AllAgentServersSettings>,
81
82 /// Configuration of audio in Zed.
83 pub audio: Option<AudioSettingsContent>,
84
85 /// Whether or not to automatically check for updates.
86 ///
87 /// Default: true
88 pub auto_update: Option<bool>,
89
90 /// This base keymap settings adjusts the default keybindings in Zed to be similar
91 /// to other common code editors. By default, Zed's keymap closely follows VSCode's
92 /// keymap, with minor adjustments, this corresponds to the "VSCode" setting.
93 ///
94 /// Default: VSCode
95 pub base_keymap: Option<BaseKeymapContent>,
96
97 /// Configuration for the collab panel visual settings.
98 pub collaboration_panel: Option<PanelSettingsContent>,
99
100 pub debugger: Option<DebuggerSettingsContent>,
101
102 /// Configuration for Diagnostics-related features.
103 pub diagnostics: Option<DiagnosticsSettingsContent>,
104
105 /// Configuration for Git-related features
106 pub git: Option<GitSettings>,
107
108 /// Common language server settings.
109 pub global_lsp_settings: Option<GlobalLspSettingsContent>,
110
111 /// The settings for the image viewer.
112 pub image_viewer: Option<ImageViewerSettingsContent>,
113
114 pub repl: Option<ReplSettingsContent>,
115
116 /// Whether or not to enable Helix mode.
117 ///
118 /// Default: false
119 pub helix_mode: Option<bool>,
120
121 pub journal: Option<JournalSettingsContent>,
122
123 /// A map of log scopes to the desired log level.
124 /// Useful for filtering out noisy logs or enabling more verbose logging.
125 ///
126 /// Example: {"log": {"client": "warn"}}
127 pub log: Option<HashMap<String, String>>,
128
129 pub line_indicator_format: Option<LineIndicatorFormat>,
130
131 pub language_models: Option<AllLanguageModelSettingsContent>,
132
133 pub outline_panel: Option<OutlinePanelSettingsContent>,
134
135 pub project_panel: Option<ProjectPanelSettingsContent>,
136
137 /// Configuration for the Message Editor
138 pub message_editor: Option<MessageEditorSettings>,
139
140 /// Configuration for Node-related features
141 pub node: Option<NodeBinarySettings>,
142
143 /// Configuration for the Notification Panel
144 pub notification_panel: Option<NotificationPanelSettingsContent>,
145
146 pub proxy: Option<String>,
147
148 /// The URL of the Zed server to connect to.
149 pub server_url: Option<String>,
150
151 /// Configuration for session-related features
152 pub session: Option<SessionSettingsContent>,
153 /// Control what info is collected by Zed.
154 pub telemetry: Option<TelemetrySettingsContent>,
155
156 /// Configuration of the terminal in Zed.
157 pub terminal: Option<TerminalSettingsContent>,
158
159 pub title_bar: Option<TitleBarSettingsContent>,
160
161 /// Whether or not to enable Vim mode.
162 ///
163 /// Default: false
164 pub vim_mode: Option<bool>,
165
166 // Settings related to calls in Zed
167 pub calls: Option<CallSettingsContent>,
168
169 /// Whether to disable all AI features in Zed.
170 ///
171 /// Default: false
172 pub disable_ai: Option<SaturatingBool>,
173
174 /// Settings for the which-key popup.
175 pub which_key: Option<WhichKeySettingsContent>,
176
177 /// Settings related to Vim mode in Zed.
178 pub vim: Option<VimSettingsContent>,
179}
180
181impl SettingsContent {
182 pub fn languages_mut(&mut self) -> &mut HashMap<String, LanguageSettingsContent> {
183 &mut self.project.all_languages.languages.0
184 }
185}
186
187// These impls are there to optimize builds by avoiding monomorphization downstream. Yes, they're repetitive, but using default impls
188// break the optimization, for whatever reason.
189pub trait RootUserSettings: Sized + DeserializeOwned {
190 fn parse_json(json: &str) -> (Option<Self>, ParseStatus);
191 fn parse_json_with_comments(json: &str) -> anyhow::Result<Self>;
192}
193
194impl RootUserSettings for SettingsContent {
195 fn parse_json(json: &str) -> (Option<Self>, ParseStatus) {
196 fallible_options::parse_json(json)
197 }
198 fn parse_json_with_comments(json: &str) -> anyhow::Result<Self> {
199 parse_json_with_comments(json)
200 }
201}
202// Explicit opt-in instead of blanket impl to avoid monomorphizing downstream. Just a hunch though.
203impl RootUserSettings for Option<SettingsContent> {
204 fn parse_json(json: &str) -> (Option<Self>, ParseStatus) {
205 fallible_options::parse_json(json)
206 }
207 fn parse_json_with_comments(json: &str) -> anyhow::Result<Self> {
208 parse_json_with_comments(json)
209 }
210}
211impl RootUserSettings for UserSettingsContent {
212 fn parse_json(json: &str) -> (Option<Self>, ParseStatus) {
213 fallible_options::parse_json(json)
214 }
215 fn parse_json_with_comments(json: &str) -> anyhow::Result<Self> {
216 parse_json_with_comments(json)
217 }
218}
219
220#[with_fallible_options]
221#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)]
222pub struct UserSettingsContent {
223 #[serde(flatten)]
224 pub content: Box<SettingsContent>,
225
226 pub dev: Option<Box<SettingsContent>>,
227 pub nightly: Option<Box<SettingsContent>>,
228 pub preview: Option<Box<SettingsContent>>,
229 pub stable: Option<Box<SettingsContent>>,
230
231 pub macos: Option<Box<SettingsContent>>,
232 pub windows: Option<Box<SettingsContent>>,
233 pub linux: Option<Box<SettingsContent>>,
234
235 #[serde(default)]
236 pub profiles: IndexMap<String, SettingsContent>,
237}
238
239pub struct ExtensionsSettingsContent {
240 pub all_languages: AllLanguageSettingsContent,
241}
242
243/// Base key bindings scheme. Base keymaps can be overridden with user keymaps.
244///
245/// Default: VSCode
246#[derive(
247 Copy,
248 Clone,
249 Debug,
250 Serialize,
251 Deserialize,
252 JsonSchema,
253 MergeFrom,
254 PartialEq,
255 Eq,
256 Default,
257 strum::VariantArray,
258)]
259pub enum BaseKeymapContent {
260 #[default]
261 VSCode,
262 JetBrains,
263 SublimeText,
264 Atom,
265 TextMate,
266 Emacs,
267 Cursor,
268 None,
269}
270
271impl strum::VariantNames for BaseKeymapContent {
272 const VARIANTS: &'static [&'static str] = &[
273 "VSCode",
274 "JetBrains",
275 "Sublime Text",
276 "Atom",
277 "TextMate",
278 "Emacs",
279 "Cursor",
280 "None",
281 ];
282}
283
284#[with_fallible_options]
285#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
286pub struct TitleBarSettingsContent {
287 /// Whether to show the branch icon beside branch switcher in the title bar.
288 ///
289 /// Default: false
290 pub show_branch_icon: Option<bool>,
291 /// Whether to show onboarding banners in the title bar.
292 ///
293 /// Default: true
294 pub show_onboarding_banner: Option<bool>,
295 /// Whether to show user avatar in the title bar.
296 ///
297 /// Default: true
298 pub show_user_picture: Option<bool>,
299 /// Whether to show the branch name button in the titlebar.
300 ///
301 /// Default: true
302 pub show_branch_name: Option<bool>,
303 /// Whether to show the project host and name in the titlebar.
304 ///
305 /// Default: true
306 pub show_project_items: Option<bool>,
307 /// Whether to show the sign in button in the title bar.
308 ///
309 /// Default: true
310 pub show_sign_in: Option<bool>,
311 /// Whether to show the user menu button in the title bar.
312 ///
313 /// Default: true
314 pub show_user_menu: Option<bool>,
315 /// Whether to show the menus in the title bar.
316 ///
317 /// Default: false
318 pub show_menus: Option<bool>,
319}
320
321/// Configuration of audio in Zed.
322#[with_fallible_options]
323#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
324pub struct AudioSettingsContent {
325 /// Opt into the new audio system.
326 ///
327 /// You need to rejoin a call for this setting to apply
328 #[serde(rename = "experimental.rodio_audio")]
329 pub rodio_audio: Option<bool>, // default is false
330 /// Requires 'rodio_audio: true'
331 ///
332 /// Automatically increase or decrease you microphone's volume. This affects how
333 /// loud you sound to others.
334 ///
335 /// Recommended: off (default)
336 /// Microphones are too quite in zed, until everyone is on experimental
337 /// audio and has auto speaker volume on this will make you very loud
338 /// compared to other speakers.
339 #[serde(rename = "experimental.auto_microphone_volume")]
340 pub auto_microphone_volume: Option<bool>,
341 /// Requires 'rodio_audio: true'
342 ///
343 /// Automatically increate or decrease the volume of other call members.
344 /// This only affects how things sound for you.
345 #[serde(rename = "experimental.auto_speaker_volume")]
346 pub auto_speaker_volume: Option<bool>,
347 /// Requires 'rodio_audio: true'
348 ///
349 /// Remove background noises. Works great for typing, cars, dogs, AC. Does
350 /// not work well on music.
351 #[serde(rename = "experimental.denoise")]
352 pub denoise: Option<bool>,
353 /// Requires 'rodio_audio: true'
354 ///
355 /// Use audio parameters compatible with the previous versions of
356 /// experimental audio and non-experimental audio. When this is false you
357 /// will sound strange to anyone not on the latest experimental audio. In
358 /// the future we will migrate by setting this to false
359 ///
360 /// You need to rejoin a call for this setting to apply
361 #[serde(rename = "experimental.legacy_audio_compatible")]
362 pub legacy_audio_compatible: Option<bool>,
363}
364
365/// Control what info is collected by Zed.
366#[with_fallible_options]
367#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Debug, MergeFrom)]
368pub struct TelemetrySettingsContent {
369 /// Send debug info like crash reports.
370 ///
371 /// Default: true
372 pub diagnostics: Option<bool>,
373 /// Send anonymized usage data like what languages you're using Zed with.
374 ///
375 /// Default: true
376 pub metrics: Option<bool>,
377}
378
379impl Default for TelemetrySettingsContent {
380 fn default() -> Self {
381 Self {
382 diagnostics: Some(true),
383 metrics: Some(true),
384 }
385 }
386}
387
388#[with_fallible_options]
389#[derive(Default, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Clone, MergeFrom)]
390pub struct DebuggerSettingsContent {
391 /// Determines the stepping granularity.
392 ///
393 /// Default: line
394 pub stepping_granularity: Option<SteppingGranularity>,
395 /// Whether the breakpoints should be reused across Zed sessions.
396 ///
397 /// Default: true
398 pub save_breakpoints: Option<bool>,
399 /// Whether to show the debug button in the status bar.
400 ///
401 /// Default: true
402 pub button: Option<bool>,
403 /// Time in milliseconds until timeout error when connecting to a TCP debug adapter
404 ///
405 /// Default: 2000ms
406 pub timeout: Option<u64>,
407 /// Whether to log messages between active debug adapters and Zed
408 ///
409 /// Default: true
410 pub log_dap_communications: Option<bool>,
411 /// Whether to format dap messages in when adding them to debug adapter logger
412 ///
413 /// Default: true
414 pub format_dap_log_messages: Option<bool>,
415 /// The dock position of the debug panel
416 ///
417 /// Default: Bottom
418 pub dock: Option<DockPosition>,
419}
420
421/// The granularity of one 'step' in the stepping requests `next`, `stepIn`, `stepOut`, and `stepBack`.
422#[derive(
423 PartialEq,
424 Eq,
425 Debug,
426 Hash,
427 Clone,
428 Copy,
429 Deserialize,
430 Serialize,
431 JsonSchema,
432 MergeFrom,
433 strum::VariantArray,
434 strum::VariantNames,
435)]
436#[serde(rename_all = "snake_case")]
437pub enum SteppingGranularity {
438 /// The step should allow the program to run until the current statement has finished executing.
439 /// The meaning of a statement is determined by the adapter and it may be considered equivalent to a line.
440 /// For example 'for(int i = 0; i < 10; i++)' could be considered to have 3 statements 'int i = 0', 'i < 10', and 'i++'.
441 Statement,
442 /// The step should allow the program to run until the current source line has executed.
443 Line,
444 /// The step should allow one instruction to execute (e.g. one x86 instruction).
445 Instruction,
446}
447
448#[derive(
449 Copy,
450 Clone,
451 Debug,
452 Serialize,
453 Deserialize,
454 JsonSchema,
455 MergeFrom,
456 PartialEq,
457 Eq,
458 strum::VariantArray,
459 strum::VariantNames,
460)]
461#[serde(rename_all = "snake_case")]
462pub enum DockPosition {
463 Left,
464 Bottom,
465 Right,
466}
467
468/// Settings for slash commands.
469#[with_fallible_options]
470#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, MergeFrom, PartialEq, Eq)]
471pub struct SlashCommandSettings {
472 /// Settings for the `/cargo-workspace` slash command.
473 pub cargo_workspace: Option<CargoWorkspaceCommandSettings>,
474}
475
476/// Settings for the `/cargo-workspace` slash command.
477#[with_fallible_options]
478#[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema, MergeFrom, PartialEq, Eq)]
479pub struct CargoWorkspaceCommandSettings {
480 /// Whether `/cargo-workspace` is enabled.
481 pub enabled: Option<bool>,
482}
483
484/// Configuration of voice calls in Zed.
485#[with_fallible_options]
486#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
487pub struct CallSettingsContent {
488 /// Whether the microphone should be muted when joining a channel or a call.
489 ///
490 /// Default: false
491 pub mute_on_join: Option<bool>,
492
493 /// Whether your current project should be shared when joining an empty channel.
494 ///
495 /// Default: false
496 pub share_on_join: Option<bool>,
497}
498
499#[with_fallible_options]
500#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
501pub struct GitPanelSettingsContent {
502 /// Whether to show the panel button in the status bar.
503 ///
504 /// Default: true
505 pub button: Option<bool>,
506 /// Where to dock the panel.
507 ///
508 /// Default: left
509 pub dock: Option<DockPosition>,
510 /// Default width of the panel in pixels.
511 ///
512 /// Default: 360
513 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
514 pub default_width: Option<f32>,
515 /// How entry statuses are displayed.
516 ///
517 /// Default: icon
518 pub status_style: Option<StatusStyle>,
519 /// How and when the scrollbar should be displayed.
520 ///
521 /// Default: inherits editor scrollbar settings
522 pub scrollbar: Option<ScrollbarSettings>,
523
524 /// What the default branch name should be when
525 /// `init.defaultBranch` is not set in git
526 ///
527 /// Default: main
528 pub fallback_branch_name: Option<String>,
529
530 /// Whether to sort entries in the panel by path
531 /// or by status (the default).
532 ///
533 /// Default: false
534 pub sort_by_path: Option<bool>,
535
536 /// Whether to collapse untracked files in the diff panel.
537 ///
538 /// Default: false
539 pub collapse_untracked_diff: Option<bool>,
540
541 /// Whether to show entries with tree or flat view in the panel
542 ///
543 /// Default: false
544 pub tree_view: Option<bool>,
545}
546
547#[derive(
548 Default,
549 Copy,
550 Clone,
551 Debug,
552 Serialize,
553 Deserialize,
554 JsonSchema,
555 MergeFrom,
556 PartialEq,
557 Eq,
558 strum::VariantArray,
559 strum::VariantNames,
560)]
561#[serde(rename_all = "snake_case")]
562pub enum StatusStyle {
563 #[default]
564 Icon,
565 LabelColor,
566}
567
568#[with_fallible_options]
569#[derive(
570 Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
571)]
572pub struct ScrollbarSettings {
573 pub show: Option<ShowScrollbar>,
574}
575
576#[with_fallible_options]
577#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
578pub struct NotificationPanelSettingsContent {
579 /// Whether to show the panel button in the status bar.
580 ///
581 /// Default: true
582 pub button: Option<bool>,
583 /// Where to dock the panel.
584 ///
585 /// Default: right
586 pub dock: Option<DockPosition>,
587 /// Default width of the panel in pixels.
588 ///
589 /// Default: 300
590 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
591 pub default_width: Option<f32>,
592}
593
594#[with_fallible_options]
595#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
596pub struct PanelSettingsContent {
597 /// Whether to show the panel button in the status bar.
598 ///
599 /// Default: true
600 pub button: Option<bool>,
601 /// Where to dock the panel.
602 ///
603 /// Default: left
604 pub dock: Option<DockPosition>,
605 /// Default width of the panel in pixels.
606 ///
607 /// Default: 240
608 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
609 pub default_width: Option<f32>,
610}
611
612#[with_fallible_options]
613#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
614pub struct MessageEditorSettings {
615 /// Whether to automatically replace emoji shortcodes with emoji characters.
616 /// For example: typing `:wave:` gets replaced with `👋`.
617 ///
618 /// Default: false
619 pub auto_replace_emoji_shortcode: Option<bool>,
620}
621
622#[with_fallible_options]
623#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
624pub struct FileFinderSettingsContent {
625 /// Whether to show file icons in the file finder.
626 ///
627 /// Default: true
628 pub file_icons: Option<bool>,
629 /// Determines how much space the file finder can take up in relation to the available window width.
630 ///
631 /// Default: small
632 pub modal_max_width: Option<FileFinderWidthContent>,
633 /// Determines whether the file finder should skip focus for the active file in search results.
634 ///
635 /// Default: true
636 pub skip_focus_for_active_in_search: Option<bool>,
637 /// Determines whether to show the git status in the file finder
638 ///
639 /// Default: true
640 pub git_status: Option<bool>,
641 /// Whether to use gitignored files when searching.
642 /// Only the file Zed had indexed will be used, not necessary all the gitignored files.
643 ///
644 /// Default: Smart
645 pub include_ignored: Option<IncludeIgnoredContent>,
646}
647
648#[derive(
649 Debug,
650 PartialEq,
651 Eq,
652 Clone,
653 Copy,
654 Default,
655 Serialize,
656 Deserialize,
657 JsonSchema,
658 MergeFrom,
659 strum::VariantArray,
660 strum::VariantNames,
661)]
662#[serde(rename_all = "snake_case")]
663pub enum IncludeIgnoredContent {
664 /// Use all gitignored files
665 All,
666 /// Use only the files Zed had indexed
667 Indexed,
668 /// Be smart and search for ignored when called from a gitignored worktree
669 #[default]
670 Smart,
671}
672
673#[derive(
674 Debug,
675 PartialEq,
676 Eq,
677 Clone,
678 Copy,
679 Default,
680 Serialize,
681 Deserialize,
682 JsonSchema,
683 MergeFrom,
684 strum::VariantArray,
685 strum::VariantNames,
686)]
687#[serde(rename_all = "lowercase")]
688pub enum FileFinderWidthContent {
689 #[default]
690 Small,
691 Medium,
692 Large,
693 XLarge,
694 Full,
695}
696
697#[with_fallible_options]
698#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Debug, JsonSchema, MergeFrom)]
699pub struct VimSettingsContent {
700 pub default_mode: Option<ModeContent>,
701 pub toggle_relative_line_numbers: Option<bool>,
702 pub use_system_clipboard: Option<UseSystemClipboard>,
703 pub use_smartcase_find: Option<bool>,
704 pub custom_digraphs: Option<HashMap<String, Arc<str>>>,
705 pub highlight_on_yank_duration: Option<u64>,
706 pub cursor_shape: Option<CursorShapeSettings>,
707}
708
709#[derive(
710 Copy,
711 Clone,
712 Default,
713 Serialize,
714 Deserialize,
715 JsonSchema,
716 MergeFrom,
717 PartialEq,
718 Debug,
719 strum::VariantArray,
720 strum::VariantNames,
721)]
722#[serde(rename_all = "snake_case")]
723pub enum ModeContent {
724 #[default]
725 Normal,
726 Insert,
727}
728
729/// Controls when to use system clipboard.
730#[derive(
731 Copy,
732 Clone,
733 Debug,
734 Serialize,
735 Deserialize,
736 PartialEq,
737 Eq,
738 JsonSchema,
739 MergeFrom,
740 strum::VariantArray,
741 strum::VariantNames,
742)]
743#[serde(rename_all = "snake_case")]
744pub enum UseSystemClipboard {
745 /// Don't use system clipboard.
746 Never,
747 /// Use system clipboard.
748 Always,
749 /// Use system clipboard for yank operations.
750 OnYank,
751}
752
753/// Cursor shape configuration for insert mode in Vim.
754#[derive(
755 Copy,
756 Clone,
757 Debug,
758 Serialize,
759 Deserialize,
760 PartialEq,
761 Eq,
762 JsonSchema,
763 MergeFrom,
764 strum::VariantArray,
765 strum::VariantNames,
766)]
767#[serde(rename_all = "snake_case")]
768pub enum VimInsertModeCursorShape {
769 /// Inherit cursor shape from the editor's base cursor_shape setting.
770 Inherit,
771 /// Vertical bar cursor.
772 Bar,
773 /// Block cursor that surrounds the character.
774 Block,
775 /// Underline cursor.
776 Underline,
777 /// Hollow box cursor.
778 Hollow,
779}
780
781/// The settings for cursor shape.
782#[with_fallible_options]
783#[derive(
784 Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom,
785)]
786pub struct CursorShapeSettings {
787 /// Cursor shape for the normal mode.
788 ///
789 /// Default: block
790 pub normal: Option<CursorShape>,
791 /// Cursor shape for the replace mode.
792 ///
793 /// Default: underline
794 pub replace: Option<CursorShape>,
795 /// Cursor shape for the visual mode.
796 ///
797 /// Default: block
798 pub visual: Option<CursorShape>,
799 /// Cursor shape for the insert mode.
800 ///
801 /// The default value follows the primary cursor_shape.
802 pub insert: Option<VimInsertModeCursorShape>,
803}
804
805/// Settings specific to journaling
806#[with_fallible_options]
807#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
808pub struct JournalSettingsContent {
809 /// The path of the directory where journal entries are stored.
810 ///
811 /// Default: `~`
812 pub path: Option<String>,
813 /// What format to display the hours in.
814 ///
815 /// Default: hour12
816 pub hour_format: Option<HourFormat>,
817}
818
819#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
820#[serde(rename_all = "snake_case")]
821pub enum HourFormat {
822 #[default]
823 Hour12,
824 Hour24,
825}
826
827#[with_fallible_options]
828#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)]
829pub struct OutlinePanelSettingsContent {
830 /// Whether to show the outline panel button in the status bar.
831 ///
832 /// Default: true
833 pub button: Option<bool>,
834 /// Customize default width (in pixels) taken by outline panel
835 ///
836 /// Default: 240
837 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
838 pub default_width: Option<f32>,
839 /// The position of outline panel
840 ///
841 /// Default: left
842 pub dock: Option<DockSide>,
843 /// Whether to show file icons in the outline panel.
844 ///
845 /// Default: true
846 pub file_icons: Option<bool>,
847 /// Whether to show folder icons or chevrons for directories in the outline panel.
848 ///
849 /// Default: true
850 pub folder_icons: Option<bool>,
851 /// Whether to show the git status in the outline panel.
852 ///
853 /// Default: true
854 pub git_status: Option<bool>,
855 /// Amount of indentation (in pixels) for nested items.
856 ///
857 /// Default: 20
858 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
859 pub indent_size: Option<f32>,
860 /// Whether to reveal it in the outline panel automatically,
861 /// when a corresponding project entry becomes active.
862 /// Gitignored entries are never auto revealed.
863 ///
864 /// Default: true
865 pub auto_reveal_entries: Option<bool>,
866 /// Whether to fold directories automatically
867 /// when directory has only one directory inside.
868 ///
869 /// Default: true
870 pub auto_fold_dirs: Option<bool>,
871 /// Settings related to indent guides in the outline panel.
872 pub indent_guides: Option<IndentGuidesSettingsContent>,
873 /// Scrollbar-related settings
874 pub scrollbar: Option<ScrollbarSettingsContent>,
875 /// Default depth to expand outline items in the current file.
876 /// The default depth to which outline entries are expanded on reveal.
877 /// - Set to 0 to collapse all items that have children
878 /// - Set to 1 or higher to collapse items at that depth or deeper
879 ///
880 /// Default: 100
881 pub expand_outlines_with_depth: Option<usize>,
882}
883
884#[derive(
885 Clone,
886 Copy,
887 Debug,
888 PartialEq,
889 Eq,
890 Serialize,
891 Deserialize,
892 JsonSchema,
893 MergeFrom,
894 strum::VariantArray,
895 strum::VariantNames,
896)]
897#[serde(rename_all = "snake_case")]
898pub enum DockSide {
899 Left,
900 Right,
901}
902
903#[derive(
904 Copy,
905 Clone,
906 Debug,
907 PartialEq,
908 Eq,
909 Deserialize,
910 Serialize,
911 JsonSchema,
912 MergeFrom,
913 strum::VariantArray,
914 strum::VariantNames,
915)]
916#[serde(rename_all = "snake_case")]
917pub enum ShowIndentGuides {
918 Always,
919 Never,
920}
921
922#[with_fallible_options]
923#[derive(
924 Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
925)]
926pub struct IndentGuidesSettingsContent {
927 /// When to show the scrollbar in the outline panel.
928 pub show: Option<ShowIndentGuides>,
929}
930
931#[derive(Clone, Copy, Default, PartialEq, Debug, JsonSchema, MergeFrom, Deserialize, Serialize)]
932#[serde(rename_all = "snake_case")]
933pub enum LineIndicatorFormat {
934 Short,
935 #[default]
936 Long,
937}
938
939/// The settings for the image viewer.
940#[with_fallible_options]
941#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, Default, PartialEq)]
942pub struct ImageViewerSettingsContent {
943 /// The unit to use for displaying image file sizes.
944 ///
945 /// Default: "binary"
946 pub unit: Option<ImageFileSizeUnit>,
947}
948
949#[with_fallible_options]
950#[derive(
951 Clone,
952 Copy,
953 Debug,
954 Serialize,
955 Deserialize,
956 JsonSchema,
957 MergeFrom,
958 Default,
959 PartialEq,
960 strum::VariantArray,
961 strum::VariantNames,
962)]
963#[serde(rename_all = "snake_case")]
964pub enum ImageFileSizeUnit {
965 /// Displays file size in binary units (e.g., KiB, MiB).
966 #[default]
967 Binary,
968 /// Displays file size in decimal units (e.g., KB, MB).
969 Decimal,
970}
971
972#[with_fallible_options]
973#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
974pub struct RemoteSettingsContent {
975 pub ssh_connections: Option<Vec<SshConnection>>,
976 pub wsl_connections: Option<Vec<WslConnection>>,
977 pub dev_container_connections: Option<Vec<DevContainerConnection>>,
978 pub read_ssh_config: Option<bool>,
979 pub use_podman: Option<bool>,
980}
981
982#[with_fallible_options]
983#[derive(
984 Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, Hash,
985)]
986pub struct DevContainerConnection {
987 pub name: String,
988 pub container_id: String,
989 pub use_podman: bool,
990}
991
992#[with_fallible_options]
993#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
994pub struct SshConnection {
995 pub host: String,
996 pub username: Option<String>,
997 pub port: Option<u16>,
998 #[serde(default)]
999 pub args: Vec<String>,
1000 #[serde(default)]
1001 pub projects: collections::BTreeSet<RemoteProject>,
1002 /// Name to use for this server in UI.
1003 pub nickname: Option<String>,
1004 // By default Zed will download the binary to the host directly.
1005 // If this is set to true, Zed will download the binary to your local machine,
1006 // and then upload it over the SSH connection. Useful if your SSH server has
1007 // limited outbound internet access.
1008 pub upload_binary_over_ssh: Option<bool>,
1009
1010 pub port_forwards: Option<Vec<SshPortForwardOption>>,
1011 /// Timeout in seconds for SSH connection and downloading the remote server binary.
1012 /// Defaults to 10 seconds if not specified.
1013 pub connection_timeout: Option<u16>,
1014}
1015
1016#[derive(Clone, Default, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom, Debug)]
1017pub struct WslConnection {
1018 pub distro_name: String,
1019 pub user: Option<String>,
1020 #[serde(default)]
1021 pub projects: BTreeSet<RemoteProject>,
1022}
1023
1024#[with_fallible_options]
1025#[derive(
1026 Clone, Debug, Default, Serialize, PartialEq, Eq, PartialOrd, Ord, Deserialize, JsonSchema,
1027)]
1028pub struct RemoteProject {
1029 pub paths: Vec<String>,
1030}
1031
1032#[with_fallible_options]
1033#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, JsonSchema, MergeFrom)]
1034pub struct SshPortForwardOption {
1035 pub local_host: Option<String>,
1036 pub local_port: u16,
1037 pub remote_host: Option<String>,
1038 pub remote_port: u16,
1039}
1040
1041/// Settings for configuring REPL display and behavior.
1042#[with_fallible_options]
1043#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
1044pub struct ReplSettingsContent {
1045 /// Maximum number of lines to keep in REPL's scrollback buffer.
1046 /// Clamped with [4, 256] range.
1047 ///
1048 /// Default: 32
1049 pub max_lines: Option<usize>,
1050 /// Maximum number of columns to keep in REPL's scrollback buffer.
1051 /// Clamped with [20, 512] range.
1052 ///
1053 /// Default: 128
1054 pub max_columns: Option<usize>,
1055 /// Whether to show small single-line outputs inline instead of in a block.
1056 ///
1057 /// Default: true
1058 pub inline_output: Option<bool>,
1059 /// Maximum number of characters for an output to be shown inline.
1060 /// Only applies when `inline_output` is true.
1061 ///
1062 /// Default: 50
1063 pub inline_output_max_length: Option<usize>,
1064}
1065
1066/// Settings for configuring the which-key popup behaviour.
1067#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
1068pub struct WhichKeySettingsContent {
1069 /// Whether to show the which-key popup when holding down key combinations
1070 ///
1071 /// Default: false
1072 pub enabled: Option<bool>,
1073 /// Delay in milliseconds before showing the which-key popup.
1074 ///
1075 /// Default: 700
1076 pub delay_ms: Option<u64>,
1077}
1078
1079#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
1080/// An ExtendingVec in the settings can only accumulate new values.
1081///
1082/// This is useful for things like private files where you only want
1083/// to allow new values to be added.
1084///
1085/// Consider using a HashMap<String, bool> instead of this type
1086/// (like auto_install_extensions) so that user settings files can both add
1087/// and remove values from the set.
1088pub struct ExtendingVec<T>(pub Vec<T>);
1089
1090impl<T> Into<Vec<T>> for ExtendingVec<T> {
1091 fn into(self) -> Vec<T> {
1092 self.0
1093 }
1094}
1095impl<T> From<Vec<T>> for ExtendingVec<T> {
1096 fn from(vec: Vec<T>) -> Self {
1097 ExtendingVec(vec)
1098 }
1099}
1100
1101impl<T: Clone> merge_from::MergeFrom for ExtendingVec<T> {
1102 fn merge_from(&mut self, other: &Self) {
1103 self.0.extend_from_slice(other.0.as_slice());
1104 }
1105}
1106
1107/// A SaturatingBool in the settings can only ever be set to true,
1108/// later attempts to set it to false will be ignored.
1109///
1110/// Used by `disable_ai`.
1111#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
1112pub struct SaturatingBool(pub bool);
1113
1114impl From<bool> for SaturatingBool {
1115 fn from(value: bool) -> Self {
1116 SaturatingBool(value)
1117 }
1118}
1119
1120impl From<SaturatingBool> for bool {
1121 fn from(value: SaturatingBool) -> bool {
1122 value.0
1123 }
1124}
1125
1126impl merge_from::MergeFrom for SaturatingBool {
1127 fn merge_from(&mut self, other: &Self) {
1128 self.0 |= other.0
1129 }
1130}
1131
1132#[derive(
1133 Copy,
1134 Clone,
1135 Default,
1136 Debug,
1137 PartialEq,
1138 Eq,
1139 PartialOrd,
1140 Ord,
1141 Serialize,
1142 Deserialize,
1143 MergeFrom,
1144 JsonSchema,
1145 derive_more::FromStr,
1146)]
1147#[serde(transparent)]
1148pub struct DelayMs(pub u64);
1149
1150impl From<u64> for DelayMs {
1151 fn from(n: u64) -> Self {
1152 Self(n)
1153 }
1154}
1155
1156impl std::fmt::Display for DelayMs {
1157 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1158 write!(f, "{}ms", self.0)
1159 }
1160}