Detailed changes
@@ -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.
@@ -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<bool>,
pub scrollbar: Option<ScrollbarContent>,
pub relative_line_numbers: Option<bool>,
+ pub seed_search_query_from_cursor: Option<SeedQuerySetting>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
@@ -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<Self>) -> String {
- let display_map = self.snapshot(cx).display_snapshot;
+ let setting = settings::get::<EditorSettings>(cx).seed_search_query_from_cursor;
+ let snapshot = &self.snapshot(cx).buffer_snapshot;
let selection = self.selections.newest::<usize>(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()
}
}
@@ -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<bool>,
pub scrollbar: Option<ScrollbarContent>,
pub relative_line_numbers: Option<bool>,
+ pub seed_search_query_from_selection: Option<SeedQuerySetting>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
@@ -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<Self>) -> 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::<usize>(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()
}
}
@@ -136,7 +136,7 @@ impl ToJson for RectF {
}
#[derive(Refineable, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
pub struct Point<T: Clone + Default + Debug> {
pub x: T,
pub y: T,
@@ -161,7 +161,7 @@ impl<T: Clone + Default + Debug> Into<taffy::geometry::Point<T>> for Point<T> {
}
#[derive(Refineable, Clone, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
pub struct Size<T: Clone + Default + Debug> {
pub width: T,
pub height: T,
@@ -227,7 +227,7 @@ impl Size<Length> {
}
#[derive(Clone, Default, Refineable, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
pub struct Edges<T: Clone + Default + Debug> {
pub top: T,
pub right: T,
@@ -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<T: Default + Clone + Debug> {
pub x: T,
@@ -140,7 +140,7 @@ impl<T: Clone + Default + Debug> Clone for Point<T> {
}
#[derive(Refineable, Default, Clone, Copy, PartialEq, Div, Hash, Serialize, Deserialize)]
-#[refineable(debug)]
+#[refineable(Debug)]
#[repr(C)]
pub struct Size<T: Clone + Default + Debug> {
pub width: T,
@@ -295,7 +295,7 @@ impl Size<Length> {
}
#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
-#[refineable(debug)]
+#[refineable(Debug)]
#[repr(C)]
pub struct Bounds<T: Clone + Default + Debug> {
pub origin: Point<T>,
@@ -459,7 +459,7 @@ impl Bounds<Pixels> {
impl<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
-#[refineable(debug)]
+#[refineable(Debug)]
#[repr(C)]
pub struct Edges<T: Clone + Default + Debug> {
pub top: T,
@@ -592,7 +592,7 @@ impl Edges<Pixels> {
}
#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
-#[refineable(debug)]
+#[refineable(Debug)]
#[repr(C)]
pub struct Corners<T: Clone + Default + Debug> {
pub top_left: T,
@@ -14,7 +14,7 @@ pub use taffy::style::{
pub type StyleCascade = Cascade<Style>;
#[derive(Clone, Refineable, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
pub struct Style {
/// What layout strategy should be used?
pub display: Display,
@@ -129,7 +129,7 @@ pub struct BoxShadow {
}
#[derive(Refineable, Clone, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
pub struct TextStyle {
pub color: Hsla,
pub font_family: SharedString,
@@ -353,7 +353,7 @@ impl Default for Style {
}
#[derive(Refineable, Copy, Clone, Default, Debug, PartialEq, Eq)]
-#[refineable(debug)]
+#[refineable(Debug)]
pub struct UnderlineStyle {
pub thickness: Pixels,
pub color: Option<Hsla>,
@@ -19,8 +19,7 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
let refineable_attr = attrs.iter().find(|attr| attr.path.is_ident("refineable"));
let mut impl_debug_on_refinement = false;
- let mut derive_serialize_on_refinement = false;
- let mut derive_deserialize_on_refinement = false;
+ let mut refinement_traits_to_derive = vec![];
if let Some(refineable_attr) = refineable_attr {
if let Ok(syn::Meta::List(meta_list)) = refineable_attr.parse_meta() {
@@ -29,16 +28,10 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
continue;
};
- if path.is_ident("debug") {
+ if path.is_ident("Debug") {
impl_debug_on_refinement = true;
- }
-
- if path.is_ident("serialize") {
- derive_serialize_on_refinement = true;
- }
-
- if path.is_ident("deserialize") {
- derive_deserialize_on_refinement = true;
+ } else {
+ refinement_traits_to_derive.push(path);
}
}
}
@@ -259,22 +252,14 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
quote! {}
};
- let derive_serialize = if derive_serialize_on_refinement {
- quote! { #[derive(serde::Serialize)]}
- } else {
- quote! {}
- };
-
- let derive_deserialize = if derive_deserialize_on_refinement {
- quote! { #[derive(serde::Deserialize)]}
- } else {
- quote! {}
- };
+ let mut derive_stream = quote! {};
+ for trait_to_derive in refinement_traits_to_derive {
+ derive_stream.extend(quote! { #[derive(#trait_to_derive)] })
+ }
let gen = quote! {
#[derive(Clone)]
- #derive_serialize
- #derive_deserialize
+ #derive_stream
pub struct #refinement_ident #impl_generics {
#( #field_visibilities #field_names: #wrapped_types ),*
}
@@ -1,9 +1,7 @@
-use std::sync::Arc;
-
+use crate::{PlayerColors, SyntaxTheme};
use gpui::Hsla;
use refineable::Refineable;
-
-use crate::{PlayerColors, SyntaxTheme};
+use std::sync::Arc;
#[derive(Clone)]
pub struct SystemColors {
@@ -14,7 +12,7 @@ pub struct SystemColors {
}
#[derive(Refineable, Clone, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
pub struct StatusColors {
pub conflict: Hsla,
pub created: Hsla,
@@ -30,7 +28,7 @@ pub struct StatusColors {
}
#[derive(Refineable, Clone, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
pub struct GitStatusColors {
pub conflict: Hsla,
pub created: Hsla,
@@ -41,7 +39,7 @@ pub struct GitStatusColors {
}
#[derive(Refineable, Clone, Debug)]
-#[refineable(debug, deserialize)]
+#[refineable(Debug, serde::Deserialize)]
pub struct ThemeColors {
pub border: Hsla,
/// Border color. Used for deemphasized borders, like a visual divider between two sections
@@ -1,8 +1,7 @@
+use crate::{Appearance, ThemeColors, ThemeColorsRefinement};
use refineable::Refineable;
use serde::Deserialize;
-use crate::{Appearance, ThemeColors, ThemeColorsRefinement};
-
#[derive(Deserialize)]
pub struct UserThemeFamily {
pub name: String,
@@ -18,7 +17,7 @@ pub struct UserTheme {
}
#[derive(Refineable, Clone)]
-#[refineable(deserialize)]
+#[refineable(Deserialize)]
pub struct UserThemeStyles {
#[refineable]
pub colors: ThemeColors,