use gpui::App; use language::CursorShape; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use settings::{Settings, SettingsSources}; #[derive(Deserialize, Clone)] pub struct EditorSettings { pub cursor_blink: bool, pub cursor_shape: Option, pub current_line_highlight: CurrentLineHighlight, pub selection_highlight: bool, pub selection_highlight_debounce: u64, pub lsp_highlight_debounce: u64, pub hover_popover_enabled: bool, pub hover_popover_delay: u64, pub toolbar: Toolbar, pub scrollbar: Scrollbar, pub gutter: Gutter, pub scroll_beyond_last_line: ScrollBeyondLastLine, pub vertical_scroll_margin: f32, pub autoscroll_on_clicks: bool, pub horizontal_scroll_margin: f32, pub scroll_sensitivity: f32, pub relative_line_numbers: bool, pub seed_search_query_from_cursor: SeedQuerySetting, pub use_smartcase_search: bool, pub multi_cursor_modifier: MultiCursorModifier, pub redact_private_values: bool, pub expand_excerpt_lines: u32, pub middle_click_paste: bool, #[serde(default)] pub double_click_in_multibuffer: DoubleClickInMultibuffer, pub search_wrap: bool, #[serde(default)] pub search: SearchSettings, pub auto_signature_help: bool, pub show_signature_help_after_edits: bool, pub jupyter: Jupyter, pub hide_mouse_while_typing: Option, } #[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum CurrentLineHighlight { // Don't highlight the current line. None, // Highlight the gutter area. Gutter, // Highlight the editor area. Line, // Highlight the full line. All, } /// When to populate a new search's query based on the text under the cursor. #[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum SeedQuerySetting { /// Always populate the search query with the word under the cursor. Always, /// Only populate the search query when there is text selected. Selection, /// Never populate the search query Never, } /// What to do when multibuffer is double clicked in some of its excerpts (parts of singleton buffers). #[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum DoubleClickInMultibuffer { /// Behave as a regular buffer and select the whole word. #[default] Select, /// Open the excerpt clicked as a new buffer in the new tab, if no `alt` modifier was pressed during double click. /// Otherwise, behave as a regular buffer and select the whole word. Open, } #[derive(Debug, Clone, Deserialize)] pub struct Jupyter { /// Whether the Jupyter feature is enabled. /// /// Default: true pub enabled: bool, } #[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct JupyterContent { /// Whether the Jupyter feature is enabled. /// /// Default: true pub enabled: Option, } #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] pub struct Toolbar { pub breadcrumbs: bool, pub quick_actions: bool, pub selections_menu: bool, } #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] pub struct Scrollbar { pub show: ShowScrollbar, pub git_diff: bool, pub selected_text: bool, pub selected_symbol: bool, pub search_results: bool, pub diagnostics: ScrollbarDiagnostics, pub cursors: bool, pub axes: ScrollbarAxes, } #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] pub struct Gutter { pub line_numbers: bool, pub code_actions: bool, pub runnables: bool, pub folds: bool, } /// When to show the scrollbar in the editor. /// /// Default: auto #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum ShowScrollbar { /// Show the scrollbar if there's important information or /// follow the system's configured behavior. Auto, /// Match the system's configured behavior. System, /// Always show the scrollbar. Always, /// Never show the scrollbar. Never, } /// Forcefully enable or disable the scrollbar for each axis #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub struct ScrollbarAxes { /// When false, forcefully disables the horizontal scrollbar. Otherwise, obey other settings. /// /// Default: true pub horizontal: bool, /// When false, forcefully disables the vertical scrollbar. Otherwise, obey other settings. /// /// Default: true pub vertical: bool, } /// Which diagnostic indicators to show in the scrollbar. /// /// Default: all #[derive(Copy, Clone, Debug, Serialize, JsonSchema, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum ScrollbarDiagnostics { /// Show all diagnostic levels: hint, information, warnings, error. All, /// Show only the following diagnostic levels: information, warning, error. Information, /// Show only the following diagnostic levels: warning, error. Warning, /// Show only the following diagnostic level: error. Error, /// Do not show diagnostics. None, } impl<'de> Deserialize<'de> for ScrollbarDiagnostics { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct Visitor; impl<'de> serde::de::Visitor<'de> for Visitor { type Value = ScrollbarDiagnostics; fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, r#"a boolean or one of "all", "information", "warning", "error", "none""# ) } fn visit_bool(self, b: bool) -> Result where E: serde::de::Error, { match b { false => Ok(ScrollbarDiagnostics::None), true => Ok(ScrollbarDiagnostics::All), } } fn visit_str(self, s: &str) -> Result where E: serde::de::Error, { match s { "all" => Ok(ScrollbarDiagnostics::All), "information" => Ok(ScrollbarDiagnostics::Information), "warning" => Ok(ScrollbarDiagnostics::Warning), "error" => Ok(ScrollbarDiagnostics::Error), "none" => Ok(ScrollbarDiagnostics::None), _ => Err(E::unknown_variant( s, &["all", "information", "warning", "error", "none"], )), } } } deserializer.deserialize_any(Visitor) } } /// The key to use for adding multiple cursors /// /// Default: alt #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum MultiCursorModifier { Alt, #[serde(alias = "cmd", alias = "ctrl")] CmdOrCtrl, } /// Whether the editor will scroll beyond the last line. /// /// Default: one_page #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum ScrollBeyondLastLine { /// The editor will not scroll beyond the last line. Off, /// The editor will scroll beyond the last line by one page. OnePage, /// The editor will scroll beyond the last line by the same number of lines as vertical_scroll_margin. VerticalScrollMargin, } /// Default options for buffer and project search items. #[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] pub struct SearchSettings { #[serde(default)] pub whole_word: bool, #[serde(default)] pub case_sensitive: bool, #[serde(default)] pub include_ignored: bool, #[serde(default)] pub regex: bool, } #[derive(Clone, Default, Serialize, Deserialize, JsonSchema)] pub struct EditorSettingsContent { /// Whether the cursor blinks in the editor. /// /// Default: true pub cursor_blink: Option, /// Cursor shape for the default editor. /// Can be "bar", "block", "underline", or "hollow". /// /// Default: None pub cursor_shape: Option, /// Determines whether the mouse cursor should be hidden while typing in an editor or input box. /// /// Default: true pub hide_mouse_while_typing: Option, /// How to highlight the current line in the editor. /// /// Default: all pub current_line_highlight: Option, /// Whether to highlight all occurrences of the selected text in an editor. /// /// Default: true pub selection_highlight: Option, /// The debounce delay before querying highlights based on the selected text. /// /// Default: 75 pub selection_highlight_debounce: Option, /// The debounce delay before querying highlights from the language /// server based on the current cursor location. /// /// Default: 75 pub lsp_highlight_debounce: Option, /// Whether to show the informational hover box when moving the mouse /// over symbols in the editor. /// /// Default: true pub hover_popover_enabled: Option, /// Time to wait before showing the informational hover box /// /// Default: 350 pub hover_popover_delay: Option, /// Toolbar related settings pub toolbar: Option, /// Scrollbar related settings pub scrollbar: Option, /// Gutter related settings pub gutter: Option, /// Whether the editor will scroll beyond the last line. /// /// Default: one_page pub scroll_beyond_last_line: Option, /// The number of lines to keep above/below the cursor when auto-scrolling. /// /// Default: 3. pub vertical_scroll_margin: Option, /// Whether to scroll when clicking near the edge of the visible text area. /// /// Default: false pub autoscroll_on_clicks: Option, /// The number of characters to keep on either side when scrolling with the mouse. /// /// Default: 5. pub horizontal_scroll_margin: Option, /// Scroll sensitivity multiplier. This multiplier is applied /// to both the horizontal and vertical delta values while scrolling. /// /// Default: 1.0 pub scroll_sensitivity: Option, /// Whether the line numbers on editors gutter are relative or not. /// /// Default: false pub relative_line_numbers: Option, /// When to populate a new search's query based on the text under the cursor. /// /// Default: always pub seed_search_query_from_cursor: Option, pub use_smartcase_search: Option, /// The key to use for adding multiple cursors /// /// Default: alt pub multi_cursor_modifier: Option, /// Hide the values of variables in `private` files, as defined by the /// private_files setting. This only changes the visual representation, /// the values are still present in the file and can be selected / copied / pasted /// /// Default: false pub redact_private_values: Option, /// How many lines to expand the multibuffer excerpts by default /// /// Default: 3 pub expand_excerpt_lines: Option, /// Whether to enable middle-click paste on Linux /// /// Default: true pub middle_click_paste: Option, /// What to do when multibuffer is double clicked in some of its excerpts /// (parts of singleton buffers). /// /// Default: select pub double_click_in_multibuffer: Option, /// Whether the editor search results will loop /// /// Default: true pub search_wrap: Option, /// Defaults to use when opening a new buffer and project search items. /// /// Default: nothing is enabled pub search: Option, /// Whether to automatically show a signature help pop-up or not. /// /// Default: false pub auto_signature_help: Option, /// Whether to show the signature help pop-up after completions or bracket pairs inserted. /// /// Default: false pub show_signature_help_after_edits: Option, /// Jupyter REPL settings. pub jupyter: Option, } // Toolbar related settings #[derive(Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] pub struct ToolbarContent { /// Whether to display breadcrumbs in the editor toolbar. /// /// Default: true pub breadcrumbs: Option, /// Whether to display quick action buttons in the editor toolbar. /// /// Default: true pub quick_actions: Option, /// Whether to show the selections menu in the editor toolbar /// /// Default: true pub selections_menu: Option, } /// Scrollbar related settings #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)] pub struct ScrollbarContent { /// When to show the scrollbar in the editor. /// /// Default: auto pub show: Option, /// Whether to show git diff indicators in the scrollbar. /// /// Default: true pub git_diff: Option, /// Whether to show buffer search result indicators in the scrollbar. /// /// Default: true pub search_results: Option, /// Whether to show selected text occurrences in the scrollbar. /// /// Default: true pub selected_text: Option, /// Whether to show selected symbol occurrences in the scrollbar. /// /// Default: true pub selected_symbol: Option, /// Which diagnostic indicators to show in the scrollbar: /// /// Default: all pub diagnostics: Option, /// Whether to show cursor positions in the scrollbar. /// /// Default: true pub cursors: Option, /// Forcefully enable or disable the scrollbar for each axis pub axes: Option, } /// Forcefully enable or disable the scrollbar for each axis #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)] pub struct ScrollbarAxesContent { /// When false, forcefully disables the horizontal scrollbar. Otherwise, obey other settings. /// /// Default: true horizontal: Option, /// When false, forcefully disables the vertical scrollbar. Otherwise, obey other settings. /// /// Default: true vertical: Option, } /// Gutter related settings #[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] pub struct GutterContent { /// Whether to show line numbers in the gutter. /// /// Default: true pub line_numbers: Option, /// Whether to show code action buttons in the gutter. /// /// Default: true pub code_actions: Option, /// Whether to show runnable buttons in the gutter. /// /// Default: true pub runnables: Option, /// Whether to show fold buttons in the gutter. /// /// Default: true pub folds: Option, } impl EditorSettings { pub fn jupyter_enabled(cx: &App) -> bool { EditorSettings::get_global(cx).jupyter.enabled } } impl Settings for EditorSettings { const KEY: Option<&'static str> = None; type FileContent = EditorSettingsContent; fn load(sources: SettingsSources, _: &mut App) -> anyhow::Result { sources.json_merge() } }