900 lines · 27.4 KB · Rust
RawDownload
use std::{    path::{Path, PathBuf},    sync::Arc,}; use anyhow::Context;use collections::{BTreeMap, HashMap};use gpui::Rgba;use schemars::JsonSchema;use serde::{Deserialize, Serialize};use settings_json::parse_json_with_comments;use settings_macros::{MergeFrom, with_fallible_options};use util::serde::default_true; use crate::{    AllLanguageSettingsContent, DelayMs, ExtendingVec, ParseStatus, ProjectTerminalSettingsContent,    RootUserSettings, SaturatingBool, fallible_options,}; #[with_fallible_options]#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]pub struct LspSettingsMap(pub HashMap<Arc<str>, LspSettings>); impl IntoIterator for LspSettingsMap {    type Item = (Arc<str>, LspSettings);    type IntoIter = std::collections::hash_map::IntoIter<Arc<str>, LspSettings>;     fn into_iter(self) -> Self::IntoIter {        self.0.into_iter()    }} impl RootUserSettings for ProjectSettingsContent {    fn parse_json(json: &str) -> (Option<Self>, ParseStatus) {        fallible_options::parse_json(json)    }    fn parse_json_with_comments(json: &str) -> anyhow::Result<Self> {        parse_json_with_comments(json)    }} #[with_fallible_options]#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]pub struct ProjectSettingsContent {    #[serde(flatten)]    pub all_languages: AllLanguageSettingsContent,     #[serde(flatten)]    pub worktree: WorktreeSettingsContent,     /// Configuration for language servers.    ///    /// The following settings can be overridden for specific language servers:    /// - initialization_options    ///    /// To override settings for a language, add an entry for that language server's    /// name to the lsp value.    /// Default: null    #[serde(default)]    pub lsp: LspSettingsMap,     pub terminal: Option<ProjectTerminalSettingsContent>,     /// Configuration for Debugger-related features    #[serde(default)]    pub dap: HashMap<Arc<str>, DapSettingsContent>,     /// Settings for context servers used for AI-related features.    #[serde(default)]    pub context_servers: HashMap<Arc<str>, ContextServerSettingsContent>,     /// Default timeout in seconds for context server tool calls.    /// Can be overridden per-server in context_servers configuration.    ///    /// Default: 60    pub context_server_timeout: Option<u64>,     /// Configuration for how direnv configuration should be loaded    pub load_direnv: Option<DirenvSettings>,     /// The list of custom Git hosting providers.    pub git_hosting_providers: Option<ExtendingVec<GitHostingProviderConfig>>,     /// Whether to disable all AI features in Zed.    ///    /// Default: false    pub disable_ai: Option<SaturatingBool>,} /// When to scan content of linked directories.#[derive(    Copy,    Clone,    Default,    Debug,    Serialize,    Deserialize,    PartialEq,    Eq,    JsonSchema,    MergeFrom,    strum::VariantArray,    strum::VariantNames,)]#[serde(rename_all = "snake_case")]pub enum ScanSymlinksSetting {    /// Always scan symlinked directories    Always,    /// Only scan symlinked directories when they've been expanded in the workspace    #[default]    Expanded,} #[with_fallible_options]#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]pub struct WorktreeSettingsContent {    /// Whether to prevent this project from being shared in public channels.    ///    /// Default: false    #[serde(default)]    pub prevent_sharing_in_public_channels: bool,     /// Completely ignore files matching globs from `file_scan_exclusions`. Overrides    /// `file_scan_inclusions`.    ///    /// Default: [    ///   "**/.git",    ///   "**/.svn",    ///   "**/.hg",    ///   "**/.jj",    ///   "**/CVS",    ///   "**/.DS_Store",    ///   "**/Thumbs.db",    ///   "**/.classpath",    ///   "**/.settings"    /// ]    pub file_scan_exclusions: Option<Vec<String>>,     /// Always include files that match these globs when scanning for files, even if they're    /// ignored by git. This setting is overridden by `file_scan_exclusions`.    /// Default: [    ///  ".env*",    ///  "docker-compose.*.yml",    /// ]    pub file_scan_inclusions: Option<Vec<String>>,     /// When to scan content of linked directories.    ///    /// Default: expanded    pub scan_symlinks: Option<ScanSymlinksSetting>,     /// Treat the files matching these globs as `.env` files.    /// Default: ["**/.env*", "**/*.pem", "**/*.key", "**/*.cert", "**/*.crt", "**/secrets.yml"]    pub private_files: Option<ExtendingVec<String>>,     /// Treat the files matching these globs as hidden files. You can hide hidden files in the project panel.    /// Default: ["**/.*"]    pub hidden_files: Option<Vec<String>>,     /// Treat the files matching these globs as read-only. These files can be opened and viewed,    /// but cannot be edited. This is useful for generated files, build outputs, or files from    /// external dependencies that should not be modified directly.    /// Default: []    pub read_only_files: Option<Vec<String>>,} #[with_fallible_options]#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, Hash)]#[serde(rename_all = "snake_case")]pub struct LspSettings {    pub binary: Option<BinarySettings>,    /// Options passed to the language server at startup.    ///    /// Ref: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize    ///    /// Consult the documentation for the specific language server to see which settings are supported.    pub initialization_options: Option<serde_json::Value>,    /// Language server settings.    ///    /// Ref: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_configuration    ///    /// Consult the documentation for the specific language server to see which settings are supported.    pub settings: Option<serde_json::Value>,    /// If the server supports sending tasks over LSP extensions,    /// this setting can be used to enable or disable them in Zed.    /// Default: true    #[serde(default = "default_true")]    pub enable_lsp_tasks: bool,    pub fetch: Option<FetchSettings>,} impl Default for LspSettings {    fn default() -> Self {        Self {            binary: None,            initialization_options: None,            settings: None,            enable_lsp_tasks: true,            fetch: None,        }    }} #[with_fallible_options]#[derive(    Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, Hash,)]pub struct BinarySettings {    pub path: Option<String>,    pub arguments: Option<Vec<String>>,    pub env: Option<BTreeMap<String, String>>,    pub ignore_system_version: Option<bool>,} #[with_fallible_options]#[derive(    Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, Hash,)]pub struct FetchSettings {    // Whether to consider pre-releases for fetching    pub pre_release: Option<bool>,} /// Common language server settings.#[with_fallible_options]#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)]pub struct GlobalLspSettingsContent {    /// Whether to show the LSP servers button in the status bar.    ///    /// Default: `true`    pub button: Option<bool>,    /// The maximum amount of time to wait for responses from language servers, in seconds.    /// A value of `0` will result in no timeout being applied (causing all LSP responses to wait indefinitely until completed).    ///    /// Default: `120`    pub request_timeout: Option<u64>,    /// Settings for language server notifications    pub notifications: Option<LspNotificationSettingsContent>,    /// Rules for rendering LSP semantic tokens.    pub semantic_token_rules: Option<SemanticTokenRules>,} #[with_fallible_options]#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]pub struct LspNotificationSettingsContent {    /// Timeout in milliseconds for automatically dismissing language server notifications.    /// Set to 0 to disable auto-dismiss.    ///    /// Default: 5000    pub dismiss_timeout_ms: Option<u64>,} /// Custom rules for rendering LSP semantic tokens.#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, JsonSchema)]#[serde(transparent)]pub struct SemanticTokenRules {    pub rules: Vec<SemanticTokenRule>,} impl SemanticTokenRules {    pub const FILE_NAME: &'static str = "semantic_token_rules.json";     pub fn load(file_path: &Path) -> anyhow::Result<Self> {        let rules_content = std::fs::read(file_path).with_context(|| {            anyhow::anyhow!(                "Could not read semantic token rules from {}",                file_path.display()            )        })?;         serde_json_lenient::from_slice::<SemanticTokenRules>(&rules_content).with_context(|| {            anyhow::anyhow!(                "Failed to parse semantic token rules from {}",                file_path.display()            )        })    }} impl crate::merge_from::MergeFrom for SemanticTokenRules {    fn merge_from(&mut self, other: &Self) {        self.rules.splice(0..0, other.rules.iter().cloned());    }} #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, JsonSchema)]#[serde(rename_all = "snake_case")]pub struct SemanticTokenRule {    pub token_type: Option<String>,    #[serde(default)]    pub token_modifiers: Vec<String>,    #[serde(default)]    pub style: Vec<String>,    pub foreground_color: Option<Rgba>,    pub background_color: Option<Rgba>,    pub underline: Option<SemanticTokenColorOverride>,    pub strikethrough: Option<SemanticTokenColorOverride>,    pub font_weight: Option<SemanticTokenFontWeight>,    pub font_style: Option<SemanticTokenFontStyle>,} impl SemanticTokenRule {    pub fn no_style_defined(&self) -> bool {        self.style.is_empty()            && self.foreground_color.is_none()            && self.background_color.is_none()            && self.underline.is_none()            && self.strikethrough.is_none()            && self.font_weight.is_none()            && self.font_style.is_none()    }} #[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)]#[serde(untagged)]pub enum SemanticTokenColorOverride {    InheritForeground(bool),    Replace(Rgba),} #[derive(    Copy,    Clone,    Debug,    Default,    Serialize,    Deserialize,    PartialEq,    Eq,    JsonSchema,    MergeFrom,    strum::VariantArray,    strum::VariantNames,)]#[serde(rename_all = "snake_case")]pub enum SemanticTokenFontWeight {    #[default]    Normal,    Bold,} #[derive(    Copy,    Clone,    Debug,    Default,    Serialize,    Deserialize,    PartialEq,    Eq,    JsonSchema,    MergeFrom,    strum::VariantArray,    strum::VariantNames,)]#[serde(rename_all = "snake_case")]pub enum SemanticTokenFontStyle {    #[default]    Normal,    Italic,} #[with_fallible_options]#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom)]#[serde(rename_all = "snake_case")]pub struct DapSettingsContent {    pub binary: Option<String>,    pub args: Option<Vec<String>>,    pub env: Option<HashMap<String, String>>,} #[with_fallible_options]#[derive(    Default, Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, JsonSchema, MergeFrom,)]pub struct SessionSettingsContent {    /// Whether or not to restore unsaved buffers on restart.    ///    /// If this is true, user won't be prompted whether to save/discard    /// dirty files when closing the application.    ///    /// Default: true    pub restore_unsaved_buffers: Option<bool>,    /// Whether or not to skip worktree trust checks.    /// When trusted, project settings are synchronized automatically,    /// language and MCP servers are downloaded and started automatically.    ///    /// Default: false    pub trust_all_worktrees: Option<bool>,} #[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema, MergeFrom, Debug)]#[serde(untagged, rename_all = "snake_case")]pub enum ContextServerSettingsContent {    Stdio {        /// Whether the context server is enabled.        #[serde(default = "default_true")]        enabled: bool,        /// Whether to run the context server on the remote server when using remote development.        ///        /// If this is false, the context server will always run on the local machine.        ///        /// Default: false        #[serde(default)]        remote: bool,        #[serde(flatten)]        command: ContextServerCommand,    },    Http {        /// Whether the context server is enabled.        #[serde(default = "default_true")]        enabled: bool,        /// The URL of the remote context server.        url: String,        /// Optional headers to send.        #[serde(skip_serializing_if = "HashMap::is_empty", default)]        headers: HashMap<String, String>,        /// Timeout for tool calls in seconds. Defaults to global context_server_timeout if not specified.        timeout: Option<u64>,        /// Pre-registered OAuth client credentials for authorization servers that        /// require out-of-band client registration.        #[serde(default, skip_serializing_if = "Option::is_none")]        oauth: Option<OAuthClientSettings>,    },    Extension {        /// Whether the context server is enabled.        #[serde(default = "default_true")]        enabled: bool,        /// Whether to run the context server on the remote server when using remote development.        ///        /// If this is false, the context server will always run on the local machine.        ///        /// Default: false        #[serde(default)]        remote: bool,        /// The settings for this context server specified by the extension.        ///        /// Consult the documentation for the context server to see what settings        /// are supported.        settings: serde_json::Value,    },} impl ContextServerSettingsContent {    pub fn set_enabled(&mut self, enabled: bool) {        match self {            ContextServerSettingsContent::Stdio {                enabled: custom_enabled,                ..            } => {                *custom_enabled = enabled;            }            ContextServerSettingsContent::Extension {                enabled: ext_enabled,                ..            } => *ext_enabled = enabled,            ContextServerSettingsContent::Http {                enabled: remote_enabled,                ..            } => *remote_enabled = enabled,        }    }} /// Pre-registered OAuth client credentials for MCP servers that don't support/// Dynamic Client Registration.#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema, MergeFrom, Debug)]pub struct OAuthClientSettings {    /// The OAuth client ID obtained from out-of-band registration with the    /// authorization server.    pub client_id: String,    /// The OAuth client secret, if this is a confidential client. For security,    /// prefer providing this interactively; we will prompt and store it in    /// the system keychain.    #[serde(default, skip_serializing_if = "Option::is_none")]    pub client_secret: Option<String>,} #[with_fallible_options]#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, JsonSchema, MergeFrom)]pub struct ContextServerCommand {    #[serde(rename = "command")]    pub path: PathBuf,    #[serde(default)]    pub args: Vec<String>,    pub env: Option<HashMap<String, String>>,    /// Timeout for tool calls in seconds. Defaults to 60 if not specified.    pub timeout: Option<u64>,} impl std::fmt::Debug for ContextServerCommand {    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {        let filtered_env = self.env.as_ref().map(|env| {            env.iter()                .map(|(k, v)| {                    (                        k,                        if util::redact::should_redact(k) {                            "[REDACTED]"                        } else {

Lines 1–500 of 900.