Add a setting for when to seed the search query from the text under the cursor

This commit is contained in:
Max Brunsfeld 2023-11-09 14:03:14 -08:00
parent 28d3d21108
commit 6b8ce3cc85
5 changed files with 75 additions and 39 deletions

View file

@ -102,6 +102,16 @@
"selections": true "selections": true
}, },
"relative_line_numbers": false, "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 hint related settings
"inlay_hints": { "inlay_hints": {
// Global switch to toggle hints on and off, switched off by default. // Global switch to toggle hints on and off, switched off by default.

View file

@ -2,7 +2,7 @@ use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::Setting; use settings::Setting;
#[derive(Deserialize)] #[derive(Clone, Deserialize)]
pub struct EditorSettings { pub struct EditorSettings {
pub cursor_blink: bool, pub cursor_blink: bool,
pub hover_popover_enabled: bool, pub hover_popover_enabled: bool,
@ -11,6 +11,15 @@ pub struct EditorSettings {
pub use_on_type_format: bool, pub use_on_type_format: bool,
pub scrollbar: Scrollbar, pub scrollbar: Scrollbar,
pub relative_line_numbers: bool, 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)] #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
@ -38,6 +47,7 @@ pub struct EditorSettingsContent {
pub use_on_type_format: Option<bool>, pub use_on_type_format: Option<bool>,
pub scrollbar: Option<ScrollbarContent>, pub scrollbar: Option<ScrollbarContent>,
pub relative_line_numbers: Option<bool>, pub relative_line_numbers: Option<bool>,
pub seed_search_query_from_selection: Option<SeedQuerySetting>,
} }
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]

View file

@ -1,7 +1,7 @@
use crate::{ use crate::{
link_go_to_definition::hide_link_definition, persistence::DB, scroll::ScrollAnchor, Anchor, editor_settings::SeedQuerySetting, link_go_to_definition::hide_link_definition,
Autoscroll, Editor, Event, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll, Editor, EditorSettings, Event,
NavigationData, ToPoint as _, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, NavigationData, ToPoint as _,
}; };
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use collections::HashSet; use collections::HashSet;
@ -937,26 +937,28 @@ impl SearchableItem for Editor {
} }
fn query_suggestion(&mut self, cx: &mut ViewContext<Self>) -> String { 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); let selection = self.selections.newest::<usize>(cx);
if selection.start == selection.end {
let (range, kind) = display_map match setting {
.buffer_snapshot SeedQuerySetting::Never => String::new(),
.surrounding_word(selection.start); SeedQuerySetting::Selection | SeedQuerySetting::Always if !selection.is_empty() => {
if kind != Some(CharKind::Word) { snapshot
return String::new(); .text_for_range(selection.start..selection.end)
.collect()
} }
let text: String = display_map.buffer_snapshot.text_for_range(range).collect(); SeedQuerySetting::Selection => String::new(),
if text.trim().is_empty() { 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() String::new()
} else {
text
} }
} else {
display_map
.buffer_snapshot
.text_for_range(selection.start..selection.end)
.collect()
} }
} }

View file

@ -11,6 +11,15 @@ pub struct EditorSettings {
pub use_on_type_format: bool, pub use_on_type_format: bool,
pub scrollbar: Scrollbar, pub scrollbar: Scrollbar,
pub relative_line_numbers: bool, 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)] #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
@ -38,6 +47,7 @@ pub struct EditorSettingsContent {
pub use_on_type_format: Option<bool>, pub use_on_type_format: Option<bool>,
pub scrollbar: Option<ScrollbarContent>, pub scrollbar: Option<ScrollbarContent>,
pub relative_line_numbers: Option<bool>, pub relative_line_numbers: Option<bool>,
pub seed_search_query_from_selection: Option<SeedQuerySetting>,
} }
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]

View file

@ -1,7 +1,8 @@
use crate::{ use crate::{
link_go_to_definition::hide_link_definition, movement::surrounding_word, persistence::DB, editor_settings::SeedQuerySetting, link_go_to_definition::hide_link_definition,
scroll::ScrollAnchor, Anchor, Autoscroll, Editor, Event, ExcerptId, ExcerptRange, MultiBuffer, movement::surrounding_word, persistence::DB, scroll::ScrollAnchor, Anchor, Autoscroll, Editor,
MultiBufferSnapshot, NavigationData, ToPoint as _, EditorSettings, Event, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot,
NavigationData, ToPoint as _,
}; };
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use collections::HashSet; use collections::HashSet;
@ -17,6 +18,7 @@ use language::{
}; };
use project::{search::SearchQuery, FormatTrigger, Item as _, Project, ProjectPath}; use project::{search::SearchQuery, FormatTrigger, Item as _, Project, ProjectPath};
use rpc::proto::{self, update_view, PeerId}; use rpc::proto::{self, update_view, PeerId};
use settings::Settings;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{ use std::{
borrow::Cow, borrow::Cow,
@ -918,26 +920,28 @@ impl SearchableItem for Editor {
} }
fn query_suggestion(&mut self, cx: &mut ViewContext<Self>) -> String { 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); let selection = self.selections.newest::<usize>(cx);
if selection.start == selection.end {
let (range, kind) = display_map match setting {
.buffer_snapshot SeedQuerySetting::Never => String::new(),
.surrounding_word(selection.start); SeedQuerySetting::Selection | SeedQuerySetting::Always if !selection.is_empty() => {
if kind != Some(CharKind::Word) { snapshot
return String::new(); .text_for_range(selection.start..selection.end)
.collect()
} }
let text: String = display_map.buffer_snapshot.text_for_range(range).collect(); SeedQuerySetting::Selection => String::new(),
if text.trim().is_empty() { 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() String::new()
} else {
text
} }
} else {
display_map
.buffer_snapshot
.text_for_range(selection.start..selection.end)
.collect()
} }
} }