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