debugger/extensions: Revert changes to extension store related to language config (#30225)
Revert #29945 Release Notes: - N/A --------- Co-authored-by: Conrad <conrad@zed.dev>
This commit is contained in:
parent
20387f24aa
commit
b091581e4b
@ -1,12 +1,11 @@
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
cmp::Reverse,
|
||||
ops::Not,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
usize,
|
||||
};
|
||||
|
||||
use collections::{HashMap, HashSet};
|
||||
use dap::{
|
||||
DapRegistry, DebugRequest,
|
||||
adapters::{DebugAdapterName, DebugTaskDefinition},
|
||||
@ -192,25 +191,22 @@ impl NewSessionModal {
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<ui::DropdownMenu> {
|
||||
let workspace = self.workspace.clone();
|
||||
let language_registry = self
|
||||
.workspace
|
||||
.update(cx, |this, _| this.app_state().languages.clone())
|
||||
.ok()?;
|
||||
let weak = cx.weak_entity();
|
||||
let label = self
|
||||
.debugger
|
||||
.as_ref()
|
||||
.map(|d| d.0.clone())
|
||||
.unwrap_or_else(|| SELECT_DEBUGGER_LABEL.clone());
|
||||
let active_buffer_language_name =
|
||||
self.task_contexts
|
||||
.active_item_context
|
||||
.as_ref()
|
||||
.and_then(|item| {
|
||||
item.1
|
||||
.as_ref()
|
||||
.and_then(|location| location.buffer.read(cx).language()?.name().into())
|
||||
});
|
||||
let active_buffer_language = self
|
||||
.task_contexts
|
||||
.active_item_context
|
||||
.as_ref()
|
||||
.and_then(|item| {
|
||||
item.1
|
||||
.as_ref()
|
||||
.and_then(|location| location.buffer.read(cx).language())
|
||||
})
|
||||
.cloned();
|
||||
DropdownMenu::new(
|
||||
"dap-adapter-picker",
|
||||
label,
|
||||
@ -229,42 +225,19 @@ impl NewSessionModal {
|
||||
}
|
||||
};
|
||||
|
||||
let available_languages = language_registry.language_names();
|
||||
let mut debugger_to_languages = HashMap::default();
|
||||
for language in available_languages {
|
||||
let Some(language) =
|
||||
language_registry.available_language_for_name(language.as_str())
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
language.config().debuggers.iter().for_each(|adapter| {
|
||||
debugger_to_languages
|
||||
.entry(adapter.clone())
|
||||
.or_insert_with(HashSet::default)
|
||||
.insert(language.name());
|
||||
});
|
||||
}
|
||||
let mut available_adapters = workspace
|
||||
.update(cx, |_, cx| DapRegistry::global(cx).enumerate_adapters())
|
||||
.ok()
|
||||
.unwrap_or_default();
|
||||
|
||||
available_adapters.sort_by_key(|name| {
|
||||
let languages_for_debugger = debugger_to_languages.get(name.as_ref());
|
||||
let languages_count =
|
||||
languages_for_debugger.map_or(0, |languages| languages.len());
|
||||
let contains_language_of_active_buffer = languages_for_debugger
|
||||
.zip(active_buffer_language_name.as_ref())
|
||||
.map_or(false, |(languages, active_buffer_language)| {
|
||||
languages.contains(active_buffer_language)
|
||||
});
|
||||
|
||||
(
|
||||
Reverse(contains_language_of_active_buffer),
|
||||
Reverse(languages_count),
|
||||
)
|
||||
});
|
||||
if let Some(language) = active_buffer_language {
|
||||
available_adapters.sort_by_key(|adapter| {
|
||||
language
|
||||
.config()
|
||||
.debuggers
|
||||
.get_index_of(adapter.0.as_ref())
|
||||
.unwrap_or(usize::MAX)
|
||||
});
|
||||
}
|
||||
|
||||
for adapter in available_adapters.into_iter() {
|
||||
menu = menu.entry(adapter.0.clone(), None, setter_for_name(adapter.clone()));
|
||||
|
@ -4,7 +4,7 @@ use std::sync::Arc;
|
||||
use anyhow::Result;
|
||||
use fs::Fs;
|
||||
use gpui::{App, Global, ReadGlobal, SharedString, Task};
|
||||
use language::{BinaryStatus, LanguageConfig, LanguageName, LoadedLanguage};
|
||||
use language::{BinaryStatus, LanguageMatcher, LanguageName, LoadedLanguage};
|
||||
use lsp::LanguageServerName;
|
||||
use parking_lot::RwLock;
|
||||
|
||||
@ -224,7 +224,10 @@ impl ExtensionGrammarProxy for ExtensionHostProxy {
|
||||
pub trait ExtensionLanguageProxy: Send + Sync + 'static {
|
||||
fn register_language(
|
||||
&self,
|
||||
config: LanguageConfig,
|
||||
language: LanguageName,
|
||||
grammar: Option<Arc<str>>,
|
||||
matcher: LanguageMatcher,
|
||||
hidden: bool,
|
||||
load: Arc<dyn Fn() -> Result<LoadedLanguage> + Send + Sync + 'static>,
|
||||
);
|
||||
|
||||
@ -238,14 +241,17 @@ pub trait ExtensionLanguageProxy: Send + Sync + 'static {
|
||||
impl ExtensionLanguageProxy for ExtensionHostProxy {
|
||||
fn register_language(
|
||||
&self,
|
||||
language: LanguageConfig,
|
||||
language: LanguageName,
|
||||
grammar: Option<Arc<str>>,
|
||||
matcher: LanguageMatcher,
|
||||
hidden: bool,
|
||||
load: Arc<dyn Fn() -> Result<LoadedLanguage> + Send + Sync + 'static>,
|
||||
) {
|
||||
let Some(proxy) = self.language_proxy.read().clone() else {
|
||||
return;
|
||||
};
|
||||
|
||||
proxy.register_language(language, load)
|
||||
proxy.register_language(language, grammar, matcher, hidden, load)
|
||||
}
|
||||
|
||||
fn remove_languages(
|
||||
|
@ -34,7 +34,8 @@ use gpui::{
|
||||
};
|
||||
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
|
||||
use language::{
|
||||
LanguageConfig, LanguageName, LanguageQueries, LoadedLanguage, QUERY_FILENAME_PREFIXES, Rope,
|
||||
LanguageConfig, LanguageMatcher, LanguageName, LanguageQueries, LoadedLanguage,
|
||||
QUERY_FILENAME_PREFIXES, Rope,
|
||||
};
|
||||
use node_runtime::NodeRuntime;
|
||||
use project::ContextProviderWithTasks;
|
||||
@ -139,7 +140,7 @@ struct GlobalExtensionStore(Entity<ExtensionStore>);
|
||||
|
||||
impl Global for GlobalExtensionStore {}
|
||||
|
||||
#[derive(Deserialize, Serialize, Default)]
|
||||
#[derive(Debug, Deserialize, Serialize, Default, PartialEq, Eq)]
|
||||
pub struct ExtensionIndex {
|
||||
pub extensions: BTreeMap<Arc<str>, ExtensionIndexEntry>,
|
||||
pub themes: BTreeMap<Arc<str>, ExtensionIndexThemeEntry>,
|
||||
@ -166,12 +167,13 @@ pub struct ExtensionIndexIconThemeEntry {
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Deserialize, Serialize)]
|
||||
pub struct ExtensionIndexLanguageEntry {
|
||||
pub extension: Arc<str>,
|
||||
pub path: PathBuf,
|
||||
#[serde(skip)]
|
||||
pub config: LanguageConfig,
|
||||
pub matcher: LanguageMatcher,
|
||||
pub hidden: bool,
|
||||
pub grammar: Option<Arc<str>>,
|
||||
}
|
||||
|
||||
actions!(zed, [ReloadExtensions]);
|
||||
@ -1181,8 +1183,44 @@ impl ExtensionStore {
|
||||
}
|
||||
|
||||
self.proxy.register_grammars(grammars_to_add);
|
||||
let languages_to_add = new_index
|
||||
.languages
|
||||
.iter_mut()
|
||||
.filter(|(_, entry)| extensions_to_load.contains(&entry.extension))
|
||||
.collect::<Vec<_>>();
|
||||
for (language_name, language) in languages_to_add {
|
||||
let mut language_path = self.installed_dir.clone();
|
||||
language_path.extend([
|
||||
Path::new(language.extension.as_ref()),
|
||||
language.path.as_path(),
|
||||
]);
|
||||
self.proxy.register_language(
|
||||
language_name.clone(),
|
||||
language.grammar.clone(),
|
||||
language.matcher.clone(),
|
||||
language.hidden,
|
||||
Arc::new(move || {
|
||||
let config = std::fs::read_to_string(language_path.join("config.toml"))?;
|
||||
let config: LanguageConfig = ::toml::from_str(&config)?;
|
||||
let queries = load_plugin_queries(&language_path);
|
||||
let context_provider =
|
||||
std::fs::read_to_string(language_path.join("tasks.json"))
|
||||
.ok()
|
||||
.and_then(|contents| {
|
||||
let definitions =
|
||||
serde_json_lenient::from_str(&contents).log_err()?;
|
||||
Some(Arc::new(ContextProviderWithTasks::new(definitions)) as Arc<_>)
|
||||
});
|
||||
|
||||
let installed_dir = self.installed_dir.clone();
|
||||
Ok(LoadedLanguage {
|
||||
config,
|
||||
queries,
|
||||
context_provider,
|
||||
toolchain_provider: None,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
let fs = self.fs.clone();
|
||||
let wasm_host = self.wasm_host.clone();
|
||||
@ -1192,60 +1230,11 @@ impl ExtensionStore {
|
||||
.iter()
|
||||
.filter_map(|name| new_index.extensions.get(name).cloned())
|
||||
.collect::<Vec<_>>();
|
||||
self.extension_index = new_index;
|
||||
cx.notify();
|
||||
cx.emit(Event::ExtensionsUpdated);
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
let languages_to_add = new_index
|
||||
.languages
|
||||
.iter_mut()
|
||||
.filter(|(_, entry)| extensions_to_load.contains(&entry.extension))
|
||||
.collect::<Vec<_>>();
|
||||
for (_, language) in languages_to_add {
|
||||
let mut language_path = installed_dir.clone();
|
||||
language_path.extend([
|
||||
Path::new(language.extension.as_ref()),
|
||||
language.path.as_path(),
|
||||
]);
|
||||
let Some(config) = fs.load(&language_path.join("config.toml")).await.ok() else {
|
||||
log::error!("Could not load config.toml in {:?}", language_path);
|
||||
continue;
|
||||
};
|
||||
let Some(config) = ::toml::from_str::<LanguageConfig>(&config).ok() else {
|
||||
log::error!(
|
||||
"Could not parse language config.toml in {:?}",
|
||||
language_path
|
||||
);
|
||||
continue;
|
||||
};
|
||||
language.config = config.clone();
|
||||
proxy.register_language(
|
||||
language.config.clone(),
|
||||
Arc::new(move || {
|
||||
let queries = load_plugin_queries(&language_path);
|
||||
let context_provider =
|
||||
std::fs::read_to_string(language_path.join("tasks.json"))
|
||||
.ok()
|
||||
.and_then(|contents| {
|
||||
let definitions =
|
||||
serde_json_lenient::from_str(&contents).log_err()?;
|
||||
Some(Arc::new(ContextProviderWithTasks::new(definitions))
|
||||
as Arc<_>)
|
||||
});
|
||||
|
||||
Ok(LoadedLanguage {
|
||||
config: config.clone(),
|
||||
queries,
|
||||
context_provider,
|
||||
toolchain_provider: None,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
this.update(cx, |this, cx| {
|
||||
this.extension_index = new_index;
|
||||
cx.notify();
|
||||
cx.emit(Event::ExtensionsUpdated);
|
||||
})
|
||||
.ok();
|
||||
cx.background_spawn({
|
||||
let fs = fs.clone();
|
||||
async move {
|
||||
@ -1448,7 +1437,9 @@ impl ExtensionStore {
|
||||
ExtensionIndexLanguageEntry {
|
||||
extension: extension_id.clone(),
|
||||
path: relative_path,
|
||||
config,
|
||||
matcher: config.matcher,
|
||||
hidden: config.hidden,
|
||||
grammar: config.grammar,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use fs::{FakeFs, Fs, RealFs};
|
||||
use futures::{AsyncReadExt, StreamExt, io::BufReader};
|
||||
use gpui::{AppContext as _, SemanticVersion, SharedString, TestAppContext};
|
||||
use http_client::{FakeHttpClient, Response};
|
||||
use language::{BinaryStatus, LanguageConfig, LanguageMatcher, LanguageRegistry};
|
||||
use language::{BinaryStatus, LanguageMatcher, LanguageRegistry};
|
||||
use lsp::LanguageServerName;
|
||||
use node_runtime::NodeRuntime;
|
||||
use parking_lot::Mutex;
|
||||
@ -206,14 +206,11 @@ async fn test_extension_store(cx: &mut TestAppContext) {
|
||||
ExtensionIndexLanguageEntry {
|
||||
extension: "zed-ruby".into(),
|
||||
path: "languages/erb".into(),
|
||||
config: LanguageConfig {
|
||||
grammar: Some("embedded_template".into()),
|
||||
hidden: false,
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["erb".into()],
|
||||
first_line_pattern: None,
|
||||
},
|
||||
..Default::default()
|
||||
grammar: Some("embedded_template".into()),
|
||||
hidden: false,
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["erb".into()],
|
||||
first_line_pattern: None,
|
||||
},
|
||||
},
|
||||
),
|
||||
@ -222,14 +219,11 @@ async fn test_extension_store(cx: &mut TestAppContext) {
|
||||
ExtensionIndexLanguageEntry {
|
||||
extension: "zed-ruby".into(),
|
||||
path: "languages/ruby".into(),
|
||||
config: LanguageConfig {
|
||||
grammar: Some("ruby".into()),
|
||||
hidden: false,
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rb".into()],
|
||||
first_line_pattern: None,
|
||||
},
|
||||
..Default::default()
|
||||
grammar: Some("ruby".into()),
|
||||
hidden: false,
|
||||
matcher: LanguageMatcher {
|
||||
path_suffixes: vec!["rb".into()],
|
||||
first_line_pattern: None,
|
||||
},
|
||||
},
|
||||
),
|
||||
@ -301,18 +295,9 @@ async fn test_extension_store(cx: &mut TestAppContext) {
|
||||
index.languages.iter().zip(expected_index.languages.iter())
|
||||
{
|
||||
assert_eq!(actual_key, expected_key);
|
||||
assert_eq!(
|
||||
actual_language.config.grammar,
|
||||
expected_language.config.grammar
|
||||
);
|
||||
assert_eq!(
|
||||
actual_language.config.matcher,
|
||||
expected_language.config.matcher
|
||||
);
|
||||
assert_eq!(
|
||||
actual_language.config.hidden,
|
||||
expected_language.config.hidden
|
||||
);
|
||||
assert_eq!(actual_language.grammar, expected_language.grammar);
|
||||
assert_eq!(actual_language.matcher, expected_language.matcher);
|
||||
assert_eq!(actual_language.hidden, expected_language.hidden);
|
||||
}
|
||||
assert_eq!(index.themes, expected_index.themes);
|
||||
|
||||
@ -405,18 +390,9 @@ async fn test_extension_store(cx: &mut TestAppContext) {
|
||||
index.languages.iter().zip(expected_index.languages.iter())
|
||||
{
|
||||
assert_eq!(actual_key, expected_key);
|
||||
assert_eq!(
|
||||
actual_language.config.grammar,
|
||||
expected_language.config.grammar
|
||||
);
|
||||
assert_eq!(
|
||||
actual_language.config.matcher,
|
||||
expected_language.config.matcher
|
||||
);
|
||||
assert_eq!(
|
||||
actual_language.config.hidden,
|
||||
expected_language.config.hidden
|
||||
);
|
||||
assert_eq!(actual_language.grammar, expected_language.grammar);
|
||||
assert_eq!(actual_language.matcher, expected_language.matcher);
|
||||
assert_eq!(actual_language.hidden, expected_language.hidden);
|
||||
}
|
||||
|
||||
assert_eq!(index.extensions, expected_index.extensions);
|
||||
@ -470,18 +446,9 @@ async fn test_extension_store(cx: &mut TestAppContext) {
|
||||
.zip(expected_index.languages.iter())
|
||||
{
|
||||
assert_eq!(actual_key, expected_key);
|
||||
assert_eq!(
|
||||
actual_language.config.grammar,
|
||||
expected_language.config.grammar
|
||||
);
|
||||
assert_eq!(
|
||||
actual_language.config.matcher,
|
||||
expected_language.config.matcher
|
||||
);
|
||||
assert_eq!(
|
||||
actual_language.config.hidden,
|
||||
expected_language.config.hidden
|
||||
);
|
||||
assert_eq!(actual_language.grammar, expected_language.grammar);
|
||||
assert_eq!(actual_language.matcher, expected_language.matcher);
|
||||
assert_eq!(actual_language.hidden, expected_language.hidden);
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
@ -534,18 +501,9 @@ async fn test_extension_store(cx: &mut TestAppContext) {
|
||||
.zip(expected_index.languages.iter())
|
||||
{
|
||||
assert_eq!(actual_key, expected_key);
|
||||
assert_eq!(
|
||||
actual_language.config.grammar,
|
||||
expected_language.config.grammar
|
||||
);
|
||||
assert_eq!(
|
||||
actual_language.config.matcher,
|
||||
expected_language.config.matcher
|
||||
);
|
||||
assert_eq!(
|
||||
actual_language.config.hidden,
|
||||
expected_language.config.hidden
|
||||
);
|
||||
assert_eq!(actual_language.grammar, expected_language.grammar);
|
||||
assert_eq!(actual_language.matcher, expected_language.matcher);
|
||||
assert_eq!(actual_language.hidden, expected_language.hidden);
|
||||
}
|
||||
|
||||
assert_eq!(language_registry.language_names(), ["Plain Text"]);
|
||||
|
@ -149,7 +149,10 @@ impl HeadlessExtensionStore {
|
||||
config.grammar = None;
|
||||
|
||||
this.proxy.register_language(
|
||||
config.clone(),
|
||||
config.name.clone(),
|
||||
None,
|
||||
config.matcher.clone(),
|
||||
config.hidden,
|
||||
Arc::new(move || {
|
||||
Ok(LoadedLanguage {
|
||||
config: config.clone(),
|
||||
|
@ -666,7 +666,7 @@ pub struct CodeLabel {
|
||||
pub filter_range: Range<usize>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, JsonSchema, Serialize, Debug)]
|
||||
#[derive(Clone, Deserialize, JsonSchema)]
|
||||
pub struct LanguageConfig {
|
||||
/// Human-readable name of the language.
|
||||
pub name: LanguageName,
|
||||
@ -694,20 +694,12 @@ pub struct LanguageConfig {
|
||||
pub auto_indent_on_paste: Option<bool>,
|
||||
/// A regex that is used to determine whether the indentation level should be
|
||||
/// increased in the following line.
|
||||
#[serde(
|
||||
default,
|
||||
deserialize_with = "deserialize_regex",
|
||||
serialize_with = "serialize_regex"
|
||||
)]
|
||||
#[serde(default, deserialize_with = "deserialize_regex")]
|
||||
#[schemars(schema_with = "regex_json_schema")]
|
||||
pub increase_indent_pattern: Option<Regex>,
|
||||
/// A regex that is used to determine whether the indentation level should be
|
||||
/// decreased in the following line.
|
||||
#[serde(
|
||||
default,
|
||||
deserialize_with = "deserialize_regex",
|
||||
serialize_with = "serialize_regex"
|
||||
)]
|
||||
#[serde(default, deserialize_with = "deserialize_regex")]
|
||||
#[schemars(schema_with = "regex_json_schema")]
|
||||
pub decrease_indent_pattern: Option<Regex>,
|
||||
/// A list of characters that trigger the automatic insertion of a closing
|
||||
@ -762,7 +754,7 @@ pub struct LanguageConfig {
|
||||
pub completion_query_characters: HashSet<char>,
|
||||
/// A list of preferred debuggers for this language.
|
||||
#[serde(default)]
|
||||
pub debuggers: IndexSet<String>,
|
||||
pub debuggers: IndexSet<SharedString>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Default, JsonSchema)]
|
||||
@ -781,7 +773,7 @@ pub struct LanguageMatcher {
|
||||
}
|
||||
|
||||
/// The configuration for JSX tag auto-closing.
|
||||
#[derive(Clone, Deserialize, JsonSchema, Serialize, Debug)]
|
||||
#[derive(Clone, Deserialize, JsonSchema)]
|
||||
pub struct JsxTagAutoCloseConfig {
|
||||
/// The name of the node for a opening tag
|
||||
pub open_tag_node_name: String,
|
||||
@ -822,7 +814,7 @@ pub struct LanguageScope {
|
||||
override_id: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Default, Debug, JsonSchema, Serialize)]
|
||||
#[derive(Clone, Deserialize, Default, Debug, JsonSchema)]
|
||||
pub struct LanguageConfigOverride {
|
||||
#[serde(default)]
|
||||
pub line_comments: Override<Vec<Arc<str>>>,
|
||||
@ -949,7 +941,7 @@ pub struct FakeLspAdapter {
|
||||
///
|
||||
/// This struct includes settings for defining which pairs of characters are considered brackets and
|
||||
/// also specifies any language-specific scopes where these pairs should be ignored for bracket matching purposes.
|
||||
#[derive(Clone, Debug, Default, JsonSchema, Serialize)]
|
||||
#[derive(Clone, Debug, Default, JsonSchema)]
|
||||
pub struct BracketPairConfig {
|
||||
/// A list of character pairs that should be treated as brackets in the context of a given language.
|
||||
pub pairs: Vec<BracketPair>,
|
||||
@ -999,7 +991,7 @@ impl<'de> Deserialize<'de> for BracketPairConfig {
|
||||
|
||||
/// Describes a single bracket pair and how an editor should react to e.g. inserting
|
||||
/// an opening bracket or to a newline character insertion in between `start` and `end` characters.
|
||||
#[derive(Clone, Debug, Default, Deserialize, PartialEq, JsonSchema, Serialize)]
|
||||
#[derive(Clone, Debug, Default, Deserialize, PartialEq, JsonSchema)]
|
||||
pub struct BracketPair {
|
||||
/// Starting substring for a bracket.
|
||||
pub start: String,
|
||||
|
@ -145,24 +145,25 @@ pub enum BinaryStatus {
|
||||
#[derive(Clone)]
|
||||
pub struct AvailableLanguage {
|
||||
id: LanguageId,
|
||||
config: LanguageConfig,
|
||||
name: LanguageName,
|
||||
grammar: Option<Arc<str>>,
|
||||
matcher: LanguageMatcher,
|
||||
hidden: bool,
|
||||
load: Arc<dyn Fn() -> Result<LoadedLanguage> + 'static + Send + Sync>,
|
||||
loaded: bool,
|
||||
}
|
||||
|
||||
impl AvailableLanguage {
|
||||
pub fn name(&self) -> LanguageName {
|
||||
self.config.name.clone()
|
||||
self.name.clone()
|
||||
}
|
||||
|
||||
pub fn matcher(&self) -> &LanguageMatcher {
|
||||
&self.config.matcher
|
||||
&self.matcher
|
||||
}
|
||||
|
||||
pub fn hidden(&self) -> bool {
|
||||
self.config.hidden
|
||||
}
|
||||
pub fn config(&self) -> &LanguageConfig {
|
||||
&self.config
|
||||
self.hidden
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,7 +327,10 @@ impl LanguageRegistry {
|
||||
#[cfg(any(feature = "test-support", test))]
|
||||
pub fn register_test_language(&self, config: LanguageConfig) {
|
||||
self.register_language(
|
||||
config.clone(),
|
||||
config.name.clone(),
|
||||
config.grammar.clone(),
|
||||
config.matcher.clone(),
|
||||
config.hidden,
|
||||
Arc::new(move || {
|
||||
Ok(LoadedLanguage {
|
||||
config: config.clone(),
|
||||
@ -485,14 +489,18 @@ impl LanguageRegistry {
|
||||
/// Adds a language to the registry, which can be loaded if needed.
|
||||
pub fn register_language(
|
||||
&self,
|
||||
config: LanguageConfig,
|
||||
name: LanguageName,
|
||||
grammar_name: Option<Arc<str>>,
|
||||
matcher: LanguageMatcher,
|
||||
hidden: bool,
|
||||
load: Arc<dyn Fn() -> Result<LoadedLanguage> + 'static + Send + Sync>,
|
||||
) {
|
||||
let state = &mut *self.state.write();
|
||||
|
||||
for existing_language in &mut state.available_languages {
|
||||
if existing_language.config.name == config.name {
|
||||
existing_language.config = config;
|
||||
if existing_language.name == name {
|
||||
existing_language.grammar = grammar_name;
|
||||
existing_language.matcher = matcher;
|
||||
existing_language.load = load;
|
||||
return;
|
||||
}
|
||||
@ -500,8 +508,11 @@ impl LanguageRegistry {
|
||||
|
||||
state.available_languages.push(AvailableLanguage {
|
||||
id: LanguageId::new(),
|
||||
config,
|
||||
name,
|
||||
grammar: grammar_name,
|
||||
matcher,
|
||||
load,
|
||||
hidden,
|
||||
loaded: false,
|
||||
});
|
||||
state.version += 1;
|
||||
@ -547,7 +558,7 @@ impl LanguageRegistry {
|
||||
let mut result = state
|
||||
.available_languages
|
||||
.iter()
|
||||
.filter_map(|l| l.loaded.not().then_some(l.config.name.to_string()))
|
||||
.filter_map(|l| l.loaded.not().then_some(l.name.to_string()))
|
||||
.chain(state.languages.iter().map(|l| l.config.name.to_string()))
|
||||
.collect::<Vec<_>>();
|
||||
result.sort_unstable_by_key(|language_name| language_name.to_lowercase());
|
||||
@ -566,7 +577,10 @@ impl LanguageRegistry {
|
||||
let mut state = self.state.write();
|
||||
state.available_languages.push(AvailableLanguage {
|
||||
id: language.id,
|
||||
config: language.config.clone(),
|
||||
name: language.name(),
|
||||
grammar: language.config.grammar.clone(),
|
||||
matcher: language.config.matcher.clone(),
|
||||
hidden: language.config.hidden,
|
||||
load: Arc::new(|| Err(anyhow!("already loaded"))),
|
||||
loaded: true,
|
||||
});
|
||||
@ -635,7 +649,7 @@ impl LanguageRegistry {
|
||||
state
|
||||
.available_languages
|
||||
.iter()
|
||||
.find(|l| l.config.name.0.as_ref() == name)
|
||||
.find(|l| l.name.0.as_ref() == name)
|
||||
.cloned()
|
||||
}
|
||||
|
||||
@ -752,11 +766,8 @@ impl LanguageRegistry {
|
||||
let current_match_type = best_language_match
|
||||
.as_ref()
|
||||
.map_or(LanguageMatchPrecedence::default(), |(_, score)| *score);
|
||||
let language_score = callback(
|
||||
&language.config.name,
|
||||
&language.config.matcher,
|
||||
current_match_type,
|
||||
);
|
||||
let language_score =
|
||||
callback(&language.name, &language.matcher, current_match_type);
|
||||
debug_assert!(
|
||||
language_score.is_none_or(|new_score| new_score > current_match_type),
|
||||
"Matching callback should only return a better match than the current one"
|
||||
@ -804,7 +815,7 @@ impl LanguageRegistry {
|
||||
let this = self.clone();
|
||||
|
||||
let id = language.id;
|
||||
let name = language.config.name.clone();
|
||||
let name = language.name.clone();
|
||||
let language_load = language.load.clone();
|
||||
|
||||
self.executor
|
||||
@ -1120,7 +1131,7 @@ impl LanguageRegistryState {
|
||||
self.languages
|
||||
.retain(|language| !languages_to_remove.contains(&language.name()));
|
||||
self.available_languages
|
||||
.retain(|language| !languages_to_remove.contains(&language.config.name));
|
||||
.retain(|language| !languages_to_remove.contains(&language.name));
|
||||
self.grammars
|
||||
.retain(|name, _| !grammars_to_remove.contains(name));
|
||||
self.version += 1;
|
||||
|
@ -5,7 +5,7 @@ use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
use extension::{ExtensionGrammarProxy, ExtensionHostProxy, ExtensionLanguageProxy};
|
||||
use language::{LanguageConfig, LanguageName, LanguageRegistry, LoadedLanguage};
|
||||
use language::{LanguageMatcher, LanguageName, LanguageRegistry, LoadedLanguage};
|
||||
|
||||
pub fn init(
|
||||
extension_host_proxy: Arc<ExtensionHostProxy>,
|
||||
@ -31,10 +31,14 @@ impl ExtensionGrammarProxy for LanguageServerRegistryProxy {
|
||||
impl ExtensionLanguageProxy for LanguageServerRegistryProxy {
|
||||
fn register_language(
|
||||
&self,
|
||||
language: LanguageConfig,
|
||||
language: LanguageName,
|
||||
grammar: Option<Arc<str>>,
|
||||
matcher: LanguageMatcher,
|
||||
hidden: bool,
|
||||
load: Arc<dyn Fn() -> Result<LoadedLanguage> + Send + Sync + 'static>,
|
||||
) {
|
||||
self.language_registry.register_language(language, load);
|
||||
self.language_registry
|
||||
.register_language(language, grammar, matcher, hidden, load);
|
||||
}
|
||||
|
||||
fn remove_languages(
|
||||
|
@ -325,7 +325,10 @@ fn register_language(
|
||||
languages.register_lsp_adapter(config.name.clone(), adapter);
|
||||
}
|
||||
languages.register_language(
|
||||
config.clone(),
|
||||
config.name.clone(),
|
||||
config.grammar.clone(),
|
||||
config.matcher.clone(),
|
||||
config.hidden,
|
||||
Arc::new(move || {
|
||||
Ok(LoadedLanguage {
|
||||
config: config.clone(),
|
||||
|
Loading…
Reference in New Issue
Block a user