diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 513ff7decd..658a267373 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -3,6 +3,7 @@ use crate::{ ReplaceAll, ReplaceNext, SearchOptions, SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleIncludeIgnored, ToggleRegex, ToggleReplace, ToggleWholeWord, }; +use anyhow::Context as _; use collections::{HashMap, HashSet}; use editor::{ actions::SelectAll, items::active_match_index, scroll::Autoscroll, Anchor, Editor, @@ -15,7 +16,7 @@ use gpui::{ ParentElement, Point, Render, SharedString, Styled, Subscription, Task, TextStyle, UpdateGlobal, WeakEntity, Window, }; -use language::Buffer; +use language::{Buffer, Language}; use menu::Confirm; use project::{ search::{SearchInputKind, SearchQuery}, @@ -29,6 +30,7 @@ use std::{ ops::{Not, Range}, path::Path, pin::pin, + sync::Arc, }; use theme::ThemeSettings; use ui::{ @@ -167,6 +169,7 @@ pub struct ProjectSearchView { filters_enabled: bool, replace_enabled: bool, included_opened_only: bool, + regex_language: Option>, _subscriptions: Vec, } @@ -613,6 +616,7 @@ impl ProjectSearchView { self.current_settings(), ); }); + self.adjust_query_regex_language(cx); } fn toggle_opened_only(&mut self, _window: &mut Window, _cx: &mut Context) { @@ -791,6 +795,22 @@ impl ProjectSearchView { } })); + let languages = project.read(cx).languages().clone(); + cx.spawn(|project_search_view, mut cx| async move { + let regex_language = languages + .language_for_name("regex") + .await + .context("loading regex language")?; + project_search_view + .update(&mut cx, |project_search_view, cx| { + project_search_view.regex_language = Some(regex_language); + project_search_view.adjust_query_regex_language(cx); + }) + .ok(); + anyhow::Ok(()) + }) + .detach_and_log_err(cx); + // Check if Worktrees have all been previously indexed let mut this = ProjectSearchView { workspace, @@ -808,6 +828,7 @@ impl ProjectSearchView { filters_enabled, replace_enabled: false, included_opened_only: false, + regex_language: None, _subscriptions: subscriptions, }; this.entity_changed(window, cx); @@ -1338,6 +1359,28 @@ impl ProjectSearchView { pub fn results_editor(&self) -> &Entity { &self.results_editor } + + fn adjust_query_regex_language(&self, cx: &mut App) { + let enable = self.search_options.contains(SearchOptions::REGEX); + let query_buffer = self + .query_editor + .read(cx) + .buffer() + .read(cx) + .as_singleton() + .expect("query editor should be backed by a singleton buffer"); + if enable { + if let Some(regex_language) = self.regex_language.clone() { + query_buffer.update(cx, |query_buffer, cx| { + query_buffer.set_language(Some(regex_language), cx); + }) + } + } else { + query_buffer.update(cx, |query_buffer, cx| { + query_buffer.set_language(None, cx); + }) + } + } } fn buffer_search_query( @@ -1461,7 +1504,6 @@ impl ProjectSearchBar { search_view.search(cx); } }); - cx.notify(); true } else { @@ -1666,31 +1708,34 @@ impl ProjectSearchBar { } fn render_text_input(&self, editor: &Entity, cx: &Context) -> impl IntoElement { + let (color, use_syntax) = if editor.read(cx).read_only(cx) { + (cx.theme().colors().text_disabled, false) + } else { + (cx.theme().colors().text, true) + }; let settings = ThemeSettings::get_global(cx); let text_style = TextStyle { - color: if editor.read(cx).read_only(cx) { - cx.theme().colors().text_disabled - } else { - cx.theme().colors().text - }, + color, font_family: settings.buffer_font.family.clone(), font_features: settings.buffer_font.features.clone(), font_fallbacks: settings.buffer_font.fallbacks.clone(), font_size: rems(0.875).into(), font_weight: settings.buffer_font.weight, line_height: relative(1.3), - ..Default::default() + ..TextStyle::default() }; - EditorElement::new( - editor, - EditorStyle { - background: cx.theme().colors().editor_background, - local_player: cx.theme().players().local(), - text: text_style, - ..Default::default() - }, - ) + let mut editor_style = EditorStyle { + background: cx.theme().colors().editor_background, + local_player: cx.theme().players().local(), + text: text_style, + ..EditorStyle::default() + }; + if use_syntax { + editor_style.syntax = cx.theme().syntax().clone(); + } + + EditorElement::new(editor, editor_style) } }