diff --git a/assets/settings/default.json b/assets/settings/default.json index 19c73ca0212016bf61b7fcf519d62fee33a4417b..9a6c7587d6266a9a80f0ef36b46e678d878f4bd6 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -102,6 +102,16 @@ "selections": true }, "relative_line_numbers": false, + // When to populate a new search's query based on the text under the cursor. + // This setting can take the following three values: + // + // 1. Always populate the search query with the word under the cursor (default). + // "always" + // 2. Only populate the search query when there is text selected + // "selection" + // 3. Never populate the search query + // "never" + "seed_search_query_from_cursor": "always", // Inlay hint related settings "inlay_hints": { // Global switch to toggle hints on and off, switched off by default. diff --git a/crates/editor/src/editor_settings.rs b/crates/editor/src/editor_settings.rs index 75f8b800f93757bec3bcbbf01b68226880267d57..b885e065a1a722564314d157a097a97a990ac971 100644 --- a/crates/editor/src/editor_settings.rs +++ b/crates/editor/src/editor_settings.rs @@ -2,7 +2,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use settings::Setting; -#[derive(Deserialize)] +#[derive(Clone, Deserialize)] pub struct EditorSettings { pub cursor_blink: bool, pub hover_popover_enabled: bool, @@ -11,6 +11,15 @@ pub struct EditorSettings { pub use_on_type_format: bool, pub scrollbar: Scrollbar, pub relative_line_numbers: bool, + pub seed_search_query_from_cursor: SeedQuerySetting, +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum SeedQuerySetting { + Always, + Selection, + Never, } #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] @@ -38,6 +47,7 @@ pub struct EditorSettingsContent { pub use_on_type_format: Option, pub scrollbar: Option, pub relative_line_numbers: Option, + pub seed_search_query_from_cursor: Option, } #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 1b922848e061b8b162fc5c1f25babf5c3ce96c0e..4c45904c502285cb217b7e61193ef8fdc95dc99b 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -1,7 +1,7 @@ use crate::{ - display_map::ToDisplayPoint, link_go_to_definition::hide_link_definition, - movement::surrounding_word, persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll, Editor, - Event, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, NavigationData, ToPoint as _, + editor_settings::SeedQuerySetting, link_go_to_definition::hide_link_definition, + persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll, Editor, EditorSettings, Event, + ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, NavigationData, ToPoint as _, }; use anyhow::{Context, Result}; use collections::HashSet; @@ -13,8 +13,8 @@ use gpui::{ ViewHandle, WeakViewHandle, }; use language::{ - proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, OffsetRangeExt, Point, - SelectionGoal, + proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, CharKind, OffsetRangeExt, + Point, SelectionGoal, }; use project::{search::SearchQuery, FormatTrigger, Item as _, Project, ProjectPath}; use rpc::proto::{self, update_view, PeerId}; @@ -937,24 +937,28 @@ impl SearchableItem for Editor { } fn query_suggestion(&mut self, cx: &mut ViewContext) -> String { - let display_map = self.snapshot(cx).display_snapshot; + let setting = settings::get::(cx).seed_search_query_from_cursor; + let snapshot = &self.snapshot(cx).buffer_snapshot; let selection = self.selections.newest::(cx); - if selection.start == selection.end { - let point = selection.start.to_display_point(&display_map); - let range = surrounding_word(&display_map, point); - let range = range.start.to_offset(&display_map, Bias::Left) - ..range.end.to_offset(&display_map, Bias::Right); - let text: String = display_map.buffer_snapshot.text_for_range(range).collect(); - if text.trim().is_empty() { + + match setting { + SeedQuerySetting::Never => String::new(), + SeedQuerySetting::Selection | SeedQuerySetting::Always if !selection.is_empty() => { + snapshot + .text_for_range(selection.start..selection.end) + .collect() + } + SeedQuerySetting::Selection => String::new(), + SeedQuerySetting::Always => { + let (range, kind) = snapshot.surrounding_word(selection.start); + if kind == Some(CharKind::Word) { + let text: String = snapshot.text_for_range(range).collect(); + if !text.trim().is_empty() { + return text; + } + } String::new() - } else { - text } - } else { - display_map - .buffer_snapshot - .text_for_range(selection.start..selection.end) - .collect() } } diff --git a/crates/editor2/src/editor_settings.rs b/crates/editor2/src/editor_settings.rs index 45c797598f51c4bde2f0008d02ac62d55accb3c7..c23bf76aea8a442e343925b06bfdcf1457236f76 100644 --- a/crates/editor2/src/editor_settings.rs +++ b/crates/editor2/src/editor_settings.rs @@ -11,6 +11,15 @@ pub struct EditorSettings { pub use_on_type_format: bool, pub scrollbar: Scrollbar, pub relative_line_numbers: bool, + pub seed_search_query_from_cursor: SeedQuerySetting, +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum SeedQuerySetting { + Always, + Selection, + Never, } #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] @@ -38,6 +47,7 @@ pub struct EditorSettingsContent { pub use_on_type_format: Option, pub scrollbar: Option, pub relative_line_numbers: Option, + pub seed_search_query_from_selection: Option, } #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] diff --git a/crates/editor2/src/items.rs b/crates/editor2/src/items.rs index 9c49e5f14317579eb1ca6e103c5058de97e76d40..b7e14244c30218cedf4c5c8ede9fe06151d3b9db 100644 --- a/crates/editor2/src/items.rs +++ b/crates/editor2/src/items.rs @@ -1,7 +1,8 @@ use crate::{ - display_map::ToDisplayPoint, link_go_to_definition::hide_link_definition, + editor_settings::SeedQuerySetting, link_go_to_definition::hide_link_definition, movement::surrounding_word, persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll, Editor, - Event, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, NavigationData, ToPoint as _, + EditorSettings, Event, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, + NavigationData, ToPoint as _, }; use anyhow::{anyhow, Context, Result}; use collections::HashSet; @@ -12,11 +13,12 @@ use gpui::{ VisualContext, WeakView, }; use language::{ - proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, OffsetRangeExt, Point, - SelectionGoal, + proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, CharKind, OffsetRangeExt, + Point, SelectionGoal, }; use project::{search::SearchQuery, FormatTrigger, Item as _, Project, ProjectPath}; use rpc::proto::{self, update_view, PeerId}; +use settings::Settings; use smallvec::SmallVec; use std::{ borrow::Cow, @@ -950,24 +952,28 @@ impl SearchableItem for Editor { } fn query_suggestion(&mut self, cx: &mut ViewContext) -> String { - let display_map = self.snapshot(cx).display_snapshot; + let setting = EditorSettings::get_global(cx).seed_search_query_from_cursor; + let snapshot = &self.snapshot(cx).buffer_snapshot; let selection = self.selections.newest::(cx); - if selection.start == selection.end { - let point = selection.start.to_display_point(&display_map); - let range = surrounding_word(&display_map, point); - let range = range.start.to_offset(&display_map, Bias::Left) - ..range.end.to_offset(&display_map, Bias::Right); - let text: String = display_map.buffer_snapshot.text_for_range(range).collect(); - if text.trim().is_empty() { + + match setting { + SeedQuerySetting::Never => String::new(), + SeedQuerySetting::Selection | SeedQuerySetting::Always if !selection.is_empty() => { + snapshot + .text_for_range(selection.start..selection.end) + .collect() + } + SeedQuerySetting::Selection => String::new(), + SeedQuerySetting::Always => { + let (range, kind) = snapshot.surrounding_word(selection.start); + if kind == Some(CharKind::Word) { + let text: String = snapshot.text_for_range(range).collect(); + if !text.trim().is_empty() { + return text; + } + } String::new() - } else { - text } - } else { - display_map - .buffer_snapshot - .text_for_range(selection.start..selection.end) - .collect() } } diff --git a/crates/gpui/src/geometry.rs b/crates/gpui/src/geometry.rs index 40b06827872edec469d82cfc1cc79c377a00633b..fe197af5d2670146de94198abbc0db3dccc02135 100644 --- a/crates/gpui/src/geometry.rs +++ b/crates/gpui/src/geometry.rs @@ -136,7 +136,7 @@ impl ToJson for RectF { } #[derive(Refineable, Debug)] -#[refineable(debug)] +#[refineable(Debug)] pub struct Point { pub x: T, pub y: T, @@ -161,7 +161,7 @@ impl Into> for Point { } #[derive(Refineable, Clone, Debug)] -#[refineable(debug)] +#[refineable(Debug)] pub struct Size { pub width: T, pub height: T, @@ -227,7 +227,7 @@ impl Size { } #[derive(Clone, Default, Refineable, Debug)] -#[refineable(debug)] +#[refineable(Debug)] pub struct Edges { pub top: T, pub right: T, diff --git a/crates/gpui2/src/geometry.rs b/crates/gpui2/src/geometry.rs index e16635be362f6bc59370805a6c93413da50a7c64..f36432dff54e65badefc63e9187f09be67426d69 100644 --- a/crates/gpui2/src/geometry.rs +++ b/crates/gpui2/src/geometry.rs @@ -9,7 +9,7 @@ use std::{ }; #[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash)] -#[refineable(debug)] +#[refineable(Debug)] #[repr(C)] pub struct Point { pub x: T, @@ -140,7 +140,7 @@ impl Clone for Point { } #[derive(Refineable, Default, Clone, Copy, PartialEq, Div, Hash, Serialize, Deserialize)] -#[refineable(debug)] +#[refineable(Debug)] #[repr(C)] pub struct Size { pub width: T, @@ -295,7 +295,7 @@ impl Size { } #[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)] -#[refineable(debug)] +#[refineable(Debug)] #[repr(C)] pub struct Bounds { pub origin: Point, @@ -459,7 +459,7 @@ impl Bounds { impl Copy for Bounds {} #[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)] -#[refineable(debug)] +#[refineable(Debug)] #[repr(C)] pub struct Edges { pub top: T, @@ -592,7 +592,7 @@ impl Edges { } #[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)] -#[refineable(debug)] +#[refineable(Debug)] #[repr(C)] pub struct Corners { pub top_left: T, diff --git a/crates/gpui2/src/style.rs b/crates/gpui2/src/style.rs index 5de173c2d4f729e90f9ba691bccb02bab664214a..44bf1c1118b12872af03be032756cdfe12459b36 100644 --- a/crates/gpui2/src/style.rs +++ b/crates/gpui2/src/style.rs @@ -14,7 +14,7 @@ pub use taffy::style::{ pub type StyleCascade = Cascade