Add logic for managing language and theme extensions (#7467)
This PR adds the initial support for loading extensions in Zed.
### Extensions Directory
Extensions are loaded from the extensions directory.
The extensions directory has the following structure:
```
extensions/
installed/
extension-a/
grammars/
languages/
extension-b/
themes/
manifest.json
```
The `manifest.json` file is used internally by Zed to keep track of
which extensions are installed. This file should be maintained
automatically, and shouldn't require any direct interaction with it.
Extensions can provide Tree-sitter grammars, languages, and themes.
Release Notes:
- N/A
---------
Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
co-authored by
Marshall
parent
6b598a07d9
commit
6edeea7c8a
@@ -1003,7 +1003,7 @@ pub mod tests {
|
||||
use gpui::{div, font, observe, px, AppContext, Context, Element, Hsla};
|
||||
use language::{
|
||||
language_settings::{AllLanguageSettings, AllLanguageSettingsContent},
|
||||
Buffer, Language, LanguageConfig, SelectionGoal,
|
||||
Buffer, Language, LanguageConfig, LanguageMatcher, SelectionGoal,
|
||||
};
|
||||
use project::Project;
|
||||
use rand::{prelude::*, Rng};
|
||||
@@ -1453,7 +1453,10 @@ pub mod tests {
|
||||
Language::new(
|
||||
LanguageConfig {
|
||||
name: "Test".into(),
|
||||
path_suffixes: vec![".test".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec![".test".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
@@ -1540,7 +1543,10 @@ pub mod tests {
|
||||
Language::new(
|
||||
LanguageConfig {
|
||||
name: "Test".into(),
|
||||
path_suffixes: vec![".test".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec![".test".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
@@ -1608,7 +1614,10 @@ pub mod tests {
|
||||
Language::new(
|
||||
LanguageConfig {
|
||||
name: "Test".into(),
|
||||
path_suffixes: vec![".test".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec![".test".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
|
||||
@@ -15,7 +15,8 @@ use language::{
|
||||
language_settings::{AllLanguageSettings, AllLanguageSettingsContent, LanguageSettingsContent},
|
||||
BracketPairConfig,
|
||||
Capability::ReadWrite,
|
||||
FakeLspAdapter, LanguageConfig, LanguageConfigOverride, LanguageRegistry, Override, Point,
|
||||
FakeLspAdapter, LanguageConfig, LanguageConfigOverride, LanguageMatcher, LanguageRegistry,
|
||||
Override, Point,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use project::project_settings::{LspSettings, ProjectSettings};
|
||||
@@ -5077,7 +5078,10 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
|
||||
let mut language = Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
@@ -5196,7 +5200,10 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
|
||||
let mut language = Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
@@ -5318,7 +5325,10 @@ async fn test_document_format_manual_trigger(cx: &mut gpui::TestAppContext) {
|
||||
let mut language = Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
// Enable Prettier formatting for the same buffer, and ensure
|
||||
// LSP is called instead of Prettier.
|
||||
prettier_parser_name: Some("test_parser".to_string()),
|
||||
@@ -7747,7 +7757,10 @@ async fn test_on_type_formatting_not_triggered(cx: &mut gpui::TestAppContext) {
|
||||
let mut language = Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
brackets: BracketPairConfig {
|
||||
pairs: vec![BracketPair {
|
||||
start: "{".to_string(),
|
||||
@@ -7859,7 +7872,10 @@ async fn test_language_server_restart_due_to_settings_change(cx: &mut gpui::Test
|
||||
let mut language = Language::new(
|
||||
LanguageConfig {
|
||||
name: Arc::clone(&language_name),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
@@ -8086,7 +8102,10 @@ async fn test_completions_in_languages_with_extra_word_characters(cx: &mut gpui:
|
||||
let mut cx = EditorLspTestContext::new(
|
||||
Language::new(
|
||||
LanguageConfig {
|
||||
path_suffixes: vec!["jsx".into()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["jsx".into()],
|
||||
..Default::default()
|
||||
},
|
||||
overrides: [(
|
||||
"element".into(),
|
||||
LanguageConfigOverride {
|
||||
@@ -8187,7 +8206,10 @@ async fn test_document_format_with_prettier(cx: &mut gpui::TestAppContext) {
|
||||
let mut language = Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
prettier_parser_name: Some("test_parser".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@ 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};
|
||||
use language::{BracketPair, BracketPairConfig, Language, LanguageConfig, LanguageMatcher};
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_matching_bracket_highlights(cx: &mut gpui::TestAppContext) {
|
||||
@@ -45,7 +45,10 @@ mod tests {
|
||||
Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
brackets: BracketPairConfig {
|
||||
pairs: vec![
|
||||
BracketPair {
|
||||
|
||||
@@ -1240,7 +1240,7 @@ pub mod tests {
|
||||
use itertools::Itertools;
|
||||
use language::{
|
||||
language_settings::AllLanguageSettingsContent, Capability, FakeLspAdapter, Language,
|
||||
LanguageConfig,
|
||||
LanguageConfig, LanguageMatcher,
|
||||
};
|
||||
use lsp::FakeLanguageServer;
|
||||
use parking_lot::Mutex;
|
||||
@@ -1529,7 +1529,10 @@ pub mod tests {
|
||||
let mut language = Language::new(
|
||||
LanguageConfig {
|
||||
name: name.into(),
|
||||
path_suffixes: vec![path_suffix.to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec![path_suffix.to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
@@ -2209,7 +2212,10 @@ pub mod tests {
|
||||
let mut language = Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
@@ -2500,7 +2506,10 @@ pub mod tests {
|
||||
let mut language = Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
@@ -2848,7 +2857,10 @@ pub mod tests {
|
||||
let mut language = Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
@@ -3079,7 +3091,10 @@ pub mod tests {
|
||||
let mut language = Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
@@ -3319,7 +3334,10 @@ pub mod tests {
|
||||
let mut language = Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
|
||||
@@ -12,7 +12,9 @@ use collections::HashSet;
|
||||
use futures::Future;
|
||||
use gpui::{View, ViewContext, VisualTestContext};
|
||||
use indoc::indoc;
|
||||
use language::{point_to_lsp, FakeLspAdapter, Language, LanguageConfig, LanguageQueries};
|
||||
use language::{
|
||||
point_to_lsp, FakeLspAdapter, Language, LanguageConfig, LanguageMatcher, LanguageQueries,
|
||||
};
|
||||
use lsp::{notification, request};
|
||||
use multi_buffer::ToPointUtf16;
|
||||
use project::Project;
|
||||
@@ -115,7 +117,10 @@ impl EditorLspTestContext {
|
||||
let language = Language::new(
|
||||
LanguageConfig {
|
||||
name: "Rust".into(),
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rs".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_rust::language()),
|
||||
@@ -160,7 +165,10 @@ impl EditorLspTestContext {
|
||||
let language = Language::new(
|
||||
LanguageConfig {
|
||||
name: "Typescript".into(),
|
||||
path_suffixes: vec!["ts".to_string()],
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["ts".to_string()],
|
||||
..Default::default()
|
||||
},
|
||||
brackets: language::BracketPairConfig {
|
||||
pairs: vec![language::BracketPair {
|
||||
start: "{".to_string(),
|
||||
|
||||
Reference in New Issue
Block a user