diff --git a/assets/settings/default.json b/assets/settings/default.json index 700a7147d0..3ef2da17b2 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -140,6 +140,15 @@ // Whether to show diagnostic indicators in the scrollbar. "diagnostics": true }, + // What to do when multibuffer is double clicked in some of its excerpts + // (parts of singleton buffers). + // May take 2 values: + // 1. Behave as a regular buffer and select the whole word. + // "double_click_in_multibuffer": "select" + // 2. Open the excerpt clicked as a new buffer in the new tab (default). + // "double_click_in_multibuffer": "open", + // For the case of "open", regular selection behavior can be achieved by holding `alt` when double clicking. + "double_click_in_multibuffer": "open", "gutter": { // Whether to show line numbers in the gutter. "line_numbers": true, diff --git a/crates/editor/src/editor_settings.rs b/crates/editor/src/editor_settings.rs index ca12112d5f..6e7fc08ef3 100644 --- a/crates/editor/src/editor_settings.rs +++ b/crates/editor/src/editor_settings.rs @@ -17,6 +17,8 @@ pub struct EditorSettings { pub relative_line_numbers: bool, pub seed_search_query_from_cursor: SeedQuerySetting, pub redact_private_values: bool, + #[serde(default)] + pub double_click_in_multibuffer: DoubleClickInMultibuffer, } /// When to populate a new search's query based on the text under the cursor. @@ -31,6 +33,18 @@ pub enum SeedQuerySetting { 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. + Select, + #[default] + /// 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(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] pub struct Toolbar { pub breadcrumbs: bool, @@ -127,6 +141,12 @@ pub struct EditorSettingsContent { /// /// Default: false pub redact_private_values: Option, + + /// What to do when multibuffer is double clicked in some of its excerpts + /// (parts of singleton buffers). + /// + /// Default: open + pub double_click_in_multibuffer: Option, } // Toolbar related settings diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 7faa671627..4f7631c2e4 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -3,7 +3,7 @@ use crate::{ BlockContext, BlockStyle, DisplaySnapshot, FoldStatus, HighlightedChunk, ToDisplayPoint, TransformBlock, }, - editor_settings::ShowScrollbar, + editor_settings::{DoubleClickInMultibuffer, ShowScrollbar}, git::{diff_hunk_to_display, DisplayDiffHunk}, hover_popover::{ self, hover_at, HOVER_POPOVER_GAP, MIN_POPOVER_CHARACTER_WIDTH, MIN_POPOVER_LINE_HEIGHT, @@ -392,7 +392,7 @@ impl EditorElement { } let mut click_count = event.click_count; - let modifiers = event.modifiers; + let mut modifiers = event.modifiers; if gutter_hitbox.is_hovered(cx) { click_count = 3; // Simulate triple-click when clicking the gutter to select lines @@ -400,6 +400,25 @@ impl EditorElement { return; } + if click_count == 2 { + match EditorSettings::get_global(cx).double_click_in_multibuffer { + DoubleClickInMultibuffer::Select => { + // do nothing special on double click, all selection logic is below + } + DoubleClickInMultibuffer::Open => { + if modifiers.alt { + // if double click is made with alt, pretend it's a regular double click without opening and alt, + // and run the selection logic. + modifiers.alt = false; + } else { + // if double click is made without alt, open the corresponding excerp + editor.open_excerpts(&OpenExcerpts, cx); + return; + } + } + } + } + let point_for_position = position_map.point_for_position(text_hitbox.bounds, event.position); let position = point_for_position.previous_valid;