mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-07 20:39:04 +03:00
Highlight include/exclude inputs when errors happen there
This commit is contained in:
parent
dfdf7e4866
commit
eec60556ab
@ -22,6 +22,7 @@ use smallvec::SmallVec;
|
|||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
collections::HashSet,
|
||||||
mem,
|
mem,
|
||||||
ops::Range,
|
ops::Range,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
@ -76,6 +77,13 @@ struct ProjectSearch {
|
|||||||
search_id: usize,
|
search_id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
enum InputPanel {
|
||||||
|
Query,
|
||||||
|
Exclude,
|
||||||
|
Include,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ProjectSearchView {
|
pub struct ProjectSearchView {
|
||||||
model: ModelHandle<ProjectSearch>,
|
model: ModelHandle<ProjectSearch>,
|
||||||
query_editor: ViewHandle<Editor>,
|
query_editor: ViewHandle<Editor>,
|
||||||
@ -83,7 +91,7 @@ pub struct ProjectSearchView {
|
|||||||
case_sensitive: bool,
|
case_sensitive: bool,
|
||||||
whole_word: bool,
|
whole_word: bool,
|
||||||
regex: bool,
|
regex: bool,
|
||||||
query_contains_error: bool,
|
panels_with_errors: HashSet<InputPanel>,
|
||||||
active_match_index: Option<usize>,
|
active_match_index: Option<usize>,
|
||||||
search_id: usize,
|
search_id: usize,
|
||||||
query_editor_was_focused: bool,
|
query_editor_was_focused: bool,
|
||||||
@ -493,7 +501,7 @@ impl ProjectSearchView {
|
|||||||
case_sensitive,
|
case_sensitive,
|
||||||
whole_word,
|
whole_word,
|
||||||
regex,
|
regex,
|
||||||
query_contains_error: false,
|
panels_with_errors: HashSet::new(),
|
||||||
active_match_index: None,
|
active_match_index: None,
|
||||||
query_editor_was_focused: false,
|
query_editor_was_focused: false,
|
||||||
included_files_editor,
|
included_files_editor,
|
||||||
@ -564,7 +572,7 @@ impl ProjectSearchView {
|
|||||||
|
|
||||||
fn build_search_query(&mut self, cx: &mut ViewContext<Self>) -> Option<SearchQuery> {
|
fn build_search_query(&mut self, cx: &mut ViewContext<Self>) -> Option<SearchQuery> {
|
||||||
let text = self.query_editor.read(cx).text(cx);
|
let text = self.query_editor.read(cx).text(cx);
|
||||||
let Ok(included_files) = self
|
let included_files = match self
|
||||||
.included_files_editor
|
.included_files_editor
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.text(cx)
|
.text(cx)
|
||||||
@ -572,12 +580,19 @@ impl ProjectSearchView {
|
|||||||
.map(str::trim)
|
.map(str::trim)
|
||||||
.filter(|glob_str| !glob_str.is_empty())
|
.filter(|glob_str| !glob_str.is_empty())
|
||||||
.map(|glob_str| glob::Pattern::new(glob_str))
|
.map(|glob_str| glob::Pattern::new(glob_str))
|
||||||
.collect::<Result<_, _>>() else {
|
.collect::<Result<_, _>>()
|
||||||
self.query_contains_error = true;
|
{
|
||||||
|
Ok(included_files) => {
|
||||||
|
self.panels_with_errors.remove(&InputPanel::Include);
|
||||||
|
included_files
|
||||||
|
}
|
||||||
|
Err(_e) => {
|
||||||
|
self.panels_with_errors.insert(InputPanel::Include);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
return None
|
return None;
|
||||||
};
|
}
|
||||||
let Ok(excluded_files) = self
|
};
|
||||||
|
let excluded_files = match self
|
||||||
.excluded_files_editor
|
.excluded_files_editor
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.text(cx)
|
.text(cx)
|
||||||
@ -585,11 +600,18 @@ impl ProjectSearchView {
|
|||||||
.map(str::trim)
|
.map(str::trim)
|
||||||
.filter(|glob_str| !glob_str.is_empty())
|
.filter(|glob_str| !glob_str.is_empty())
|
||||||
.map(|glob_str| glob::Pattern::new(glob_str))
|
.map(|glob_str| glob::Pattern::new(glob_str))
|
||||||
.collect::<Result<_, _>>() else {
|
.collect::<Result<_, _>>()
|
||||||
self.query_contains_error = true;
|
{
|
||||||
|
Ok(excluded_files) => {
|
||||||
|
self.panels_with_errors.remove(&InputPanel::Exclude);
|
||||||
|
excluded_files
|
||||||
|
}
|
||||||
|
Err(_e) => {
|
||||||
|
self.panels_with_errors.insert(InputPanel::Exclude);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
return None
|
return None;
|
||||||
};
|
}
|
||||||
|
};
|
||||||
if self.regex {
|
if self.regex {
|
||||||
match SearchQuery::regex(
|
match SearchQuery::regex(
|
||||||
text,
|
text,
|
||||||
@ -598,9 +620,12 @@ impl ProjectSearchView {
|
|||||||
included_files,
|
included_files,
|
||||||
excluded_files,
|
excluded_files,
|
||||||
) {
|
) {
|
||||||
Ok(query) => Some(query),
|
Ok(query) => {
|
||||||
Err(_) => {
|
self.panels_with_errors.remove(&InputPanel::Query);
|
||||||
self.query_contains_error = true;
|
Some(query)
|
||||||
|
}
|
||||||
|
Err(_e) => {
|
||||||
|
self.panels_with_errors.insert(InputPanel::Query);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -968,11 +993,23 @@ impl View for ProjectSearchBar {
|
|||||||
if let Some(search) = self.active_project_search.as_ref() {
|
if let Some(search) = self.active_project_search.as_ref() {
|
||||||
let search = search.read(cx);
|
let search = search.read(cx);
|
||||||
let theme = cx.global::<Settings>().theme.clone();
|
let theme = cx.global::<Settings>().theme.clone();
|
||||||
let editor_container = if search.query_contains_error {
|
let query_container_style = if search.panels_with_errors.contains(&InputPanel::Query) {
|
||||||
theme.search.invalid_editor
|
theme.search.invalid_editor
|
||||||
} else {
|
} else {
|
||||||
theme.search.editor.input.container
|
theme.search.editor.input.container
|
||||||
};
|
};
|
||||||
|
let include_container_style =
|
||||||
|
if search.panels_with_errors.contains(&InputPanel::Include) {
|
||||||
|
theme.search.invalid_include_exclude_editor
|
||||||
|
} else {
|
||||||
|
theme.search.include_exclude_editor.input.container
|
||||||
|
};
|
||||||
|
let exclude_container_style =
|
||||||
|
if search.panels_with_errors.contains(&InputPanel::Exclude) {
|
||||||
|
theme.search.invalid_include_exclude_editor
|
||||||
|
} else {
|
||||||
|
theme.search.include_exclude_editor.input.container
|
||||||
|
};
|
||||||
|
|
||||||
let included_files_view = ChildView::new(&search.included_files_editor, cx)
|
let included_files_view = ChildView::new(&search.included_files_editor, cx)
|
||||||
.aligned()
|
.aligned()
|
||||||
@ -1010,7 +1047,7 @@ impl View for ProjectSearchBar {
|
|||||||
.aligned()
|
.aligned()
|
||||||
}))
|
}))
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(editor_container)
|
.with_style(query_container_style)
|
||||||
.aligned()
|
.aligned()
|
||||||
.constrained()
|
.constrained()
|
||||||
.with_min_width(theme.search.editor.min_width)
|
.with_min_width(theme.search.editor.min_width)
|
||||||
@ -1053,7 +1090,7 @@ impl View for ProjectSearchBar {
|
|||||||
Flex::row()
|
Flex::row()
|
||||||
.with_child(included_files_view)
|
.with_child(included_files_view)
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(theme.search.include_exclude_editor.input.container)
|
.with_style(include_container_style)
|
||||||
.aligned()
|
.aligned()
|
||||||
.constrained()
|
.constrained()
|
||||||
.with_min_width(theme.search.include_exclude_editor.min_width)
|
.with_min_width(theme.search.include_exclude_editor.min_width)
|
||||||
@ -1064,7 +1101,7 @@ impl View for ProjectSearchBar {
|
|||||||
Flex::row()
|
Flex::row()
|
||||||
.with_child(excluded_files_view)
|
.with_child(excluded_files_view)
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(theme.search.include_exclude_editor.input.container)
|
.with_style(exclude_container_style)
|
||||||
.aligned()
|
.aligned()
|
||||||
.constrained()
|
.constrained()
|
||||||
.with_min_width(theme.search.include_exclude_editor.min_width)
|
.with_min_width(theme.search.include_exclude_editor.min_width)
|
||||||
|
@ -320,6 +320,7 @@ pub struct Search {
|
|||||||
pub invalid_editor: ContainerStyle,
|
pub invalid_editor: ContainerStyle,
|
||||||
pub option_button_group: ContainerStyle,
|
pub option_button_group: ContainerStyle,
|
||||||
pub include_exclude_editor: FindEditor,
|
pub include_exclude_editor: FindEditor,
|
||||||
|
pub invalid_include_exclude_editor: ContainerStyle,
|
||||||
pub include_exclude_inputs: ContainedText,
|
pub include_exclude_inputs: ContainedText,
|
||||||
pub option_button: Interactive<ContainedText>,
|
pub option_button: Interactive<ContainedText>,
|
||||||
pub match_background: Color,
|
pub match_background: Color,
|
||||||
|
@ -26,6 +26,12 @@ export default function search(colorScheme: ColorScheme) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const includeExcludeEditor = {
|
||||||
|
...editor,
|
||||||
|
minWidth: 100,
|
||||||
|
maxWidth: 250,
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// TODO: Add an activeMatchBackground on the rust side to differenciate between active and inactive
|
// TODO: Add an activeMatchBackground on the rust side to differenciate between active and inactive
|
||||||
matchBackground: withOpacity(foreground(layer, "accent"), 0.4),
|
matchBackground: withOpacity(foreground(layer, "accent"), 0.4),
|
||||||
@ -64,10 +70,10 @@ export default function search(colorScheme: ColorScheme) {
|
|||||||
...editor,
|
...editor,
|
||||||
border: border(layer, "negative"),
|
border: border(layer, "negative"),
|
||||||
},
|
},
|
||||||
includeExcludeEditor: {
|
includeExcludeEditor,
|
||||||
...editor,
|
invalidIncludeExcludeEditor: {
|
||||||
minWidth: 100,
|
...includeExcludeEditor,
|
||||||
maxWidth: 250,
|
border: border(layer, "negative"),
|
||||||
},
|
},
|
||||||
matchIndex: {
|
matchIndex: {
|
||||||
...text(layer, "mono", "variant"),
|
...text(layer, "mono", "variant"),
|
||||||
|
Loading…
Reference in New Issue
Block a user