8801 lines · 387.0 KB · Rust
RawDownload
use gpui::{Action as _, App};use settings::{LanguageSettingsContent, SettingsContent};use std::sync::Arc;use strum::IntoDiscriminant as _;use ui::{IntoElement, SharedString}; use crate::{    ActionLink, DynamicItem, PROJECT, SettingField, SettingItem, SettingsFieldMetadata,    SettingsPage, SettingsPageItem, SubPageLink, USER, all_language_names, sub_page_stack,}; const DEFAULT_STRING: String = String::new();/// A default empty string reference. Useful in `pick` functions for cases either in dynamic item fields, or when dealing with `settings::Maybe`/// to avoid the "NO DEFAULT" case.const DEFAULT_EMPTY_STRING: Option<&String> = Some(&DEFAULT_STRING); const DEFAULT_SHARED_STRING: SharedString = SharedString::new_static("");/// A default empty string reference. Useful in `pick` functions for cases either in dynamic item fields, or when dealing with `settings::Maybe`/// to avoid the "NO DEFAULT" case.const DEFAULT_EMPTY_SHARED_STRING: Option<&SharedString> = Some(&DEFAULT_SHARED_STRING); macro_rules! concat_sections {    (@vec, $($arr:expr),+ $(,)?) => {{        let total_len = 0_usize $(+ $arr.len())+;        let mut out = Vec::with_capacity(total_len);         $(            out.extend($arr);        )+         out    }};     ($($arr:expr),+ $(,)?) => {{        let total_len = 0_usize $(+ $arr.len())+;         let mut out: Box<[std::mem::MaybeUninit<_>]> = Box::new_uninit_slice(total_len);         let mut index = 0usize;        $(            let array = $arr;            for item in array {                out[index].write(item);                index += 1;            }        )+         debug_assert_eq!(index, total_len);         // SAFETY: we wrote exactly `total_len` elements.        unsafe { out.assume_init() }    }};} pub(crate) fn settings_data(cx: &App) -> Vec<SettingsPage> {    vec![        general_page(),        appearance_page(),        keymap_page(),        editor_page(),        languages_and_tools_page(cx),        search_and_files_page(),        window_and_layout_page(),        panels_page(),        debugger_page(),        terminal_page(),        version_control_page(),        collaboration_page(),        ai_page(),        network_page(),    ]} fn general_page() -> SettingsPage {    fn general_settings_section() -> [SettingsPageItem; 8] {        [            SettingsPageItem::SectionHeader("General Settings"),            SettingsPageItem::SettingItem(SettingItem {                files: PROJECT,                title: "Project Name",                description: "The displayed name of this project. If left empty, the root directory name will be displayed.",                field: Box::new(SettingField {                    json_path: Some("project_name"),                    pick: |settings_content| {                        settings_content                            .project                            .worktree                            .project_name                            .as_ref()                            .or(DEFAULT_EMPTY_STRING)                    },                    write: |settings_content, value| {                        settings_content.project.worktree.project_name =                            value.filter(|name| !name.is_empty());                    },                }),                metadata: Some(Box::new(SettingsFieldMetadata {                    placeholder: Some("Project Name"),                    ..Default::default()                })),            }),            SettingsPageItem::SettingItem(SettingItem {                title: "When Closing With No Tabs",                description: "What to do when using the 'close active item' action with no tabs.",                field: Box::new(SettingField {                    json_path: Some("when_closing_with_no_tabs"),                    pick: |settings_content| {                        settings_content                            .workspace                            .when_closing_with_no_tabs                            .as_ref()                    },                    write: |settings_content, value| {                        settings_content.workspace.when_closing_with_no_tabs = value;                    },                }),                metadata: None,                files: USER,            }),            SettingsPageItem::SettingItem(SettingItem {                title: "On Last Window Closed",                description: "What to do when the last window is closed.",                field: Box::new(SettingField {                    json_path: Some("on_last_window_closed"),                    pick: |settings_content| {                        settings_content.workspace.on_last_window_closed.as_ref()                    },                    write: |settings_content, value| {                        settings_content.workspace.on_last_window_closed = value;                    },                }),                metadata: None,                files: USER,            }),            SettingsPageItem::SettingItem(SettingItem {                title: "Use System Path Prompts",                description: "Use native OS dialogs for 'Open' and 'Save As'.",                field: Box::new(SettingField {                    json_path: Some("use_system_path_prompts"),                    pick: |settings_content| {                        settings_content.workspace.use_system_path_prompts.as_ref()                    },                    write: |settings_content, value| {                        settings_content.workspace.use_system_path_prompts = value;                    },                }),                metadata: None,                files: USER,            }),            SettingsPageItem::SettingItem(SettingItem {                title: "Use System Prompts",                description: "Use native OS dialogs for confirmations.",                field: Box::new(SettingField {                    json_path: Some("use_system_prompts"),                    pick: |settings_content| settings_content.workspace.use_system_prompts.as_ref(),                    write: |settings_content, value| {                        settings_content.workspace.use_system_prompts = value;                    },                }),                metadata: None,                files: USER,            }),            SettingsPageItem::SettingItem(SettingItem {                title: "Redact Private Values",                description: "Hide the values of variables in private files.",                field: Box::new(SettingField {                    json_path: Some("redact_private_values"),                    pick: |settings_content| settings_content.editor.redact_private_values.as_ref(),                    write: |settings_content, value| {                        settings_content.editor.redact_private_values = value;                    },                }),                metadata: None,                files: USER,            }),            SettingsPageItem::SettingItem(SettingItem {                title: "Private Files",                description: "Globs to match against file paths to determine if a file is private.",                field: Box::new(                    SettingField {                        json_path: Some("worktree.private_files"),                        pick: |settings_content| {                            settings_content.project.worktree.private_files.as_ref()                        },                        write: |settings_content, value| {                            settings_content.project.worktree.private_files = value;                        },                    }                    .unimplemented(),                ),                metadata: None,                files: USER,            }),        ]    }    fn security_section() -> [SettingsPageItem; 2] {        [            SettingsPageItem::SectionHeader("Security"),            SettingsPageItem::SettingItem(SettingItem {                title: "Trust All Projects By Default",                description: "When opening Zed, avoid Restricted Mode by auto-trusting all projects, enabling use of all features without having to give permission to each new project.",                field: Box::new(SettingField {                    json_path: Some("session.trust_all_projects"),                    pick: |settings_content| {                        settings_content                            .session                            .as_ref()                            .and_then(|session| session.trust_all_worktrees.as_ref())                    },                    write: |settings_content, value| {                        settings_content                            .session                            .get_or_insert_default()                            .trust_all_worktrees = value;                    },                }),                metadata: None,                files: USER,            }),        ]    }     fn workspace_restoration_section() -> [SettingsPageItem; 3] {        [            SettingsPageItem::SectionHeader("Workspace Restoration"),            SettingsPageItem::SettingItem(SettingItem {                title: "Restore Unsaved Buffers",                description: "Whether or not to restore unsaved buffers on restart.",                field: Box::new(SettingField {                    json_path: Some("session.restore_unsaved_buffers"),                    pick: |settings_content| {                        settings_content                            .session                            .as_ref()                            .and_then(|session| session.restore_unsaved_buffers.as_ref())                    },                    write: |settings_content, value| {                        settings_content                            .session                            .get_or_insert_default()                            .restore_unsaved_buffers = value;                    },                }),                metadata: None,                files: USER,            }),            SettingsPageItem::SettingItem(SettingItem {                title: "Restore On Startup",                description: "What to restore from the previous session when opening Zed.",                field: Box::new(SettingField {                    json_path: Some("restore_on_startup"),                    pick: |settings_content| settings_content.workspace.restore_on_startup.as_ref(),                    write: |settings_content, value| {                        settings_content.workspace.restore_on_startup = value;                    },                }),                metadata: None,                files: USER,            }),        ]    }     fn scoped_settings_section() -> [SettingsPageItem; 3] {        [            SettingsPageItem::SectionHeader("Scoped Settings"),            SettingsPageItem::SettingItem(SettingItem {                files: USER,                title: "Preview Channel",                description: "Which settings should be activated only in Preview build of Zed.",                field: Box::new(                    SettingField {                        json_path: Some("preview_channel_settings"),                        pick: |settings_content| Some(settings_content),                        write: |_settings_content, _value| {},                    }                    .unimplemented(),                ),                metadata: None,            }),            SettingsPageItem::SettingItem(SettingItem {                files: USER,                title: "Settings Profiles",                description: "Any number of settings profiles that are temporarily applied on top of your existing user settings.",                field: Box::new(                    SettingField {                        json_path: Some("settings_profiles"),                        pick: |settings_content| Some(settings_content),                        write: |_settings_content, _value| {},                    }                    .unimplemented(),                ),                metadata: None,            }),        ]    }     fn privacy_section() -> [SettingsPageItem; 3] {        [            SettingsPageItem::SectionHeader("Privacy"),            SettingsPageItem::SettingItem(SettingItem {                title: "Telemetry Diagnostics",                description: "Send debug information like crash reports.",                field: Box::new(SettingField {                    json_path: Some("telemetry.diagnostics"),                    pick: |settings_content| {                        settings_content                            .telemetry                            .as_ref()                            .and_then(|telemetry| telemetry.diagnostics.as_ref())                    },                    write: |settings_content, value| {                        settings_content                            .telemetry                            .get_or_insert_default()                            .diagnostics = value;                    },                }),                metadata: None,                files: USER,            }),            SettingsPageItem::SettingItem(SettingItem {                title: "Telemetry Metrics",                description: "Send anonymized usage data like what languages you're using Zed with.",                field: Box::new(SettingField {                    json_path: Some("telemetry.metrics"),                    pick: |settings_content| {                        settings_content                            .telemetry                            .as_ref()                            .and_then(|telemetry| telemetry.metrics.as_ref())                    },                    write: |settings_content, value| {                        settings_content.telemetry.get_or_insert_default().metrics = value;                    },                }),                metadata: None,                files: USER,            }),        ]    }     fn auto_update_section() -> [SettingsPageItem; 2] {        [            SettingsPageItem::SectionHeader("Auto Update"),            SettingsPageItem::SettingItem(SettingItem {                title: "Auto Update",                description: "Whether or not to automatically check for updates.",                field: Box::new(SettingField {                    json_path: Some("auto_update"),                    pick: |settings_content| settings_content.auto_update.as_ref(),                    write: |settings_content, value| {                        settings_content.auto_update = value;                    },                }),                metadata: None,                files: USER,            }),        ]    }     SettingsPage {        title: "General",        items: concat_sections!(            general_settings_section(),            security_section(),            workspace_restoration_section(),            scoped_settings_section(),            privacy_section(),            auto_update_section(),        ),    }} fn appearance_page() -> SettingsPage {    fn theme_section() -> [SettingsPageItem; 3] {        [            SettingsPageItem::SectionHeader("Theme"),            SettingsPageItem::DynamicItem(DynamicItem {                discriminant: SettingItem {                    files: USER,                    title: "Theme Mode",                    description: "Choose a static, fixed theme or dynamically select themes based on appearance and light/dark modes.",                    field: Box::new(SettingField {                        json_path: Some("theme$"),                        pick: |settings_content| {                            Some(&dynamic_variants::<settings::ThemeSelection>()[                                settings_content                                    .theme                                    .theme                                    .as_ref()?                                    .discriminant() as usize])                        },                        write: |settings_content, value| {                            let Some(value) = value else {                                settings_content.theme.theme = None;                                return;                            };                            let settings_value = settings_content.theme.theme.get_or_insert_default();                            *settings_value = match value {                                settings::ThemeSelectionDiscriminants::Static => {                                    let name = match settings_value {                                        settings::ThemeSelection::Static(_) => return,                                        settings::ThemeSelection::Dynamic { mode, light, dark } => {                                            match mode {                                                theme::ThemeAppearanceMode::Light => light.clone(),                                                theme::ThemeAppearanceMode::Dark => dark.clone(),                                                theme::ThemeAppearanceMode::System => dark.clone(), // no cx, can't determine correct choice                                            }                                        },                                    };                                    settings::ThemeSelection::Static(name)                                },                                settings::ThemeSelectionDiscriminants::Dynamic => {                                    let static_name = match settings_value {                                        settings::ThemeSelection::Static(theme_name) => theme_name.clone(),                                        settings::ThemeSelection::Dynamic {..} => return,                                    };                                     settings::ThemeSelection::Dynamic {                                        mode: settings::ThemeAppearanceMode::System,                                        light: static_name.clone(),                                        dark: static_name,                                    }                                },                            };                        },                    }),                    metadata: None,                },                pick_discriminant: |settings_content| {                    Some(settings_content.theme.theme.as_ref()?.discriminant() as usize)                },                fields: dynamic_variants::<settings::ThemeSelection>().into_iter().map(|variant| {                    match variant {                        settings::ThemeSelectionDiscriminants::Static => vec![                            SettingItem {                                files: USER,                                title: "Theme Name",                                description: "The name of your selected theme.",                                field: Box::new(SettingField {                                    json_path: Some("theme"),                                    pick: |settings_content| {                                        match settings_content.theme.theme.as_ref() {                                            Some(settings::ThemeSelection::Static(name)) => Some(name),                                            _ => None                                        }                                    },                                    write: |settings_content, value| {                                        let Some(value) = value else {                                            return;                                        };                                        match settings_content                                            .theme                                            .theme.get_or_insert_default() {                                                settings::ThemeSelection::Static(theme_name) => *theme_name = value,                                                _ => return                                            }                                    },                                }),                                metadata: None,                            }                        ],                        settings::ThemeSelectionDiscriminants::Dynamic => vec![                            SettingItem {                                files: USER,                                title: "Mode",                                description: "Choose whether to use the selected light or dark theme or to follow your OS appearance configuration.",                                field: Box::new(SettingField {                                    json_path: Some("theme.mode"),                                    pick: |settings_content| {                                        match settings_content.theme.theme.as_ref() {                                            Some(settings::ThemeSelection::Dynamic { mode, ..}) => Some(mode),                                            _ => None                                        }                                    },                                    write: |settings_content, value| {                                        let Some(value) = value else {                                            return;                                        };                                        match settings_content                                            .theme                                            .theme.get_or_insert_default() {                                                settings::ThemeSelection::Dynamic{ mode, ..} => *mode = value,                                                _ => return                                            }                                    },                                }),                                metadata: None,                            },                            SettingItem {                                files: USER,                                title: "Light Theme",                                description: "The theme to use when mode is set to light, or when mode is set to system and it is in light mode.",                                field: Box::new(SettingField {                                    json_path: Some("theme.light"),                                    pick: |settings_content| {                                        match settings_content.theme.theme.as_ref() {                                            Some(settings::ThemeSelection::Dynamic { light, ..}) => Some(light),                                            _ => None                                        }

Lines 1–500 of 8801.