154 lines · 5.0 KB · Rust
RawDownload
use crate::{Editor, RangeToAnchorExt};use gpui::{Context, Window};use language::CursorShape; enum MatchingBracketHighlight {} pub fn refresh_matching_bracket_highlights(    editor: &mut Editor,    window: &mut Window,    cx: &mut Context<Editor>,) {    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 snapshot = editor.snapshot(window, cx);    let head = newest_selection.head();    let mut tail = head;    if (editor.cursor_shape == CursorShape::Block || editor.cursor_shape == CursorShape::Hollow)        && head < snapshot.buffer_snapshot.len()    {        tail += 1;    }     if let Some((opening_range, closing_range)) = snapshot        .buffer_snapshot        .innermost_enclosing_bracket_ranges(head..tail, None)    {        editor.highlight_background::<MatchingBracketHighlight>(            &[                opening_range.to_anchors(&snapshot.buffer_snapshot),                closing_range.to_anchors(&snapshot.buffer_snapshot),            ],            |theme| theme.editor_document_highlight_bracket_background,            cx,        )    }} #[cfg(test)]mod tests {    use super::*;    use crate::{editor_tests::init_test, test::editor_lsp_test_context::EditorLspTestContext};    use indoc::indoc;    use language::{BracketPair, BracketPairConfig, Language, LanguageConfig, LanguageMatcher};     #[gpui::test]    async fn test_matching_bracket_highlights(cx: &mut gpui::TestAppContext) {        init_test(cx, |_| {});         let mut cx = EditorLspTestContext::new(            Language::new(                LanguageConfig {                    name: "Rust".into(),                    matcher: LanguageMatcher {                        path_suffixes: vec!["rs".to_string()],                        ..Default::default()                    },                    brackets: BracketPairConfig {                        pairs: vec![                            BracketPair {                                start: "{".to_string(),                                end: "}".to_string(),                                close: false,                                surround: false,                                newline: true,                            },                            BracketPair {                                start: "(".to_string(),                                end: ")".to_string(),                                close: false,                                surround: false,                                newline: true,                            },                        ],                        ..Default::default()                    },                    ..Default::default()                },                Some(tree_sitter_rust::LANGUAGE.into()),            )            .with_brackets_query(indoc! {r#"                ("{" @open "}" @close)                ("(" @open ")" @close)                "#})            .unwrap(),            Default::default(),            cx,        )        .await;         // positioning cursor inside bracket highlights both        cx.set_state(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(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(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(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        cx.set_state(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);            }        "#});    }}