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