highlight both brackets, only when empty selection, and add test
This commit is contained in:
parent
9b36e3d009
commit
1f3dc2f534
6 changed files with 201 additions and 50 deletions
|
@ -1,6 +1,6 @@
|
|||
use gpui::ViewContext;
|
||||
|
||||
use crate::Editor;
|
||||
use crate::{Editor, RangeToAnchorExt};
|
||||
|
||||
enum MatchingBracketHighlight {}
|
||||
|
||||
|
@ -8,33 +8,135 @@ pub fn refresh_matching_bracket_highlights(editor: &mut Editor, cx: &mut ViewCon
|
|||
editor.clear_background_highlights::<MatchingBracketHighlight>(cx);
|
||||
|
||||
let newest_selection = editor.selections.newest::<usize>(cx);
|
||||
// Don't highlight brackets if the selection isn't empty
|
||||
if !newest_selection.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let head = newest_selection.head();
|
||||
let snapshot = editor.snapshot(cx);
|
||||
if let Some((opening_range, closing_range)) = snapshot
|
||||
.buffer_snapshot
|
||||
.enclosing_bracket_ranges(newest_selection.range())
|
||||
.enclosing_bracket_ranges(head..head)
|
||||
{
|
||||
let head = newest_selection.head();
|
||||
let range_to_highlight = if opening_range.contains(&head) {
|
||||
Some(closing_range)
|
||||
} else if closing_range.contains(&head) {
|
||||
Some(opening_range)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(range_to_highlight) = range_to_highlight {
|
||||
let anchor_range = snapshot
|
||||
.buffer_snapshot
|
||||
.anchor_before(range_to_highlight.start)
|
||||
..snapshot
|
||||
.buffer_snapshot
|
||||
.anchor_after(range_to_highlight.end);
|
||||
|
||||
editor.highlight_background::<MatchingBracketHighlight>(
|
||||
vec![anchor_range],
|
||||
|theme| theme.editor.document_highlight_read_background,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
editor.highlight_background::<MatchingBracketHighlight>(
|
||||
vec![
|
||||
opening_range.to_anchors(&snapshot.buffer_snapshot),
|
||||
closing_range.to_anchors(&snapshot.buffer_snapshot),
|
||||
],
|
||||
|theme| theme.editor.document_highlight_read_background,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use indoc::indoc;
|
||||
|
||||
use language::{BracketPair, Language, LanguageConfig};
|
||||
|
||||
use crate::test::EditorLspTestContext;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_matching_bracket_highlights(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = EditorLspTestContext::new(
|
||||
Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
brackets: vec![
|
||||
BracketPair {
|
||||
start: "{".to_string(),
|
||||
end: "}".to_string(),
|
||||
close: false,
|
||||
newline: true,
|
||||
},
|
||||
BracketPair {
|
||||
start: "(".to_string(),
|
||||
end: ")".to_string(),
|
||||
close: false,
|
||||
newline: true,
|
||||
},
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
)
|
||||
.with_brackets_query(indoc! {r#"
|
||||
("{" @open "}" @close)
|
||||
("(" @open ")" @close)
|
||||
"#})
|
||||
.unwrap(),
|
||||
Default::default(),
|
||||
cx,
|
||||
)
|
||||
.await;
|
||||
|
||||
// positioning cursor inside bracket highlights both
|
||||
cx.set_state_by(
|
||||
vec!['|'.into()],
|
||||
indoc! {r#"
|
||||
pub fn test("Test |argument") {
|
||||
another_test(1, 2, 3);
|
||||
}"#},
|
||||
);
|
||||
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
||||
pub fn test[(]"Test argument"[)] {
|
||||
another_test(1, 2, 3);
|
||||
}"#});
|
||||
|
||||
cx.set_state_by(
|
||||
vec!['|'.into()],
|
||||
indoc! {r#"
|
||||
pub fn test("Test argument") {
|
||||
another_test(1, |2, 3);
|
||||
}"#},
|
||||
);
|
||||
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
||||
pub fn test("Test argument") {
|
||||
another_test[(]1, 2, 3[)];
|
||||
}"#});
|
||||
|
||||
cx.set_state_by(
|
||||
vec!['|'.into()],
|
||||
indoc! {r#"
|
||||
pub fn test("Test argument") {
|
||||
another|_test(1, 2, 3);
|
||||
}"#},
|
||||
);
|
||||
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
||||
pub fn test("Test argument") [{]
|
||||
another_test(1, 2, 3);
|
||||
[}]"#});
|
||||
|
||||
// positioning outside of brackets removes highlight
|
||||
cx.set_state_by(
|
||||
vec!['|'.into()],
|
||||
indoc! {r#"
|
||||
pub f|n test("Test argument") {
|
||||
another_test(1, 2, 3);
|
||||
}"#},
|
||||
);
|
||||
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
||||
pub fn test("Test argument") {
|
||||
another_test(1, 2, 3);
|
||||
}"#});
|
||||
|
||||
// non empty selection dismisses highlight
|
||||
// positioning outside of brackets removes highlight
|
||||
cx.set_state_by(
|
||||
vec![('<', '>').into()],
|
||||
indoc! {r#"
|
||||
pub fn test("Te<st arg>ument") {
|
||||
another_test(1, 2, 3);
|
||||
}"#},
|
||||
);
|
||||
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
||||
pub fn test("Test argument") {
|
||||
another_test(1, 2, 3);
|
||||
}"#});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue