project.rs

  1use std::{
  2    path::{Path, PathBuf},
  3    sync::Arc,
  4};
  5
  6use anyhow::Context;
  7use collections::{BTreeMap, HashMap};
  8use gpui::Rgba;
  9use schemars::JsonSchema;
 10use serde::{Deserialize, Serialize};
 11use settings_json::parse_json_with_comments;
 12use settings_macros::{MergeFrom, with_fallible_options};
 13use util::serde::default_true;
 14
 15use crate::{
 16    AllLanguageSettingsContent, DelayMs, ExtendingVec, ParseStatus, ProjectTerminalSettingsContent,
 17    RootUserSettings, SaturatingBool, fallible_options,
 18};
 19
 20#[with_fallible_options]
 21#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
 22pub struct LspSettingsMap(pub HashMap<Arc<str>, LspSettings>);
 23
 24impl IntoIterator for LspSettingsMap {
 25    type Item = (Arc<str>, LspSettings);
 26    type IntoIter = std::collections::hash_map::IntoIter<Arc<str>, LspSettings>;
 27
 28    fn into_iter(self) -> Self::IntoIter {
 29        self.0.into_iter()
 30    }
 31}
 32
 33impl RootUserSettings for ProjectSettingsContent {
 34    fn parse_json(json: &str) -> (Option<Self>, ParseStatus) {
 35        fallible_options::parse_json(json)
 36    }
 37    fn parse_json_with_comments(json: &str) -> anyhow::Result<Self> {
 38        parse_json_with_comments(json)
 39    }
 40}
 41
 42#[with_fallible_options]
 43#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
 44pub struct ProjectSettingsContent {
 45    #[serde(flatten)]
 46    pub all_languages: AllLanguageSettingsContent,
 47
 48    #[serde(flatten)]
 49    pub worktree: WorktreeSettingsContent,
 50
 51    /// Configuration for language servers.
 52    ///
 53    /// The following settings can be overridden for specific language servers:
 54    /// - initialization_options
 55    ///
 56    /// To override settings for a language, add an entry for that language server's
 57    /// name to the lsp value.
 58    /// Default: null
 59    #[serde(default)]
 60    pub lsp: LspSettingsMap,
 61
 62    pub terminal: Option<ProjectTerminalSettingsContent>,
 63
 64    /// Configuration for Debugger-related features
 65    #[serde(default)]
 66    pub dap: HashMap<Arc<str>, DapSettingsContent>,
 67
 68    /// Settings for context servers used for AI-related features.
 69    #[serde(default)]
 70    pub context_servers: HashMap<Arc<str>, ContextServerSettingsContent>,
 71
 72    /// Default timeout in seconds for context server tool calls.
 73    /// Can be overridden per-server in context_servers configuration.
 74    ///
 75    /// Default: 60
 76    pub context_server_timeout: Option<u64>,
 77
 78    /// Configuration for how direnv configuration should be loaded
 79    pub load_direnv: Option<DirenvSettings>,
 80
 81    /// The list of custom Git hosting providers.
 82    pub git_hosting_providers: Option<ExtendingVec<GitHostingProviderConfig>>,
 83
 84    /// Whether to disable all AI features in Zed.
 85    ///
 86    /// Default: false
 87    pub disable_ai: Option<SaturatingBool>,
 88}
 89
 90#[with_fallible_options]
 91#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
 92pub struct WorktreeSettingsContent {
 93    /// Whether to prevent this project from being shared in public channels.
 94    ///
 95    /// Default: false
 96    #[serde(default)]
 97    pub prevent_sharing_in_public_channels: bool,
 98
 99    /// Completely ignore files matching globs from `file_scan_exclusions`. Overrides
100    /// `file_scan_inclusions`.
101    ///
102    /// Default: [
103    ///   "**/.git",
104    ///   "**/.svn",
105    ///   "**/.hg",
106    ///   "**/.jj",
107    ///   "**/CVS",
108    ///   "**/.DS_Store",
109    ///   "**/Thumbs.db",
110    ///   "**/.classpath",
111    ///   "**/.settings"
112    /// ]
113    pub file_scan_exclusions: Option<Vec<String>>,
114
115    /// Always include files that match these globs when scanning for files, even if they're
116    /// ignored by git. This setting is overridden by `file_scan_exclusions`.
117    /// Default: [
118    ///  ".env*",
119    ///  "docker-compose.*.yml",
120    /// ]
121    pub file_scan_inclusions: Option<Vec<String>>,
122
123    /// Treat the files matching these globs as `.env` files.
124    /// Default: ["**/.env*", "**/*.pem", "**/*.key", "**/*.cert", "**/*.crt", "**/secrets.yml"]
125    pub private_files: Option<ExtendingVec<String>>,
126
127    /// Treat the files matching these globs as hidden files. You can hide hidden files in the project panel.
128    /// Default: ["**/.*"]
129    pub hidden_files: Option<Vec<String>>,
130
131    /// Treat the files matching these globs as read-only. These files can be opened and viewed,
132    /// but cannot be edited. This is useful for generated files, build outputs, or files from
133    /// external dependencies that should not be modified directly.
134    /// Default: []
135    pub read_only_files: Option<Vec<String>>,
136}
137
138#[with_fallible_options]
139#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, Hash)]
140#[serde(rename_all = "snake_case")]
141pub struct LspSettings {
142    pub binary: Option<BinarySettings>,
143    /// Options passed to the language server at startup.
144    ///
145    /// Ref: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize
146    ///
147    /// Consult the documentation for the specific language server to see which settings are supported.
148    pub initialization_options: Option<serde_json::Value>,
149    /// Language server settings.
150    ///
151    /// Ref: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_configuration
152    ///
153    /// Consult the documentation for the specific language server to see which settings are supported.
154    pub settings: Option<serde_json::Value>,
155    /// If the server supports sending tasks over LSP extensions,
156    /// this setting can be used to enable or disable them in Zed.
157    /// Default: true
158    #[serde(default = "default_true")]
159    pub enable_lsp_tasks: bool,
160    pub fetch: Option<FetchSettings>,
161}
162
163impl Default for LspSettings {
164    fn default() -> Self {
165        Self {
166            binary: None,
167            initialization_options: None,
168            settings: None,
169            enable_lsp_tasks: true,
170            fetch: None,
171        }
172    }
173}
174
175#[with_fallible_options]
176#[derive(
177    Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, Hash,
178)]
179pub struct BinarySettings {
180    pub path: Option<String>,
181    pub arguments: Option<Vec<String>>,
182    pub env: Option<BTreeMap<String, String>>,
183    pub ignore_system_version: Option<bool>,
184}
185
186#[with_fallible_options]
187#[derive(
188    Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, Hash,
189)]
190pub struct FetchSettings {
191    // Whether to consider pre-releases for fetching
192    pub pre_release: Option<bool>,
193}
194
195/// Common language server settings.
196#[with_fallible_options]
197#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
198pub struct GlobalLspSettingsContent {
199    /// Whether to show the LSP servers button in the status bar.
200    ///
201    /// Default: `true`
202    pub button: Option<bool>,
203    /// The maximum amount of time to wait for responses from language servers, in seconds.
204    /// A value of `0` will result in no timeout being applied (causing all LSP responses to wait indefinitely until completed).
205    ///
206    /// Default: `120`
207    pub request_timeout: Option<u64>,
208    /// Settings for language server notifications
209    pub notifications: Option<LspNotificationSettingsContent>,
210    /// Rules for rendering LSP semantic tokens.
211    pub semantic_token_rules: Option<SemanticTokenRules>,
212}
213
214#[with_fallible_options]
215#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]
216pub struct LspNotificationSettingsContent {
217    /// Timeout in milliseconds for automatically dismissing language server notifications.
218    /// Set to 0 to disable auto-dismiss.
219    ///
220    /// Default: 5000
221    pub dismiss_timeout_ms: Option<u64>,
222}
223
224/// Custom rules for rendering LSP semantic tokens.
225#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, JsonSchema)]
226#[serde(transparent)]
227pub struct SemanticTokenRules {
228    pub rules: Vec<SemanticTokenRule>,
229}
230
231impl SemanticTokenRules {
232    pub const FILE_NAME: &'static str = "semantic_token_rules.json";
233
234    pub fn load(file_path: &Path) -> anyhow::Result<Self> {
235        let rules_content = std::fs::read(file_path).with_context(|| {
236            anyhow::anyhow!(
237                "Could not read semantic token rules from {}",
238                file_path.display()
239            )
240        })?;
241
242        serde_json_lenient::from_slice::<SemanticTokenRules>(&rules_content).with_context(|| {
243            anyhow::anyhow!(
244                "Failed to parse semantic token rules from {}",
245                file_path.display()
246            )
247        })
248    }
249}
250
251impl crate::merge_from::MergeFrom for SemanticTokenRules {
252    fn merge_from(&mut self, other: &Self) {
253        self.rules.splice(0..0, other.rules.iter().cloned());
254    }
255}
256
257#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, JsonSchema)]
258#[serde(rename_all = "snake_case")]
259pub struct SemanticTokenRule {
260    pub token_type: Option<String>,
261    #[serde(default)]
262    pub token_modifiers: Vec<String>,
263    #[serde(default)]
264    pub style: Vec<String>,
265    pub foreground_color: Option<Rgba>,
266    pub background_color: Option<Rgba>,
267    pub underline: Option<SemanticTokenColorOverride>,
268    pub strikethrough: Option<SemanticTokenColorOverride>,
269    pub font_weight: Option<SemanticTokenFontWeight>,
270    pub font_style: Option<SemanticTokenFontStyle>,
271}
272
273impl SemanticTokenRule {
274    pub fn no_style_defined(&self) -> bool {
275        self.style.is_empty()
276            && self.foreground_color.is_none()
277            && self.background_color.is_none()
278            && self.underline.is_none()
279            && self.strikethrough.is_none()
280            && self.font_weight.is_none()
281            && self.font_style.is_none()
282    }
283}
284
285#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]
286#[serde(untagged)]
287pub enum SemanticTokenColorOverride {
288    InheritForeground(bool),
289    Replace(Rgba),
290}
291
292#[derive(
293    Copy,
294    Clone,
295    Debug,
296    Default,
297    Serialize,
298    Deserialize,
299    PartialEq,
300    Eq,
301    JsonSchema,
302    MergeFrom,
303    strum::VariantArray,
304    strum::VariantNames,
305)]
306#[serde(rename_all = "snake_case")]
307pub enum SemanticTokenFontWeight {
308    #[default]
309    Normal,
310    Bold,
311}
312
313#[derive(
314    Copy,
315    Clone,
316    Debug,
317    Default,
318    Serialize,
319    Deserialize,
320    PartialEq,
321    Eq,
322    JsonSchema,
323    MergeFrom,
324    strum::VariantArray,
325    strum::VariantNames,
326)]
327#[serde(rename_all = "snake_case")]
328pub enum SemanticTokenFontStyle {
329    #[default]
330    Normal,
331    Italic,
332}
333
334#[with_fallible_options]
335#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]
336#[serde(rename_all = "snake_case")]
337pub struct DapSettingsContent {
338    pub binary: Option<String>,
339    pub args: Option<Vec<String>>,
340    pub env: Option<HashMap<String, String>>,
341}
342
343#[with_fallible_options]
344#[derive(
345    Default, Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, JsonSchema, MergeFrom,
346)]
347pub struct SessionSettingsContent {
348    /// Whether or not to restore unsaved buffers on restart.
349    ///
350    /// If this is true, user won't be prompted whether to save/discard
351    /// dirty files when closing the application.
352    ///
353    /// Default: true
354    pub restore_unsaved_buffers: Option<bool>,
355    /// Whether or not to skip worktree trust checks.
356    /// When trusted, project settings are synchronized automatically,
357    /// language and MCP servers are downloaded and started automatically.
358    ///
359    /// Default: false
360    pub trust_all_worktrees: Option<bool>,
361}
362
363#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema, MergeFrom, Debug)]
364#[serde(untagged, rename_all = "snake_case")]
365pub enum ContextServerSettingsContent {
366    Stdio {
367        /// Whether the context server is enabled.
368        #[serde(default = "default_true")]
369        enabled: bool,
370        /// Whether to run the context server on the remote server when using remote development.
371        ///
372        /// If this is false, the context server will always run on the local machine.
373        ///
374        /// Default: false
375        #[serde(default)]
376        remote: bool,
377        #[serde(flatten)]
378        command: ContextServerCommand,
379    },
380    Http {
381        /// Whether the context server is enabled.
382        #[serde(default = "default_true")]
383        enabled: bool,
384        /// The URL of the remote context server.
385        url: String,
386        /// Optional headers to send.
387        #[serde(skip_serializing_if = "HashMap::is_empty", default)]
388        headers: HashMap<String, String>,
389        /// Timeout for tool calls in seconds. Defaults to global context_server_timeout if not specified.
390        timeout: Option<u64>,
391    },
392    Extension {
393        /// Whether the context server is enabled.
394        #[serde(default = "default_true")]
395        enabled: bool,
396        /// Whether to run the context server on the remote server when using remote development.
397        ///
398        /// If this is false, the context server will always run on the local machine.
399        ///
400        /// Default: false
401        #[serde(default)]
402        remote: bool,
403        /// The settings for this context server specified by the extension.
404        ///
405        /// Consult the documentation for the context server to see what settings
406        /// are supported.
407        settings: serde_json::Value,
408    },
409}
410
411impl ContextServerSettingsContent {
412    pub fn set_enabled(&mut self, enabled: bool) {
413        match self {
414            ContextServerSettingsContent::Stdio {
415                enabled: custom_enabled,
416                ..
417            } => {
418                *custom_enabled = enabled;
419            }
420            ContextServerSettingsContent::Extension {
421                enabled: ext_enabled,
422                ..
423            } => *ext_enabled = enabled,
424            ContextServerSettingsContent::Http {
425                enabled: remote_enabled,
426                ..
427            } => *remote_enabled = enabled,
428        }
429    }
430}
431
432#[with_fallible_options]
433#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema, MergeFrom)]
434pub struct ContextServerCommand {
435    #[serde(rename = "command")]
436    pub path: PathBuf,
437    pub args: Vec<String>,
438    pub env: Option<HashMap<String, String>>,
439    /// Timeout for tool calls in seconds. Defaults to 60 if not specified.
440    pub timeout: Option<u64>,
441}
442
443impl std::fmt::Debug for ContextServerCommand {
444    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
445        let filtered_env = self.env.as_ref().map(|env| {
446            env.iter()
447                .map(|(k, v)| {
448                    (
449                        k,
450                        if util::redact::should_redact(k) {
451                            "[REDACTED]"
452                        } else {
453                            v
454                        },
455                    )
456                })
457                .collect::<Vec<_>>()
458        });
459
460        f.debug_struct("ContextServerCommand")
461            .field("path", &self.path)
462            .field("args", &self.args)
463            .field("env", &filtered_env)
464            .finish()
465    }
466}
467
468#[with_fallible_options]
469#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
470pub struct GitSettings {
471    /// Whether or not to enable git integration.
472    ///
473    /// Default: true
474    #[serde(flatten)]
475    pub enabled: Option<GitEnabledSettings>,
476    /// Whether or not to show the git gutter.
477    ///
478    /// Default: tracked_files
479    pub git_gutter: Option<GitGutterSetting>,
480    /// Sets the debounce threshold (in milliseconds) after which changes are reflected in the git gutter.
481    ///
482    /// Default: 0
483    pub gutter_debounce: Option<u64>,
484    /// Whether or not to show git blame data inline in
485    /// the currently focused line.
486    ///
487    /// Default: on
488    pub inline_blame: Option<InlineBlameSettings>,
489    /// Git blame settings.
490    pub blame: Option<BlameSettings>,
491    /// Which information to show in the branch picker.
492    ///
493    /// Default: on
494    pub branch_picker: Option<BranchPickerSettingsContent>,
495    /// How hunks are displayed visually in the editor.
496    ///
497    /// Default: staged_hollow
498    pub hunk_style: Option<GitHunkStyleSetting>,
499    /// How file paths are displayed in the git gutter.
500    ///
501    /// Default: file_name_first
502    pub path_style: Option<GitPathStyle>,
503    /// Directory where git worktrees are created, relative to the repository
504    /// working directory.
505    ///
506    /// When the resolved directory is outside the project root, the
507    /// project's directory name is automatically appended so that
508    /// sibling repos don't collide. For example, with the default
509    /// `"../worktrees"` and a project at `~/code/zed`, worktrees are
510    /// created under `~/code/worktrees/zed/`.
511    ///
512    /// When the resolved directory is inside the project root, no
513    /// extra component is added (it's already project-scoped).
514    ///
515    /// Examples:
516    /// - `"../worktrees"` — `~/code/worktrees/<project>/` (default)
517    /// - `".git/zed-worktrees"` — `<project>/.git/zed-worktrees/`
518    /// - `"my-worktrees"` — `<project>/my-worktrees/`
519    ///
520    /// Trailing slashes are ignored.
521    ///
522    /// Default: ../worktrees
523    pub worktree_directory: Option<String>,
524}
525
526#[with_fallible_options]
527#[derive(Clone, Copy, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
528#[serde(rename_all = "snake_case")]
529pub struct GitEnabledSettings {
530    pub disable_git: Option<bool>,
531    pub enable_status: Option<bool>,
532    pub enable_diff: Option<bool>,
533}
534
535impl GitEnabledSettings {
536    pub fn is_git_status_enabled(&self) -> bool {
537        !self.disable_git.unwrap_or(false) && self.enable_status.unwrap_or(true)
538    }
539
540    pub fn is_git_diff_enabled(&self) -> bool {
541        !self.disable_git.unwrap_or(false) && self.enable_diff.unwrap_or(true)
542    }
543}
544
545#[derive(
546    Clone,
547    Copy,
548    Debug,
549    PartialEq,
550    Default,
551    Serialize,
552    Deserialize,
553    JsonSchema,
554    MergeFrom,
555    strum::VariantArray,
556    strum::VariantNames,
557)]
558#[serde(rename_all = "snake_case")]
559pub enum GitGutterSetting {
560    /// Show git gutter in tracked files.
561    #[default]
562    TrackedFiles,
563    /// Hide git gutter
564    Hide,
565}
566
567#[with_fallible_options]
568#[derive(Clone, Copy, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
569#[serde(rename_all = "snake_case")]
570pub struct InlineBlameSettings {
571    /// Whether or not to show git blame data inline in
572    /// the currently focused line.
573    ///
574    /// Default: true
575    pub enabled: Option<bool>,
576    /// Whether to only show the inline blame information
577    /// after a delay once the cursor stops moving.
578    ///
579    /// Default: 0
580    pub delay_ms: Option<DelayMs>,
581    /// The amount of padding between the end of the source line and the start
582    /// of the inline blame in units of columns.
583    ///
584    /// Default: 7
585    pub padding: Option<u32>,
586    /// The minimum column number to show the inline blame information at
587    ///
588    /// Default: 0
589    pub min_column: Option<u32>,
590    /// Whether to show commit summary as part of the inline blame.
591    ///
592    /// Default: false
593    pub show_commit_summary: Option<bool>,
594}
595
596#[with_fallible_options]
597#[derive(Clone, Copy, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
598#[serde(rename_all = "snake_case")]
599pub struct BlameSettings {
600    /// Whether to show the avatar of the author of the commit.
601    ///
602    /// Default: true
603    pub show_avatar: Option<bool>,
604}
605
606#[with_fallible_options]
607#[derive(Clone, Copy, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
608#[serde(rename_all = "snake_case")]
609pub struct BranchPickerSettingsContent {
610    /// Whether to show author name as part of the commit information.
611    ///
612    /// Default: false
613    pub show_author_name: Option<bool>,
614}
615
616#[derive(
617    Clone,
618    Copy,
619    PartialEq,
620    Debug,
621    Default,
622    Serialize,
623    Deserialize,
624    JsonSchema,
625    MergeFrom,
626    strum::VariantArray,
627    strum::VariantNames,
628)]
629#[serde(rename_all = "snake_case")]
630pub enum GitHunkStyleSetting {
631    /// Show unstaged hunks with a filled background and staged hunks hollow.
632    #[default]
633    StagedHollow,
634    /// Show unstaged hunks hollow and staged hunks with a filled background.
635    UnstagedHollow,
636}
637
638#[with_fallible_options]
639#[derive(
640    Copy,
641    Clone,
642    Debug,
643    PartialEq,
644    Default,
645    Serialize,
646    Deserialize,
647    JsonSchema,
648    MergeFrom,
649    strum::VariantArray,
650    strum::VariantNames,
651)]
652#[serde(rename_all = "snake_case")]
653pub enum GitPathStyle {
654    /// Show file name first, then path
655    #[default]
656    FileNameFirst,
657    /// Show full path first
658    FilePathFirst,
659}
660
661#[with_fallible_options]
662#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
663pub struct DiagnosticsSettingsContent {
664    /// Whether to show the project diagnostics button in the status bar.
665    pub button: Option<bool>,
666
667    /// Whether or not to include warning diagnostics.
668    ///
669    /// Default: true
670    pub include_warnings: Option<bool>,
671
672    /// Settings for using LSP pull diagnostics mechanism in Zed.
673    pub lsp_pull_diagnostics: Option<LspPullDiagnosticsSettingsContent>,
674
675    /// Settings for showing inline diagnostics.
676    pub inline: Option<InlineDiagnosticsSettingsContent>,
677}
678
679#[with_fallible_options]
680#[derive(
681    Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq,
682)]
683pub struct LspPullDiagnosticsSettingsContent {
684    /// Whether to pull for diagnostics or not.
685    ///
686    /// Default: true
687    pub enabled: Option<bool>,
688    /// Minimum time to wait before pulling diagnostics from the language server(s).
689    /// 0 turns the debounce off.
690    ///
691    /// Default: 50
692    pub debounce_ms: Option<DelayMs>,
693}
694
695#[with_fallible_options]
696#[derive(
697    Clone, Copy, Debug, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Eq,
698)]
699pub struct InlineDiagnosticsSettingsContent {
700    /// Whether or not to show inline diagnostics
701    ///
702    /// Default: false
703    pub enabled: Option<bool>,
704    /// Whether to only show the inline diagnostics after a delay after the
705    /// last editor event.
706    ///
707    /// Default: 150
708    pub update_debounce_ms: Option<DelayMs>,
709    /// The amount of padding between the end of the source line and the start
710    /// of the inline diagnostic in units of columns.
711    ///
712    /// Default: 4
713    pub padding: Option<u32>,
714    /// The minimum column to display inline diagnostics. This setting can be
715    /// used to horizontally align inline diagnostics at some position. Lines
716    /// longer than this value will still push diagnostics further to the right.
717    ///
718    /// Default: 0
719    pub min_column: Option<u32>,
720
721    pub max_severity: Option<DiagnosticSeverityContent>,
722}
723
724#[with_fallible_options]
725#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]
726pub struct NodeBinarySettings {
727    /// The path to the Node binary.
728    pub path: Option<String>,
729    /// The path to the npm binary Zed should use (defaults to `.path/../npm`).
730    pub npm_path: Option<String>,
731    /// If enabled, Zed will download its own copy of Node.
732    pub ignore_system_version: Option<bool>,
733}
734
735#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
736#[serde(rename_all = "snake_case")]
737pub enum DirenvSettings {
738    /// Load direnv configuration through a shell hook
739    ShellHook,
740    /// Load direnv configuration directly using `direnv export json`
741    #[default]
742    Direct,
743    /// Do not load direnv configuration
744    Disabled,
745}
746
747#[derive(
748    Clone,
749    Copy,
750    Debug,
751    Eq,
752    PartialEq,
753    Ord,
754    PartialOrd,
755    Serialize,
756    Deserialize,
757    JsonSchema,
758    MergeFrom,
759    strum::VariantArray,
760    strum::VariantNames,
761)]
762#[serde(rename_all = "snake_case")]
763pub enum DiagnosticSeverityContent {
764    // No diagnostics are shown.
765    Off,
766    Error,
767    Warning,
768    Info,
769    Hint,
770    All,
771}
772
773/// A custom Git hosting provider.
774#[with_fallible_options]
775#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)]
776pub struct GitHostingProviderConfig {
777    /// The type of the provider.
778    ///
779    /// Must be one of `github`, `gitlab`, `bitbucket`, `gitea`, `forgejo`, or `source_hut`.
780    pub provider: GitHostingProviderKind,
781
782    /// The base URL for the provider (e.g., "https://code.corp.big.com").
783    pub base_url: String,
784
785    /// The display name for the provider (e.g., "BigCorp GitHub").
786    pub name: String,
787}
788
789#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]
790#[serde(rename_all = "snake_case")]
791pub enum GitHostingProviderKind {
792    Github,
793    Gitlab,
794    Bitbucket,
795    Gitea,
796    Forgejo,
797    SourceHut,
798}