diff --git a/Cargo.lock b/Cargo.lock index 79eae80258..f7a354ed28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2861,6 +2861,8 @@ dependencies = [ "text", "theme", "tree-sitter", + "tree-sitter-html", + "tree-sitter-javascript", "tree-sitter-json 0.19.0", "tree-sitter-python", "tree-sitter-rust", diff --git a/crates/language/Cargo.toml b/crates/language/Cargo.toml index 6e9f368e77..6d80eee779 100644 --- a/crates/language/Cargo.toml +++ b/crates/language/Cargo.toml @@ -63,6 +63,8 @@ util = { path = "../util", features = ["test-support"] } ctor = "0.1" env_logger = "0.9" rand = "0.8.3" +tree-sitter-html = "*" +tree-sitter-javascript = "*" tree-sitter-json = "*" tree-sitter-rust = "*" tree-sitter-python = "*" diff --git a/crates/language/src/tests.rs b/crates/language/src/tests.rs index 8f56f3287e..3cfddce71f 100644 --- a/crates/language/src/tests.rs +++ b/crates/language/src/tests.rs @@ -14,7 +14,7 @@ use std::{ }; use text::network::Network; use unindent::Unindent as _; -use util::post_inc; +use util::{post_inc, test::marked_text_ranges}; #[cfg(test)] #[ctor::ctor] @@ -1035,6 +1035,120 @@ fn test_autoindent_language_without_indents_query(cx: &mut MutableAppContext) { }); } +#[gpui::test] +fn test_autoindent_with_injected_languages(cx: &mut MutableAppContext) { + cx.set_global({ + let mut settings = Settings::test(cx); + settings.language_overrides.extend([ + ( + "HTML".into(), + settings::EditorSettings { + tab_size: Some(2.try_into().unwrap()), + ..Default::default() + }, + ), + ( + "JavaScript".into(), + settings::EditorSettings { + tab_size: Some(8.try_into().unwrap()), + ..Default::default() + }, + ), + ]); + settings + }); + + let html_language = Arc::new( + Language::new( + LanguageConfig { + name: "HTML".into(), + ..Default::default() + }, + Some(tree_sitter_html::language()), + ) + .with_indents_query( + " + (element + (start_tag) @start + (end_tag)? @end) @indent + ", + ) + .unwrap() + .with_injection_query( + r#" + (script_element + (raw_text) @content + (#set! "language" "javascript")) + "#, + ) + .unwrap(), + ); + + let javascript_language = Arc::new( + Language::new( + LanguageConfig { + name: "JavaScript".into(), + ..Default::default() + }, + Some(tree_sitter_javascript::language()), + ) + .with_indents_query( + r#" + (object "}" @end) @indent + "#, + ) + .unwrap(), + ); + + let language_registry = Arc::new(LanguageRegistry::test()); + language_registry.add(html_language.clone()); + language_registry.add(javascript_language.clone()); + + cx.add_model(|cx| { + let (text, ranges) = marked_text_ranges( + &" +
ˇ +
+ + ˇ + + " + .unindent(), + false, + ); + + let mut buffer = Buffer::new(0, text, cx); + buffer.set_language_registry(language_registry); + buffer.set_language(Some(html_language), cx); + buffer.edit( + ranges.into_iter().map(|range| (range, "\na")), + Some(AutoindentMode::EachLine), + cx, + ); + assert_eq!( + buffer.text(), + " +
+ a +
+ + + a + + " + .unindent() + ); + buffer + }); +} + #[gpui::test] fn test_serialization(cx: &mut gpui::MutableAppContext) { let mut now = Instant::now();