diff --git a/crates/buffer/src/language.rs b/crates/buffer/src/language.rs index 8970aaa444..5e3cf19745 100644 --- a/crates/buffer/src/language.rs +++ b/crates/buffer/src/language.rs @@ -1,10 +1,11 @@ -use crate::{HighlightMap}; +use crate::HighlightMap; +use anyhow::Result; use parking_lot::Mutex; use serde::Deserialize; use std::{path::Path, str, sync::Arc}; +use theme::SyntaxTheme; use tree_sitter::{Language as Grammar, Query}; pub use tree_sitter::{Parser, Tree}; -use theme::SyntaxTheme; #[derive(Default, Deserialize)] pub struct LanguageConfig { @@ -12,18 +13,12 @@ pub struct LanguageConfig { pub path_suffixes: Vec, } -#[derive(Deserialize)] -pub struct BracketPair { - pub start: String, - pub end: String, -} - pub struct Language { - pub config: LanguageConfig, - pub grammar: Grammar, - pub highlight_query: Query, - pub brackets_query: Query, - pub highlight_map: Mutex, + pub(crate) config: LanguageConfig, + pub(crate) grammar: Grammar, + pub(crate) highlight_query: Query, + pub(crate) brackets_query: Query, + pub(crate) highlight_map: Mutex, } #[derive(Default)] @@ -62,6 +57,26 @@ impl LanguageRegistry { } impl Language { + pub fn new(config: LanguageConfig, grammar: Grammar) -> Self { + Self { + config, + brackets_query: Query::new(grammar, "").unwrap(), + highlight_query: Query::new(grammar, "").unwrap(), + grammar, + highlight_map: Default::default(), + } + } + + pub fn with_highlights_query(mut self, highlights_query_source: &str) -> Result { + self.highlight_query = Query::new(self.grammar, highlights_query_source)?; + Ok(self) + } + + pub fn with_brackets_query(mut self, brackets_query_source: &str) -> Result { + self.brackets_query = Query::new(self.grammar, brackets_query_source)?; + Ok(self) + } + pub fn name(&self) -> &str { self.config.name.as_str() } diff --git a/crates/buffer/src/lib.rs b/crates/buffer/src/lib.rs index cb1fe11c6e..92ac0c70e0 100644 --- a/crates/buffer/src/lib.rs +++ b/crates/buffer/src/lib.rs @@ -4078,19 +4078,16 @@ mod tests { } fn rust_lang() -> Arc { - let lang = tree_sitter_rust::language(); - let brackets_query = r#" - ("{" @open "}" @close) - "#; - Arc::new(Language { - config: LanguageConfig { - name: "Rust".to_string(), - path_suffixes: vec!["rs".to_string()], - }, - grammar: tree_sitter_rust::language(), - highlight_query: tree_sitter::Query::new(lang.clone(), "").unwrap(), - brackets_query: tree_sitter::Query::new(lang.clone(), brackets_query).unwrap(), - highlight_map: Default::default(), - }) + Arc::new( + Language::new( + LanguageConfig { + name: "Rust".to_string(), + path_suffixes: vec!["rs".to_string()], + }, + tree_sitter_rust::language(), + ) + .with_brackets_query(r#" ("{" @open "}" @close) "#) + .unwrap(), + ) } } diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index 8bc6881aed..d9655d9a9c 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -670,7 +670,6 @@ mod tests { async fn test_highlighted_chunks_at(mut cx: gpui::TestAppContext) { use unindent::Unindent as _; - let grammar = tree_sitter_rust::language(); let text = r#" fn outer() {} @@ -678,28 +677,28 @@ mod tests { fn inner() {} }"# .unindent(); - let highlight_query = tree_sitter::Query::new( - grammar, - r#" - (mod_item name: (identifier) body: _ @mod.body) - (function_item name: (identifier) @fn.name)"#, - ) - .unwrap(); + let theme = SyntaxTheme::new(vec![ ("mod.body".to_string(), Color::from_u32(0xff0000ff).into()), ("fn.name".to_string(), Color::from_u32(0x00ff00ff).into()), ]); - let lang = Arc::new(Language { - config: LanguageConfig { - name: "Test".to_string(), - path_suffixes: vec![".test".to_string()], - ..Default::default() - }, - grammar: grammar.clone(), - highlight_query, - brackets_query: tree_sitter::Query::new(grammar, "").unwrap(), - highlight_map: Default::default(), - }); + let lang = Arc::new( + Language::new( + LanguageConfig { + name: "Test".to_string(), + path_suffixes: vec![".test".to_string()], + ..Default::default() + }, + tree_sitter_rust::language(), + ) + .with_highlights_query( + r#" + (mod_item name: (identifier) body: _ @mod.body) + (function_item name: (identifier) @fn.name) + "#, + ) + .unwrap(), + ); lang.set_theme(&theme); let buffer = cx.add_model(|cx| { @@ -759,7 +758,6 @@ mod tests { cx.foreground().set_block_on_ticks(usize::MAX..=usize::MAX); - let grammar = tree_sitter_rust::language(); let text = r#" fn outer() {} @@ -767,28 +765,28 @@ mod tests { fn inner() {} }"# .unindent(); - let highlight_query = tree_sitter::Query::new( - grammar, - r#" - (mod_item name: (identifier) body: _ @mod.body) - (function_item name: (identifier) @fn.name)"#, - ) - .unwrap(); + let theme = SyntaxTheme::new(vec![ ("mod.body".to_string(), Color::from_u32(0xff0000ff).into()), ("fn.name".to_string(), Color::from_u32(0x00ff00ff).into()), ]); - let lang = Arc::new(Language { - config: LanguageConfig { - name: "Test".to_string(), - path_suffixes: vec![".test".to_string()], - ..Default::default() - }, - grammar: grammar.clone(), - highlight_query, - brackets_query: tree_sitter::Query::new(grammar, "").unwrap(), - highlight_map: Default::default(), - }); + let lang = Arc::new( + Language::new( + LanguageConfig { + name: "Test".to_string(), + path_suffixes: vec![".test".to_string()], + ..Default::default() + }, + tree_sitter_rust::language(), + ) + .with_highlights_query( + r#" + (mod_item name: (identifier) body: _ @mod.body) + (function_item name: (identifier) @fn.name) + "#, + ) + .unwrap(), + ); lang.set_theme(&theme); let buffer = cx.add_model(|cx| { diff --git a/crates/editor/src/lib.rs b/crates/editor/src/lib.rs index ad0585837b..66a234e60f 100644 --- a/crates/editor/src/lib.rs +++ b/crates/editor/src/lib.rs @@ -4068,15 +4068,10 @@ mod tests { #[gpui::test] async fn test_select_larger_smaller_syntax_node(mut cx: gpui::TestAppContext) { let settings = cx.read(EditorSettings::test); - - let grammar = tree_sitter_rust::language(); - let language = Arc::new(Language { - config: LanguageConfig::default(), - brackets_query: tree_sitter::Query::new(grammar, "").unwrap(), - highlight_query: tree_sitter::Query::new(grammar, "").unwrap(), - highlight_map: Default::default(), - grammar, - }); + let language = Arc::new(Language::new( + LanguageConfig::default(), + tree_sitter_rust::language(), + )); let text = r#" use mod1::mod2::{mod3, mod4}; @@ -4086,6 +4081,7 @@ mod tests { } "# .unindent(); + let buffer = cx.add_model(|cx| { let history = History::new(text.into()); Buffer::from_history(0, history, None, Some(language), cx) diff --git a/crates/workspace/src/lib.rs b/crates/workspace/src/lib.rs index 6a5fc7f76b..d7a660974e 100644 --- a/crates/workspace/src/lib.rs +++ b/crates/workspace/src/lib.rs @@ -270,19 +270,14 @@ pub struct WorkspaceParams { impl WorkspaceParams { #[cfg(any(test, feature = "test-support"))] pub fn test(cx: &mut MutableAppContext) -> Self { - let grammar = tree_sitter_rust::language(); - let language = Arc::new(buffer::Language { - config: buffer::LanguageConfig { + let mut languages = LanguageRegistry::new(); + languages.add(Arc::new(buffer::Language::new( + buffer::LanguageConfig { name: "Rust".to_string(), path_suffixes: vec!["rs".to_string()], }, - brackets_query: tree_sitter::Query::new(grammar, "").unwrap(), - highlight_query: tree_sitter::Query::new(grammar, "").unwrap(), - highlight_map: Default::default(), - grammar, - }); - let mut languages = LanguageRegistry::new(); - languages.add(language); + tree_sitter_rust::language(), + ))); let client = Client::new(); let http_client = client::test::FakeHttpClient::new(|_| async move { diff --git a/crates/zed/src/language.rs b/crates/zed/src/language.rs index af0581ed8d..774d8c6502 100644 --- a/crates/zed/src/language.rs +++ b/crates/zed/src/language.rs @@ -1,8 +1,7 @@ -use buffer::{HighlightMap, Language, LanguageRegistry}; -use parking_lot::Mutex; +use buffer::{Language, LanguageRegistry}; use rust_embed::RustEmbed; +use std::borrow::Cow; use std::{str, sync::Arc}; -use tree_sitter::Query; #[derive(RustEmbed)] #[folder = "languages"] @@ -18,19 +17,16 @@ fn rust() -> Language { let grammar = tree_sitter_rust::language(); let rust_config = toml::from_slice(&LanguageDir::get("rust/config.toml").unwrap().data).unwrap(); - Language { - config: rust_config, - grammar, - highlight_query: load_query(grammar, "rust/highlights.scm"), - brackets_query: load_query(grammar, "rust/brackets.scm"), - highlight_map: Mutex::new(HighlightMap::default()), - } + Language::new(rust_config, grammar) + .with_highlights_query(load_query("rust/highlights.scm").as_ref()) + .unwrap() + .with_brackets_query(load_query("rust/brackets.scm").as_ref()) + .unwrap() } -fn load_query(grammar: tree_sitter::Language, path: &str) -> Query { - Query::new( - grammar, - str::from_utf8(&LanguageDir::get(path).unwrap().data).unwrap(), - ) - .unwrap() +fn load_query(path: &str) -> Cow<'static, str> { + match LanguageDir::get(path).unwrap().data { + Cow::Borrowed(s) => Cow::Borrowed(str::from_utf8(s).unwrap()), + Cow::Owned(s) => Cow::Owned(String::from_utf8(s).unwrap()), + } }