mod action; mod agent; mod editor; mod extension; mod fallible_options; mod language; mod language_model; pub mod merge_from; mod project; mod serde_helper; mod terminal; mod theme; mod title_bar; mod workspace; pub use action::{ActionName, ActionWithArguments}; pub use agent::*; pub use editor::*; pub use extension::*; pub use fallible_options::*; pub use language::*; pub use language_model::*; pub use merge_from::MergeFrom as MergeFromTrait; pub use project::*; use serde::de::DeserializeOwned; pub use serde_helper::{ serialize_f32_with_two_decimal_places, serialize_optional_f32_with_two_decimal_places, }; use settings_json::parse_json_with_comments; pub use terminal::*; pub use theme::*; pub use title_bar::*; pub use workspace::*; use collections::{HashMap, IndexMap}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use settings_macros::{MergeFrom, with_fallible_options}; /// Defines a settings override struct where each field is /// `Option>`, along with: /// - `OVERRIDE_KEYS`: a `&[&str]` of the field names (the JSON keys) /// - `get_by_key(&self, key) -> Option<&SettingsContent>`: accessor by key /// /// The field list is the single source of truth for the override key strings. macro_rules! settings_overrides { ( $(#[$attr:meta])* pub struct $name:ident { $($field:ident),* $(,)? } ) => { $(#[$attr])* pub struct $name { $(pub $field: Option>,)* } impl $name { /// The JSON override keys, derived from the field names on this struct. pub const OVERRIDE_KEYS: &[&str] = &[$(stringify!($field)),*]; /// Look up an override by its JSON key name. pub fn get_by_key(&self, key: &str) -> Option<&SettingsContent> { match key { $(stringify!($field) => self.$field.as_deref(),)* _ => None, } } } } } use std::collections::{BTreeMap, BTreeSet}; use std::hash::Hash; use std::sync::Arc; pub use util::serde::default_true; #[derive(Debug, Clone, PartialEq, Eq)] pub enum ParseStatus { /// Settings were parsed successfully Success, /// Settings file was not changed, so no parsing was performed Unchanged, /// Settings failed to parse Failed { error: String }, } /// Determines when the mouse cursor should be hidden in response to keyboard /// input. /// /// Default: on_typing_and_action #[derive( Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum HideMouseMode { /// Never hide the mouse cursor Never, /// Hide only when typing OnTyping, /// Hide on typing and on key bindings that resolve to an action #[default] OnTypingAndAction, } #[with_fallible_options] #[derive(Debug, PartialEq, Default, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)] pub struct SettingsContent { #[serde(flatten)] pub project: ProjectSettingsContent, #[serde(flatten)] pub theme: Box, #[serde(flatten)] pub extension: ExtensionSettingsContent, #[serde(flatten)] pub workspace: WorkspaceSettingsContent, #[serde(flatten)] pub editor: EditorSettingsContent, #[serde(flatten)] pub remote: RemoteSettingsContent, /// Settings related to the file finder. pub file_finder: Option, pub git_panel: Option, pub tabs: Option, pub tab_bar: Option, pub status_bar: Option, pub preview_tabs: Option, pub agent: Option, pub agent_servers: Option, /// Configuration of audio in Zed. pub audio: Option, /// Whether or not to automatically check for updates. /// /// Default: true pub auto_update: Option, /// This base keymap settings adjusts the default keybindings in Zed to be similar /// to other common code editors. By default, Zed's keymap closely follows VSCode's /// keymap, with minor adjustments, this corresponds to the "VSCode" setting. /// /// Default: VSCode pub base_keymap: Option, /// Configuration for the collab panel visual settings. pub collaboration_panel: Option, pub debugger: Option, /// Configuration for Diagnostics-related features. pub diagnostics: Option, /// Configuration for Git-related features pub git: Option, /// Common language server settings. pub global_lsp_settings: Option, /// The settings for the image viewer. pub image_viewer: Option, pub repl: Option, /// Whether or not to enable Helix mode. /// /// Default: false pub helix_mode: Option, /// Determines when the mouse cursor should be hidden in response to /// keyboard input. Applies globally across all input surfaces (editors, /// terminals, palettes, etc.). /// /// Default: on_typing_and_action pub hide_mouse: Option, pub journal: Option, /// A map of log scopes to the desired log level. /// Useful for filtering out noisy logs or enabling more verbose logging. /// /// Example: {"log": {"client": "warn"}} pub log: Option>, pub line_indicator_format: Option, pub language_models: Option, pub outline_panel: Option, pub project_panel: Option, /// Configuration for the Message Editor pub message_editor: Option, /// Configuration for Node-related features pub node: Option, pub proxy: Option, /// The URL of the Zed server to connect to. pub server_url: Option, /// The URL used as the key for credential storage. /// /// When set, credentials are stored under this URL instead of `server_url`. /// This allows running multiple Zed instances side by side without them /// overwriting each other's keychain entries. pub credentials_url: Option, /// Configuration for session-related features pub session: Option, /// Control what info is collected by Zed. pub telemetry: Option, /// Configuration of the terminal in Zed. pub terminal: Option, pub title_bar: Option, /// Whether or not to enable Vim mode. /// /// Default: false pub vim_mode: Option, // Settings related to calls in Zed pub calls: Option, /// Settings for the which-key popup. pub which_key: Option, /// Settings related to Vim mode in Zed. pub vim: Option, /// Number of lines to search for modelines at the beginning and end of files. /// Modelines contain editor directives (e.g., vim/emacs settings) that configure /// the editor behavior for specific files. /// /// Default: 5 pub modeline_lines: Option, /// Local overrides for feature flags, keyed by flag name. pub feature_flags: Option, /// Settings for developer-oriented instrumentation tools (profilers, /// tracers, etc.) that can be toggled at runtime. pub instrumentation: Option, } /// Configuration for developer-oriented instrumentation tools that collect /// diagnostic data about a running Zed instance. #[with_fallible_options] #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)] pub struct InstrumentationSettingsContent { /// Configuration for the performance profiler, accessed via the /// `zed: open performance profiler` action. pub performance_profiler: Option, } /// Configuration for the performance profiler which collects timing data /// for foreground and background executor tasks. #[with_fallible_options] #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)] pub struct PerformanceProfilerSettingsContent { /// Whether to collect timing data for foreground and background executor /// tasks. Enabling this may lead to increased memory usage, hence it's /// disabled by default for regular builds. /// /// Default: false pub enabled: Option, } #[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, MergeFrom)] #[serde(transparent)] pub struct FeatureFlagsMap(pub HashMap); // A manual `JsonSchema` impl keeps this type's schema registered under a // unique name. The derived impl on a `#[serde(transparent)]` newtype around // `HashMap` would inline to the map's own schema name (`Map_of_string`), // which is shared with every other `HashMap` setting field in // `SettingsContent`. A named placeholder lets `json_schema_store` find and // replace just this field's schema at runtime without clobbering the others. impl JsonSchema for FeatureFlagsMap { fn schema_name() -> std::borrow::Cow<'static, str> { "FeatureFlagsMap".into() } fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { schemars::json_schema!({ "type": "object", "additionalProperties": { "type": "string" } }) } } impl std::ops::Deref for FeatureFlagsMap { type Target = HashMap; fn deref(&self) -> &Self::Target { &self.0 } } impl std::ops::DerefMut for FeatureFlagsMap { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl SettingsContent { pub fn languages_mut(&mut self) -> &mut HashMap { &mut self.project.all_languages.languages.0 } } // These impls are there to optimize builds by avoiding monomorphization downstream. Yes, they're repetitive, but using default impls // break the optimization, for whatever reason. pub trait RootUserSettings: Sized + DeserializeOwned { fn parse_json(json: &str) -> (Option, ParseStatus); fn parse_json_with_comments(json: &str) -> anyhow::Result; } impl RootUserSettings for SettingsContent { fn parse_json(json: &str) -> (Option, ParseStatus) { fallible_options::parse_json(json) } fn parse_json_with_comments(json: &str) -> anyhow::Result { parse_json_with_comments(json) } } // Explicit opt-in instead of blanket impl to avoid monomorphizing downstream. Just a hunch though. impl RootUserSettings for Option { fn parse_json(json: &str) -> (Option, ParseStatus) { fallible_options::parse_json(json) } fn parse_json_with_comments(json: &str) -> anyhow::Result { parse_json_with_comments(json) } } impl RootUserSettings for UserSettingsContent { fn parse_json(json: &str) -> (Option, ParseStatus) { fallible_options::parse_json(json) } fn parse_json_with_comments(json: &str) -> anyhow::Result { parse_json_with_comments(json) } } settings_overrides! { #[with_fallible_options] #[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)] pub struct ReleaseChannelOverrides { dev, nightly, preview, stable } } settings_overrides! { #[with_fallible_options] #[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)] pub struct PlatformOverrides { macos, linux, windows } } /// Determines what settings a profile starts from before applying its overrides. #[derive( Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom, )] #[serde(rename_all = "snake_case")] pub enum ProfileBase { /// Apply profile settings on top of the user's current settings. #[default] User, /// Apply profile settings on top of Zed's default settings, ignoring user customizations. Default, } /// A named settings profile that can temporarily override settings. #[with_fallible_options] #[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)] pub struct SettingsProfile { /// What base settings to start from before applying this profile's overrides. /// /// - `user`: Apply on top of user's settings (default) /// - `default`: Apply on top of Zed's default settings, ignoring user customizations #[serde(default)] pub base: ProfileBase, /// The settings overrides for this profile. #[serde(default)] pub settings: Box, } #[with_fallible_options] #[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, JsonSchema, MergeFrom)] pub struct UserSettingsContent { #[serde(flatten)] pub content: Box, #[serde(flatten)] pub release_channel_overrides: ReleaseChannelOverrides, #[serde(flatten)] pub platform_overrides: PlatformOverrides, #[serde(default)] pub profiles: IndexMap, } pub struct ExtensionsSettingsContent { pub all_languages: AllLanguageSettingsContent, } /// Base key bindings scheme. Base keymaps can be overridden with user keymaps. /// /// Default: VSCode #[derive( Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default, strum::VariantArray, )] pub enum BaseKeymapContent { #[default] VSCode, JetBrains, SublimeText, Atom, TextMate, Emacs, Cursor, None, } impl strum::VariantNames for BaseKeymapContent { const VARIANTS: &'static [&'static str] = &[ "VSCode", "JetBrains", "Sublime Text", "Atom", "TextMate", "Emacs", "Cursor", "None", ]; } /// Configuration of audio in Zed. #[with_fallible_options] #[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)] pub struct AudioSettingsContent { /// Automatically increase or decrease you microphone's volume. This affects how /// loud you sound to others. /// /// Recommended: off (default) /// Microphones are too quite in zed, until everyone is on experimental /// audio and has auto speaker volume on this will make you very loud /// compared to other speakers. #[serde(rename = "experimental.auto_microphone_volume")] pub auto_microphone_volume: Option, /// Remove background noises. Works great for typing, cars, dogs, AC. Does /// not work well on music. /// Select specific output audio device. #[serde(rename = "experimental.output_audio_device")] pub output_audio_device: Option, /// Select specific input audio device. #[serde(rename = "experimental.input_audio_device")] pub input_audio_device: Option, } #[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)] #[serde(transparent)] pub struct AudioOutputDeviceName(pub Option); impl AsRef> for AudioInputDeviceName { fn as_ref(&self) -> &Option { &self.0 } } impl From> for AudioInputDeviceName { fn from(value: Option) -> Self { Self(value) } } #[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)] #[serde(transparent)] pub struct AudioInputDeviceName(pub Option); impl AsRef> for AudioOutputDeviceName { fn as_ref(&self) -> &Option { &self.0 } } impl From> for AudioOutputDeviceName { fn from(value: Option) -> Self { Self(value) } } /// Control what info is collected by Zed. #[with_fallible_options] #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Debug, MergeFrom)] pub struct TelemetrySettingsContent { /// Send debug info like crash reports. /// /// Default: true pub diagnostics: Option, /// Send anonymized usage data like what languages you're using Zed with. /// /// Default: true pub metrics: Option, } impl Default for TelemetrySettingsContent { fn default() -> Self { Self { diagnostics: Some(true), metrics: Some(true), } } } #[with_fallible_options] #[derive(Default, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Clone, MergeFrom)] pub struct DebuggerSettingsContent { /// Determines the stepping granularity. /// /// Default: line pub stepping_granularity: Option, /// Whether the breakpoints should be reused across Zed sessions. /// /// Default: true pub save_breakpoints: Option, /// Whether to show the debug button in the status bar. /// /// Default: true pub button: Option, /// Time in milliseconds until timeout error when connecting to a TCP debug adapter /// /// Default: 2000ms pub timeout: Option, /// Whether to log messages between active debug adapters and Zed /// /// Default: true pub log_dap_communications: Option, /// Whether to format dap messages in when adding them to debug adapter logger /// /// Default: true pub format_dap_log_messages: Option, /// The dock position of the debug panel /// /// Default: Bottom pub dock: Option, } /// The granularity of one 'step' in the stepping requests `next`, `stepIn`, `stepOut`, and `stepBack`. #[derive( PartialEq, Eq, Debug, Hash, Clone, Copy, Deserialize, Serialize, JsonSchema, MergeFrom, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum SteppingGranularity { /// The step should allow the program to run until the current statement has finished executing. /// The meaning of a statement is determined by the adapter and it may be considered equivalent to a line. /// For example 'for(int i = 0; i < 10; i++)' could be considered to have 3 statements 'int i = 0', 'i < 10', and 'i++'. Statement, /// The step should allow the program to run until the current source line has executed. Line, /// The step should allow one instruction to execute (e.g. one x86 instruction). Instruction, } #[derive( Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum DockPosition { Left, Bottom, Right, } /// Configuration of voice calls in Zed. #[with_fallible_options] #[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)] pub struct CallSettingsContent { /// Whether the microphone should be muted when joining a channel or a call. /// /// Default: false pub mute_on_join: Option, /// Whether your current project should be shared when joining an empty channel. /// /// Default: false pub share_on_join: Option, } #[with_fallible_options] #[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)] pub struct GitPanelSettingsContent { /// Whether to show the panel button in the status bar. /// /// Default: true pub button: Option, /// Where to dock the panel. /// /// Default: right pub dock: Option, /// Default width of the panel in pixels. /// /// Default: 360 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")] pub default_width: Option, /// How entry statuses are displayed. /// /// Default: icon pub status_style: Option, /// Whether to show file icons in the git panel. /// /// Default: false pub file_icons: Option, /// Whether to show folder icons or chevrons for directories in the git panel. /// /// Default: true pub folder_icons: Option, /// How and when the scrollbar should be displayed. /// /// Default: inherits editor scrollbar settings pub scrollbar: Option, /// What the default branch name should be when /// `init.defaultBranch` is not set in git /// /// Default: main pub fallback_branch_name: Option, /// Whether to sort entries in the panel by path /// or by status (the default). /// /// Default: false pub sort_by_path: Option, /// Whether to collapse untracked files in the diff panel. /// /// Default: false pub collapse_untracked_diff: Option, /// Whether to show entries with tree or flat view in the panel /// /// Default: false pub tree_view: Option, /// Whether to show the addition/deletion change count next to each file in the Git panel. /// /// Default: true pub diff_stats: Option, /// Whether to show a badge on the git panel icon with the count of uncommitted changes. /// /// Default: false pub show_count_badge: Option, /// Whether the git panel should open on startup. /// /// Default: false pub starts_open: Option, /// Maximum length of the commit message title before a warning is shown. /// Set to 0 to disable. /// /// Default: 72 pub commit_title_max_length: Option, } #[derive( Default, Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum StatusStyle { #[default] Icon, LabelColor, } #[with_fallible_options] #[derive( Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, )] pub struct ScrollbarSettings { pub show: Option, } #[with_fallible_options] #[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)] pub struct PanelSettingsContent { /// Whether to show the panel button in the status bar. /// /// Default: true pub button: Option, /// Where to dock the panel. /// /// Default: right pub dock: Option, /// Default width of the panel in pixels. /// /// Default: 240 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")] pub default_width: Option, } #[with_fallible_options] #[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)] pub struct MessageEditorSettings { /// Whether to automatically replace emoji shortcodes with emoji characters. /// For example: typing `:wave:` gets replaced with `👋`. /// /// Default: false pub auto_replace_emoji_shortcode: Option, } #[with_fallible_options] #[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)] pub struct FileFinderSettingsContent { /// Whether to show file icons in the file finder. /// /// Default: true pub file_icons: Option, /// Determines how much space the file finder can take up in relation to the available window width. /// /// Default: small pub modal_max_width: Option, /// Determines whether the file finder should skip focus for the active file in search results. /// /// Default: true pub skip_focus_for_active_in_search: Option, /// Whether to use gitignored files when searching. /// Only the file Zed had indexed will be used, not necessary all the gitignored files. /// /// Default: Smart pub include_ignored: Option, /// Whether to include text channels in file finder results. /// /// Default: false pub include_channels: Option, } #[derive( Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema, MergeFrom, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum IncludeIgnoredContent { /// Use all gitignored files All, /// Use only the files Zed had indexed Indexed, /// Be smart and search for ignored when called from a gitignored worktree #[default] Smart, } #[derive( Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema, MergeFrom, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "lowercase")] pub enum FileFinderWidthContent { #[default] Small, Medium, Large, XLarge, Full, } #[with_fallible_options] #[derive(Clone, Default, Serialize, Deserialize, PartialEq, Debug, JsonSchema, MergeFrom)] pub struct VimSettingsContent { pub default_mode: Option, pub toggle_relative_line_numbers: Option, pub use_system_clipboard: Option, pub use_smartcase_find: Option, pub use_regex_search: Option, /// When enabled, the `:substitute` command replaces all matches in a line /// by default. The 'g' flag then toggles this behavior., pub gdefault: Option, pub custom_digraphs: Option>>, pub highlight_on_yank_duration: Option, pub cursor_shape: Option, /// When enabled, edit predictions are shown in Vim normal mode. /// By default, edit predictions are only shown in insert and replace modes. pub show_edit_predictions_in_normal_mode: Option, } #[derive( Copy, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Debug, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum ModeContent { #[default] Normal, Insert, } /// Controls when to use system clipboard. #[derive( Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum UseSystemClipboard { /// Don't use system clipboard. Never, /// Use system clipboard. Always, /// Use system clipboard for yank operations. OnYank, } /// Cursor shape configuration for insert mode in Vim. #[derive( Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum VimInsertModeCursorShape { /// Inherit cursor shape from the editor's base cursor_shape setting. Inherit, /// Vertical bar cursor. Bar, /// Block cursor that surrounds the character. Block, /// Underline cursor. Underline, /// Hollow box cursor. Hollow, } /// The settings for cursor shape. #[with_fallible_options] #[derive( Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, )] pub struct CursorShapeSettings { /// Cursor shape for the normal mode. /// /// Default: block pub normal: Option, /// Cursor shape for the replace mode. /// /// Default: underline pub replace: Option, /// Cursor shape for the visual mode. /// /// Default: block pub visual: Option, /// Cursor shape for the insert mode. /// /// The default value follows the primary cursor_shape. pub insert: Option, } /// Settings specific to journaling #[with_fallible_options] #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)] pub struct JournalSettingsContent { /// The path of the directory where journal entries are stored. /// /// Default: `~` pub path: Option, /// What format to display the hours in. /// /// Default: hour12 pub hour_format: Option, } #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)] #[serde(rename_all = "snake_case")] pub enum HourFormat { #[default] Hour12, Hour24, } #[with_fallible_options] #[derive(Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, PartialEq)] pub struct OutlinePanelSettingsContent { /// Whether to show the outline panel button in the status bar. /// /// Default: true pub button: Option, /// Customize default width (in pixels) taken by outline panel /// /// Default: 240 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")] pub default_width: Option, /// The position of outline panel /// /// Default: right pub dock: Option, /// Whether to show file icons in the outline panel. /// /// Default: true pub file_icons: Option, /// Whether to show folder icons or chevrons for directories in the outline panel. /// /// Default: true pub folder_icons: Option, /// Whether to show the git status in the outline panel. /// /// Default: true pub git_status: Option, /// Amount of indentation (in pixels) for nested items. /// /// Default: 20 #[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")] pub indent_size: Option, /// Whether to reveal it in the outline panel automatically, /// when a corresponding project entry becomes active. /// Gitignored entries are never auto revealed. /// /// Default: true pub auto_reveal_entries: Option, /// Whether to fold directories automatically /// when directory has only one directory inside. /// /// Default: true pub auto_fold_dirs: Option, /// Settings related to indent guides in the outline panel. pub indent_guides: Option, /// Scrollbar-related settings pub scrollbar: Option, /// Default depth to expand outline items in the current file. /// The default depth to which outline entries are expanded on reveal. /// - Set to 0 to collapse all items that have children /// - Set to 1 or higher to collapse items at that depth or deeper /// /// Default: 100 pub expand_outlines_with_depth: Option, } #[derive( Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, MergeFrom, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum DockSide { Left, Right, } #[derive( Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize, JsonSchema, MergeFrom, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum ShowIndentGuides { Always, Never, } #[with_fallible_options] #[derive( Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default, )] pub struct IndentGuidesSettingsContent { /// When to show the scrollbar in the outline panel. pub show: Option, } #[derive(Clone, Copy, Default, PartialEq, Debug, JsonSchema, MergeFrom, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum LineIndicatorFormat { Short, #[default] Long, } /// The settings for the image viewer. #[with_fallible_options] #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, Default, PartialEq)] pub struct ImageViewerSettingsContent { /// The unit to use for displaying image file sizes. /// /// Default: "binary" pub unit: Option, } #[with_fallible_options] #[derive( Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, Default, PartialEq, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum ImageFileSizeUnit { /// Displays file size in binary units (e.g., KiB, MiB). #[default] Binary, /// Displays file size in decimal units (e.g., KB, MB). Decimal, } #[with_fallible_options] #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)] pub struct RemoteSettingsContent { pub ssh_connections: Option>, pub wsl_connections: Option>, pub dev_container_connections: Option>, pub read_ssh_config: Option, pub use_podman: Option, } #[with_fallible_options] #[derive( Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, MergeFrom, Hash, )] pub struct DevContainerConnection { pub name: String, pub remote_user: String, pub container_id: String, pub use_podman: bool, pub extension_ids: Vec, pub remote_env: BTreeMap, } #[with_fallible_options] #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom)] pub struct SshConnection { pub host: String, pub username: Option, pub port: Option, #[serde(default)] pub args: Vec, #[serde(default)] pub projects: collections::BTreeSet, /// Name to use for this server in UI. pub nickname: Option, // By default Zed will download the binary to the host directly. // If this is set to true, Zed will download the binary to your local machine, // and then upload it over the SSH connection. Useful if your SSH server has // limited outbound internet access. pub upload_binary_over_ssh: Option, pub port_forwards: Option>, /// Timeout in seconds for SSH connection and downloading the remote server binary. /// Defaults to 10 seconds if not specified. pub connection_timeout: Option, } #[derive(Clone, Default, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom, Debug)] pub struct WslConnection { pub distro_name: String, pub user: Option, #[serde(default)] pub projects: BTreeSet, } #[with_fallible_options] #[derive( Clone, Debug, Default, Serialize, PartialEq, Eq, PartialOrd, Ord, Deserialize, JsonSchema, )] pub struct RemoteProject { pub paths: Vec, } #[with_fallible_options] #[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, JsonSchema, MergeFrom)] pub struct SshPortForwardOption { pub local_host: Option, pub local_port: u16, pub remote_host: Option, pub remote_port: u16, } /// Settings for configuring REPL display and behavior. #[with_fallible_options] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)] pub struct ReplSettingsContent { /// Maximum number of lines to keep in REPL's scrollback buffer. /// Clamped with [4, 256] range. /// /// Default: 32 pub max_lines: Option, /// Maximum number of columns to keep in REPL's scrollback buffer. /// Clamped with [20, 512] range. /// /// Default: 128 pub max_columns: Option, /// Whether to show small single-line outputs inline instead of in a block. /// /// Default: true pub inline_output: Option, /// Maximum number of characters for an output to be shown inline. /// Only applies when `inline_output` is true. /// /// Default: 50 pub inline_output_max_length: Option, /// Maximum number of lines of output to display before scrolling. /// Set to 0 to disable output height limits. /// /// Default: 0 pub output_max_height_lines: Option, } /// Settings for configuring the which-key popup behaviour. #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom)] pub struct WhichKeySettingsContent { /// Whether to show the which-key popup when holding down key combinations /// /// Default: false pub enabled: Option, /// Delay in milliseconds before showing the which-key popup. /// /// Default: 700 pub delay_ms: Option, } // An ExtendingVec in the settings can only accumulate new values. // // This is useful for things like private files where you only want // to allow new values to be added. // // Consider using a HashMap instead of this type // (like auto_install_extensions) so that user settings files can both add // and remove values from the set. #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct ExtendingVec(pub Vec); impl Into> for ExtendingVec { fn into(self) -> Vec { self.0 } } impl From> for ExtendingVec { fn from(vec: Vec) -> Self { ExtendingVec(vec) } } impl merge_from::MergeFrom for ExtendingVec { fn merge_from(&mut self, other: &Self) { self.0.extend_from_slice(other.0.as_slice()); } } // A SaturatingBool in the settings can only ever be set to true, // later attempts to set it to false will be ignored. // // Used by `disable_ai`. #[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct SaturatingBool(pub bool); impl From for SaturatingBool { fn from(value: bool) -> Self { SaturatingBool(value) } } impl From for bool { fn from(value: SaturatingBool) -> bool { value.0 } } impl merge_from::MergeFrom for SaturatingBool { fn merge_from(&mut self, other: &Self) { self.0 |= other.0 } } #[derive( Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, MergeFrom, JsonSchema, derive_more::FromStr, )] #[serde(transparent)] pub struct DelayMs(pub u64); impl From for DelayMs { fn from(n: u64) -> Self { Self(n) } } impl std::fmt::Display for DelayMs { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}ms", self.0) } }