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