use super::*;use crate::{ LanguageConfig, LanguageMatcher, LanguageQueries, buffer_tests::markdown_inline_lang, markdown_lang, rust_lang,};use gpui::App;use pretty_assertions::assert_eq;use rand::rngs::StdRng;use std::borrow::Cow;use std::{env, ops::Range, sync::Arc};use text::{Buffer, BufferId, ReplicaId};use tree_sitter::Node;use unindent::Unindent as _;use util::test::marked_text_ranges; #[test]fn test_splice_included_ranges() { let ranges = vec![ts_range(20..30), ts_range(50..60), ts_range(80..90)]; let (new_ranges, change) = splice_included_ranges( ranges.clone(), &[54..56, 58..68], &[ts_range(50..54), ts_range(59..67)], ); assert_eq!( new_ranges, &[ ts_range(20..30), ts_range(50..54), ts_range(59..67), ts_range(80..90), ] ); assert_eq!(change, 1..3); let (new_ranges, change) = splice_included_ranges(ranges.clone(), &[70..71, 91..100], &[]); assert_eq!( new_ranges, &[ts_range(20..30), ts_range(50..60), ts_range(80..90)] ); assert_eq!(change, 2..3); let (new_ranges, change) = splice_included_ranges(ranges.clone(), &[], &[ts_range(0..2), ts_range(70..75)]); assert_eq!( new_ranges, &[ ts_range(0..2), ts_range(20..30), ts_range(50..60), ts_range(70..75), ts_range(80..90) ] ); assert_eq!(change, 0..4); let (new_ranges, change) = splice_included_ranges(ranges.clone(), &[30..50], &[ts_range(25..55)]); assert_eq!(new_ranges, &[ts_range(25..55), ts_range(80..90)]); assert_eq!(change, 0..1); // does not create overlapping ranges let (new_ranges, change) = splice_included_ranges(ranges, &[0..18], &[ts_range(20..32)]); assert_eq!( new_ranges, &[ts_range(20..32), ts_range(50..60), ts_range(80..90)] ); assert_eq!(change, 0..1); fn ts_range(range: Range<usize>) -> tree_sitter::Range { tree_sitter::Range { start_byte: range.start, start_point: tree_sitter::Point { row: 0, column: range.start, }, end_byte: range.end, end_point: tree_sitter::Point { row: 0, column: range.end, }, } }} #[gpui::test]fn test_syntax_map_layers_for_range(cx: &mut App) { let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone())); let language = rust_lang(); registry.add(language.clone()); let mut buffer = Buffer::new( ReplicaId::LOCAL, BufferId::new(1).unwrap(), r#" fn a() { assert_eq!( b(vec![C {}]), vec![d.e], ); println!("{}", f(|_| true)); } "# .unindent(), ); let mut syntax_map = SyntaxMap::new(&buffer); syntax_map.set_language_registry(registry); syntax_map.reparse(language.clone(), &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(2, 0)..Point::new(2, 0), &[ "...(function_item ... (block (expression_statement (macro_invocation...", "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...", ], ); assert_layers_for_range( &syntax_map, &buffer, Point::new(2, 14)..Point::new(2, 16), &[ "...(function_item ...", "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...", "...(array_expression (struct_expression ...", ], ); assert_layers_for_range( &syntax_map, &buffer, Point::new(3, 14)..Point::new(3, 16), &[ "...(function_item ...", "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...", "...(array_expression (field_expression ...", ], ); assert_layers_for_range( &syntax_map, &buffer, Point::new(5, 12)..Point::new(5, 16), &[ "...(function_item ...", "...(call_expression ... (arguments (closure_expression ...", ], ); // Replace a vec! macro invocation with a plain slice, removing a syntactic layer. let macro_name_range = range_for_text(&buffer, "vec!"); buffer.edit([(macro_name_range, "&")]); syntax_map.interpolate(&buffer); syntax_map.reparse(language.clone(), &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(2, 14)..Point::new(2, 16), &[ "...(function_item ...", "...(tuple_expression (call_expression ... arguments: (arguments (reference_expression value: (array_expression...", ], ); // Put the vec! macro back, adding back the syntactic layer. buffer.undo(); syntax_map.interpolate(&buffer); syntax_map.reparse(language, &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(2, 14)..Point::new(2, 16), &[ "...(function_item ...", "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...", "...(array_expression (struct_expression ...", ], );} #[gpui::test]fn test_syntax_map_languages_match_layers_for_range(cx: &mut App) { let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone())); let markdown = markdown_lang(); let markdown_inline = Arc::new(markdown_inline_lang()); registry.add(markdown.clone()); registry.add(markdown_inline); registry.add(rust_lang()); let buffer = Buffer::new( ReplicaId::LOCAL, BufferId::new(1).unwrap(), r#" This is `inline`. ```rs fn a() {} ``` "# .unindent(), ); let mut syntax_map = SyntaxMap::new(&buffer); syntax_map.set_language_registry(registry); syntax_map.reparse(markdown, &buffer); let all_language_names = syntax_map .languages(&buffer, true) .map(|language| language.name().to_string()) .collect::<Vec<_>>(); let all_layer_language_names = syntax_map .layers_for_range(0..buffer.len(), &buffer, true) .map(|layer| layer.language.name().to_string()) .collect::<Vec<_>>(); assert_eq!(all_language_names, all_layer_language_names); assert!( all_language_names .iter() .any(|language_name| language_name == "Markdown-Inline"), "expected hidden languages to be included when include_hidden is true" ); assert!( all_language_names .iter() .any(|language_name| language_name == "Markdown") ); assert!( all_language_names .iter() .any(|language_name| language_name == "Rust") ); let visible_language_names = syntax_map .languages(&buffer, false) .map(|language| language.name().to_string()) .collect::<Vec<_>>(); let visible_layer_language_names = syntax_map .layers_for_range(0..buffer.len(), &buffer, false) .map(|layer| layer.language.name().to_string()) .collect::<Vec<_>>(); assert_eq!(visible_language_names, visible_layer_language_names); assert!( !visible_language_names .iter() .any(|language_name| language_name == "Markdown-Inline"), "expected hidden languages to be excluded when include_hidden is false" ); assert!( visible_language_names .iter() .any(|language_name| language_name == "Markdown") ); assert!( visible_language_names .iter() .any(|language_name| language_name == "Rust") );} #[gpui::test]fn test_dynamic_language_injection(cx: &mut App) { let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone())); let markdown = markdown_lang(); let markdown_inline = Arc::new(markdown_inline_lang()); registry.add(markdown.clone()); registry.add(markdown_inline.clone()); registry.add(rust_lang()); registry.add(Arc::new(ruby_lang())); let mut buffer = Buffer::new( ReplicaId::LOCAL, BufferId::new(1).unwrap(), r#" This is a code block: ```rs fn foo() {} ``` "# .unindent(), ); let mut syntax_map = SyntaxMap::new(&buffer); syntax_map.set_language_registry(registry.clone()); syntax_map.reparse(markdown.clone(), &buffer); syntax_map.reparse(markdown_inline.clone(), &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(3, 0)..Point::new(3, 0), &[ "(document (section (paragraph (inline)) (fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (block_continuation) (code_fence_content (block_continuation)) (fenced_code_block_delimiter))))", "(inline (code_span (code_span_delimiter) (code_span_delimiter)))", "...(function_item name: (identifier) parameters: (parameters) body: (block)...", ], ); // Replace `rs` with a path to ending in `.rb` in code block. let macro_name_range = range_for_text(&buffer, "rs"); buffer.edit([(macro_name_range, "foo/bar/baz.rb")]); syntax_map.interpolate(&buffer); syntax_map.reparse(markdown.clone(), &buffer); syntax_map.reparse(markdown_inline.clone(), &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(3, 0)..Point::new(3, 0), &[ "(document (section (paragraph (inline)) (fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (block_continuation) (code_fence_content (block_continuation)) (fenced_code_block_delimiter))))", "(inline (code_span (code_span_delimiter) (code_span_delimiter)))", "...(call method: (identifier) arguments: (argument_list (call method: (identifier) arguments: (argument_list) block: (block)...", ], ); // Replace Ruby with a language that hasn't been loaded yet. let macro_name_range = range_for_text(&buffer, "foo/bar/baz.rb"); buffer.edit([(macro_name_range, "html")]); syntax_map.interpolate(&buffer); syntax_map.reparse(markdown.clone(), &buffer); syntax_map.reparse(markdown_inline.clone(), &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(3, 0)..Point::new(3, 0), &[ "(document (section (paragraph (inline)) (fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (block_continuation) (code_fence_content (block_continuation)) (fenced_code_block_delimiter))))", "(inline (code_span (code_span_delimiter) (code_span_delimiter)))", ], ); assert!(syntax_map.contains_unknown_injections()); registry.add(Arc::new(html_lang())); syntax_map.reparse(markdown, &buffer); syntax_map.reparse(markdown_inline, &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(3, 0)..Point::new(3, 0), &[ "(document (section (paragraph (inline)) (fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (block_continuation) (code_fence_content (block_continuation)) (fenced_code_block_delimiter))))", "(inline (code_span (code_span_delimiter) (code_span_delimiter)))", "(document (text))", ], ); assert!(!syntax_map.contains_unknown_injections());} #[gpui::test]fn test_rust_json_macro_empty_string_highlighting(cx: &mut App) { let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone())); let language = rust_lang(); registry.add(language.clone()); let buffer = Buffer::new( ReplicaId::LOCAL, BufferId::new(1).unwrap(), r#" serde_json::json!({ "email": "", "password": "password123", "requires2FA": false }) "# .unindent(), ); let mut syntax_map = SyntaxMap::new(&buffer); syntax_map.set_language_registry(registry); syntax_map.reparse(language, &buffer); assert_capture_ranges( &syntax_map, &buffer, &["string"], r#" serde_json::json!({ «"email"»: «""», «"password"»: «"password123"», «"requires2FA"»: false }) "#, ); assert_capture_ranges( &syntax_map, &buffer, &["boolean"], r#" serde_json::json!({ "email": "", "password": "password123", "requires2FA": «false» }) "#, );} #[gpui::test]fn test_typing_multiple_new_injections(cx: &mut App) { let (buffer, syntax_map) = test_edit_sequence( "Rust", &[ "fn a() { test_macro }", "fn a() { test_macro«!» }", "fn a() { test_macro!«()» }", "fn a() { test_macro!(«b») }", "fn a() { test_macro!(b«.») }", "fn a() { test_macro!(b.«c») }", "fn a() { test_macro!(b.c«()») }", "fn a() { test_macro!(b.c(«vec»)) }", "fn a() { test_macro!(b.c(vec«!»)) }", "fn a() { test_macro!(b.c(vec!«[]»)) }", "fn a() { test_macro!(b.c(vec![«d»])) }", "fn a() { test_macro!(b.c(vec![d«.»])) }", "fn a() { test_macro!(b.c(vec![d.«e»])) }", ], cx, ); assert_capture_ranges( &syntax_map, &buffer, &["property"], "fn a() { test_macro!(b.«c»(vec![d.«e»])) }", );} #[gpui::test]fn test_pasting_new_injection_line_between_others(cx: &mut App) { let (buffer, syntax_map) = test_edit_sequence( "Rust", &[ " fn a() { b!(B {}); c!(C {}); d!(D {}); e!(E {}); f!(F {}); g!(G {}); } ", " fn a() { b!(B {}); c!(C {}); d!(D {}); « h!(H {}); » e!(E {}); f!(F {}); g!(G {}); } ", ], cx, ); assert_capture_ranges( &syntax_map, &buffer, &["type"], " fn a() { b!(«B» {}); c!(«C» {}); d!(«D» {}); h!(«H» {}); e!(«E» {}); f!(«F» {}); g!(«G» {}); } ", );} #[gpui::test]fn test_joining_injections_with_child_injections(cx: &mut App) { let (buffer, syntax_map) = test_edit_sequence( "Rust", &[ " fn a() { b!( c![one.two.three], d![four.five.six], ); e!( f![seven.eight], ); } ", " fn a() { b!( c![one.two.three], d![four.five.six],Lines 1–500 of 1642. Load more
use super::*; use crate::{ LanguageConfig, LanguageMatcher, LanguageQueries, buffer_tests::markdown_inline_lang, markdown_lang, rust_lang, }; use gpui::App; use pretty_assertions::assert_eq; use rand::rngs::StdRng; use std::borrow::Cow; use std::{env, ops::Range, sync::Arc}; use text::{Buffer, BufferId, ReplicaId}; use tree_sitter::Node; use unindent::Unindent as _; use util::test::marked_text_ranges; #[test] fn test_splice_included_ranges() { let ranges = vec![ts_range(20..30), ts_range(50..60), ts_range(80..90)]; let (new_ranges, change) = splice_included_ranges( ranges.clone(), &[54..56, 58..68], &[ts_range(50..54), ts_range(59..67)], ); assert_eq!( new_ranges, &[ ts_range(20..30), ts_range(50..54), ts_range(59..67), ts_range(80..90), ] ); assert_eq!(change, 1..3); let (new_ranges, change) = splice_included_ranges(ranges.clone(), &[70..71, 91..100], &[]); assert_eq!( new_ranges, &[ts_range(20..30), ts_range(50..60), ts_range(80..90)] ); assert_eq!(change, 2..3); let (new_ranges, change) = splice_included_ranges(ranges.clone(), &[], &[ts_range(0..2), ts_range(70..75)]); assert_eq!( new_ranges, &[ ts_range(0..2), ts_range(20..30), ts_range(50..60), ts_range(70..75), ts_range(80..90) ] ); assert_eq!(change, 0..4); let (new_ranges, change) = splice_included_ranges(ranges.clone(), &[30..50], &[ts_range(25..55)]); assert_eq!(new_ranges, &[ts_range(25..55), ts_range(80..90)]); assert_eq!(change, 0..1); // does not create overlapping ranges let (new_ranges, change) = splice_included_ranges(ranges, &[0..18], &[ts_range(20..32)]); assert_eq!( new_ranges, &[ts_range(20..32), ts_range(50..60), ts_range(80..90)] ); assert_eq!(change, 0..1); fn ts_range(range: Range<usize>) -> tree_sitter::Range { tree_sitter::Range { start_byte: range.start, start_point: tree_sitter::Point { row: 0, column: range.start, }, end_byte: range.end, end_point: tree_sitter::Point { row: 0, column: range.end, }, } } } #[gpui::test] fn test_syntax_map_layers_for_range(cx: &mut App) { let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone())); let language = rust_lang(); registry.add(language.clone()); let mut buffer = Buffer::new( ReplicaId::LOCAL, BufferId::new(1).unwrap(), r#" fn a() { assert_eq!( b(vec![C {}]), vec![d.e], ); println!("{}", f(|_| true)); } "# .unindent(), ); let mut syntax_map = SyntaxMap::new(&buffer); syntax_map.set_language_registry(registry); syntax_map.reparse(language.clone(), &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(2, 0)..Point::new(2, 0), &[ "...(function_item ... (block (expression_statement (macro_invocation...", "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...", ], ); assert_layers_for_range( &syntax_map, &buffer, Point::new(2, 14)..Point::new(2, 16), &[ "...(function_item ...", "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...", "...(array_expression (struct_expression ...", ], ); assert_layers_for_range( &syntax_map, &buffer, Point::new(3, 14)..Point::new(3, 16), &[ "...(function_item ...", "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...", "...(array_expression (field_expression ...", ], ); assert_layers_for_range( &syntax_map, &buffer, Point::new(5, 12)..Point::new(5, 16), &[ "...(function_item ...", "...(call_expression ... (arguments (closure_expression ...", ], ); // Replace a vec! macro invocation with a plain slice, removing a syntactic layer. let macro_name_range = range_for_text(&buffer, "vec!"); buffer.edit([(macro_name_range, "&")]); syntax_map.interpolate(&buffer); syntax_map.reparse(language.clone(), &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(2, 14)..Point::new(2, 16), &[ "...(function_item ...", "...(tuple_expression (call_expression ... arguments: (arguments (reference_expression value: (array_expression...", ], ); // Put the vec! macro back, adding back the syntactic layer. buffer.undo(); syntax_map.interpolate(&buffer); syntax_map.reparse(language, &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(2, 14)..Point::new(2, 16), &[ "...(function_item ...", "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...", "...(array_expression (struct_expression ...", ], ); } #[gpui::test] fn test_syntax_map_languages_match_layers_for_range(cx: &mut App) { let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone())); let markdown = markdown_lang(); let markdown_inline = Arc::new(markdown_inline_lang()); registry.add(markdown.clone()); registry.add(markdown_inline); registry.add(rust_lang()); let buffer = Buffer::new( ReplicaId::LOCAL, BufferId::new(1).unwrap(), r#" This is `inline`. ```rs fn a() {} ``` "# .unindent(), ); let mut syntax_map = SyntaxMap::new(&buffer); syntax_map.set_language_registry(registry); syntax_map.reparse(markdown, &buffer); let all_language_names = syntax_map .languages(&buffer, true) .map(|language| language.name().to_string()) .collect::<Vec<_>>(); let all_layer_language_names = syntax_map .layers_for_range(0..buffer.len(), &buffer, true) .map(|layer| layer.language.name().to_string()) .collect::<Vec<_>>(); assert_eq!(all_language_names, all_layer_language_names); assert!( all_language_names .iter() .any(|language_name| language_name == "Markdown-Inline"), "expected hidden languages to be included when include_hidden is true" ); assert!( all_language_names .iter() .any(|language_name| language_name == "Markdown") ); assert!( all_language_names .iter() .any(|language_name| language_name == "Rust") ); let visible_language_names = syntax_map .languages(&buffer, false) .map(|language| language.name().to_string()) .collect::<Vec<_>>(); let visible_layer_language_names = syntax_map .layers_for_range(0..buffer.len(), &buffer, false) .map(|layer| layer.language.name().to_string()) .collect::<Vec<_>>(); assert_eq!(visible_language_names, visible_layer_language_names); assert!( !visible_language_names .iter() .any(|language_name| language_name == "Markdown-Inline"), "expected hidden languages to be excluded when include_hidden is false" ); assert!( visible_language_names .iter() .any(|language_name| language_name == "Markdown") ); assert!( visible_language_names .iter() .any(|language_name| language_name == "Rust") ); } #[gpui::test] fn test_dynamic_language_injection(cx: &mut App) { let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone())); let markdown = markdown_lang(); let markdown_inline = Arc::new(markdown_inline_lang()); registry.add(markdown.clone()); registry.add(markdown_inline.clone()); registry.add(rust_lang()); registry.add(Arc::new(ruby_lang())); let mut buffer = Buffer::new( ReplicaId::LOCAL, BufferId::new(1).unwrap(), r#" This is a code block: ```rs fn foo() {} ``` "# .unindent(), ); let mut syntax_map = SyntaxMap::new(&buffer); syntax_map.set_language_registry(registry.clone()); syntax_map.reparse(markdown.clone(), &buffer); syntax_map.reparse(markdown_inline.clone(), &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(3, 0)..Point::new(3, 0), &[ "(document (section (paragraph (inline)) (fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (block_continuation) (code_fence_content (block_continuation)) (fenced_code_block_delimiter))))", "(inline (code_span (code_span_delimiter) (code_span_delimiter)))", "...(function_item name: (identifier) parameters: (parameters) body: (block)...", ], ); // Replace `rs` with a path to ending in `.rb` in code block. let macro_name_range = range_for_text(&buffer, "rs"); buffer.edit([(macro_name_range, "foo/bar/baz.rb")]); syntax_map.interpolate(&buffer); syntax_map.reparse(markdown.clone(), &buffer); syntax_map.reparse(markdown_inline.clone(), &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(3, 0)..Point::new(3, 0), &[ "(document (section (paragraph (inline)) (fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (block_continuation) (code_fence_content (block_continuation)) (fenced_code_block_delimiter))))", "(inline (code_span (code_span_delimiter) (code_span_delimiter)))", "...(call method: (identifier) arguments: (argument_list (call method: (identifier) arguments: (argument_list) block: (block)...", ], ); // Replace Ruby with a language that hasn't been loaded yet. let macro_name_range = range_for_text(&buffer, "foo/bar/baz.rb"); buffer.edit([(macro_name_range, "html")]); syntax_map.interpolate(&buffer); syntax_map.reparse(markdown.clone(), &buffer); syntax_map.reparse(markdown_inline.clone(), &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(3, 0)..Point::new(3, 0), &[ "(document (section (paragraph (inline)) (fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (block_continuation) (code_fence_content (block_continuation)) (fenced_code_block_delimiter))))", "(inline (code_span (code_span_delimiter) (code_span_delimiter)))", ], ); assert!(syntax_map.contains_unknown_injections()); registry.add(Arc::new(html_lang())); syntax_map.reparse(markdown, &buffer); syntax_map.reparse(markdown_inline, &buffer); assert_layers_for_range( &syntax_map, &buffer, Point::new(3, 0)..Point::new(3, 0), &[ "(document (section (paragraph (inline)) (fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (block_continuation) (code_fence_content (block_continuation)) (fenced_code_block_delimiter))))", "(inline (code_span (code_span_delimiter) (code_span_delimiter)))", "(document (text))", ], ); assert!(!syntax_map.contains_unknown_injections()); } #[gpui::test] fn test_rust_json_macro_empty_string_highlighting(cx: &mut App) { let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone())); let language = rust_lang(); registry.add(language.clone()); let buffer = Buffer::new( ReplicaId::LOCAL, BufferId::new(1).unwrap(), r#" serde_json::json!({ "email": "", "password": "password123", "requires2FA": false }) "# .unindent(), ); let mut syntax_map = SyntaxMap::new(&buffer); syntax_map.set_language_registry(registry); syntax_map.reparse(language, &buffer); assert_capture_ranges( &syntax_map, &buffer, &["string"], r#" serde_json::json!({ «"email"»: «""», «"password"»: «"password123"», «"requires2FA"»: false }) "#, ); assert_capture_ranges( &syntax_map, &buffer, &["boolean"], r#" serde_json::json!({ "email": "", "password": "password123", "requires2FA": «false» }) "#, ); } #[gpui::test] fn test_typing_multiple_new_injections(cx: &mut App) { let (buffer, syntax_map) = test_edit_sequence( "Rust", &[ "fn a() { test_macro }", "fn a() { test_macro«!» }", "fn a() { test_macro!«()» }", "fn a() { test_macro!(«b») }", "fn a() { test_macro!(b«.») }", "fn a() { test_macro!(b.«c») }", "fn a() { test_macro!(b.c«()») }", "fn a() { test_macro!(b.c(«vec»)) }", "fn a() { test_macro!(b.c(vec«!»)) }", "fn a() { test_macro!(b.c(vec!«[]»)) }", "fn a() { test_macro!(b.c(vec![«d»])) }", "fn a() { test_macro!(b.c(vec![d«.»])) }", "fn a() { test_macro!(b.c(vec![d.«e»])) }", ], cx, ); assert_capture_ranges( &syntax_map, &buffer, &["property"], "fn a() { test_macro!(b.«c»(vec![d.«e»])) }", ); } #[gpui::test] fn test_pasting_new_injection_line_between_others(cx: &mut App) { let (buffer, syntax_map) = test_edit_sequence( "Rust", &[ " fn a() { b!(B {}); c!(C {}); d!(D {}); e!(E {}); f!(F {}); g!(G {}); } ", " fn a() { b!(B {}); c!(C {}); d!(D {}); « h!(H {}); » e!(E {}); f!(F {}); g!(G {}); } ", ], cx, ); assert_capture_ranges( &syntax_map, &buffer, &["type"], " fn a() { b!(«B» {}); c!(«C» {}); d!(«D» {}); h!(«H» {}); e!(«E» {}); f!(«F» {}); g!(«G» {}); } ", ); } #[gpui::test] fn test_joining_injections_with_child_injections(cx: &mut App) { let (buffer, syntax_map) = test_edit_sequence( "Rust", &[ " fn a() { b!( c![one.two.three], d![four.five.six], ); e!( f![seven.eight], ); } ", " fn a() { b!( c![one.two.three], d![four.five.six],