1use crate::{
2 language_settings::{
3 all_language_settings, AllLanguageSettingsContent, LanguageSettingsContent,
4 },
5 task_context::ContextProvider,
6 with_parser, CachedLspAdapter, File, Language, LanguageConfig, LanguageId, LanguageMatcher,
7 LanguageServerName, LspAdapter, PLAIN_TEXT,
8};
9use anyhow::{anyhow, Context, Result};
10use collections::{hash_map, HashMap, HashSet};
11
12use futures::{
13 channel::{mpsc, oneshot},
14 Future,
15};
16use globset::GlobSet;
17use gpui::{AppContext, BackgroundExecutor};
18use lsp::LanguageServerId;
19use parking_lot::{Mutex, RwLock};
20use postage::watch;
21use schemars::JsonSchema;
22use serde::{Deserialize, Serialize};
23use std::{
24 borrow::{Borrow, Cow},
25 ffi::OsStr,
26 ops::Not,
27 path::{Path, PathBuf},
28 sync::Arc,
29};
30use sum_tree::Bias;
31use text::{Point, Rope};
32use theme::Theme;
33use unicase::UniCase;
34use util::{maybe, paths::PathExt, post_inc, ResultExt};
35
36#[derive(
37 Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
38)]
39pub struct LanguageName(pub Arc<str>);
40
41impl LanguageName {
42 pub fn new(s: &str) -> Self {
43 Self(Arc::from(s))
44 }
45
46 pub fn from_proto(s: String) -> Self {
47 Self(Arc::from(s))
48 }
49 pub fn to_proto(self) -> String {
50 self.0.to_string()
51 }
52 pub fn lsp_id(&self) -> String {
53 match self.0.as_ref() {
54 "Plain Text" => "plaintext".to_string(),
55 language_name => language_name.to_lowercase(),
56 }
57 }
58}
59
60impl Borrow<str> for LanguageName {
61 fn borrow(&self) -> &str {
62 self.0.as_ref()
63 }
64}
65
66impl std::fmt::Display for LanguageName {
67 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
68 write!(f, "{}", self.0)
69 }
70}
71
72impl<'a> From<&'a str> for LanguageName {
73 fn from(str: &'a str) -> LanguageName {
74 LanguageName(str.into())
75 }
76}
77
78pub struct LanguageRegistry {
79 state: RwLock<LanguageRegistryState>,
80 language_server_download_dir: Option<Arc<Path>>,
81 executor: BackgroundExecutor,
82 lsp_binary_status_tx: LspBinaryStatusSender,
83}
84
85struct LanguageRegistryState {
86 next_language_server_id: usize,
87 languages: Vec<Arc<Language>>,
88 language_settings: AllLanguageSettingsContent,
89 available_languages: Vec<AvailableLanguage>,
90 grammars: HashMap<Arc<str>, AvailableGrammar>,
91 lsp_adapters: HashMap<LanguageName, Vec<Arc<CachedLspAdapter>>>,
92 available_lsp_adapters:
93 HashMap<LanguageServerName, Arc<dyn Fn() -> Arc<CachedLspAdapter> + 'static + Send + Sync>>,
94 loading_languages: HashMap<LanguageId, Vec<oneshot::Sender<Result<Arc<Language>>>>>,
95 subscription: (watch::Sender<()>, watch::Receiver<()>),
96 theme: Option<Arc<Theme>>,
97 version: usize,
98 reload_count: usize,
99
100 #[cfg(any(test, feature = "test-support"))]
101 fake_server_entries: HashMap<LanguageServerName, FakeLanguageServerEntry>,
102}
103
104#[cfg(any(test, feature = "test-support"))]
105pub struct FakeLanguageServerEntry {
106 pub capabilities: lsp::ServerCapabilities,
107 pub initializer: Option<Box<dyn 'static + Send + Sync + Fn(&mut lsp::FakeLanguageServer)>>,
108 pub tx: futures::channel::mpsc::UnboundedSender<lsp::FakeLanguageServer>,
109 pub _server: Option<lsp::FakeLanguageServer>,
110}
111
112#[derive(Clone, Debug, PartialEq, Eq)]
113pub enum LanguageServerBinaryStatus {
114 None,
115 CheckingForUpdate,
116 Downloading,
117 Failed { error: String },
118}
119
120#[derive(Clone)]
121pub struct AvailableLanguage {
122 id: LanguageId,
123 name: LanguageName,
124 grammar: Option<Arc<str>>,
125 matcher: LanguageMatcher,
126 load: Arc<
127 dyn Fn() -> Result<(
128 LanguageConfig,
129 LanguageQueries,
130 Option<Arc<dyn ContextProvider>>,
131 )>
132 + 'static
133 + Send
134 + Sync,
135 >,
136 loaded: bool,
137}
138
139impl AvailableLanguage {
140 pub fn name(&self) -> LanguageName {
141 self.name.clone()
142 }
143
144 pub fn matcher(&self) -> &LanguageMatcher {
145 &self.matcher
146 }
147}
148
149enum AvailableGrammar {
150 Native(tree_sitter::Language),
151 Loaded(#[allow(unused)] PathBuf, tree_sitter::Language),
152 Loading(
153 #[allow(unused)] PathBuf,
154 Vec<oneshot::Sender<Result<tree_sitter::Language, Arc<anyhow::Error>>>>,
155 ),
156 Unloaded(PathBuf),
157 LoadFailed(Arc<anyhow::Error>),
158}
159
160#[derive(Debug)]
161pub struct LanguageNotFound;
162
163impl std::fmt::Display for LanguageNotFound {
164 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165 write!(f, "language not found")
166 }
167}
168
169pub const QUERY_FILENAME_PREFIXES: &[(
170 &str,
171 fn(&mut LanguageQueries) -> &mut Option<Cow<'static, str>>,
172)] = &[
173 ("highlights", |q| &mut q.highlights),
174 ("brackets", |q| &mut q.brackets),
175 ("outline", |q| &mut q.outline),
176 ("indents", |q| &mut q.indents),
177 ("embedding", |q| &mut q.embedding),
178 ("injections", |q| &mut q.injections),
179 ("overrides", |q| &mut q.overrides),
180 ("redactions", |q| &mut q.redactions),
181 ("runnables", |q| &mut q.runnables),
182];
183
184/// Tree-sitter language queries for a given language.
185#[derive(Debug, Default)]
186pub struct LanguageQueries {
187 pub highlights: Option<Cow<'static, str>>,
188 pub brackets: Option<Cow<'static, str>>,
189 pub indents: Option<Cow<'static, str>>,
190 pub outline: Option<Cow<'static, str>>,
191 pub embedding: Option<Cow<'static, str>>,
192 pub injections: Option<Cow<'static, str>>,
193 pub overrides: Option<Cow<'static, str>>,
194 pub redactions: Option<Cow<'static, str>>,
195 pub runnables: Option<Cow<'static, str>>,
196}
197
198#[derive(Clone, Default)]
199struct LspBinaryStatusSender {
200 txs: Arc<Mutex<Vec<mpsc::UnboundedSender<(LanguageServerName, LanguageServerBinaryStatus)>>>>,
201}
202
203impl LanguageRegistry {
204 pub fn new(executor: BackgroundExecutor) -> Self {
205 let this = Self {
206 state: RwLock::new(LanguageRegistryState {
207 next_language_server_id: 0,
208 languages: Vec::new(),
209 available_languages: Vec::new(),
210 grammars: Default::default(),
211 language_settings: Default::default(),
212 loading_languages: Default::default(),
213 lsp_adapters: Default::default(),
214 available_lsp_adapters: HashMap::default(),
215 subscription: watch::channel(),
216 theme: Default::default(),
217 version: 0,
218 reload_count: 0,
219
220 #[cfg(any(test, feature = "test-support"))]
221 fake_server_entries: Default::default(),
222 }),
223 language_server_download_dir: None,
224 lsp_binary_status_tx: Default::default(),
225 executor,
226 };
227 this.add(PLAIN_TEXT.clone());
228 this
229 }
230
231 #[cfg(any(test, feature = "test-support"))]
232 pub fn test(executor: BackgroundExecutor) -> Self {
233 let mut this = Self::new(executor);
234 this.language_server_download_dir = Some(Path::new("/the-download-dir").into());
235 this
236 }
237
238 /// Clears out all of the loaded languages and reload them from scratch.
239 pub fn reload(&self) {
240 self.state.write().reload();
241 }
242
243 /// Reorders the list of language servers for the given language.
244 ///
245 /// Uses the provided list of ordered [`CachedLspAdapters`] as the desired order.
246 ///
247 /// Any existing language servers not present in `ordered_lsp_adapters` will be
248 /// appended to the end.
249 pub fn reorder_language_servers(
250 &self,
251 language: &LanguageName,
252 ordered_lsp_adapters: Vec<Arc<CachedLspAdapter>>,
253 ) {
254 self.state
255 .write()
256 .reorder_language_servers(language, ordered_lsp_adapters);
257 }
258
259 /// Removes the specified languages and grammars from the registry.
260 pub fn remove_languages(
261 &self,
262 languages_to_remove: &[LanguageName],
263 grammars_to_remove: &[Arc<str>],
264 ) {
265 self.state
266 .write()
267 .remove_languages(languages_to_remove, grammars_to_remove)
268 }
269
270 pub fn remove_lsp_adapter(&self, language_name: &LanguageName, name: &LanguageServerName) {
271 let mut state = self.state.write();
272 if let Some(adapters) = state.lsp_adapters.get_mut(language_name) {
273 adapters.retain(|adapter| &adapter.name != name)
274 }
275 state.version += 1;
276 state.reload_count += 1;
277 *state.subscription.0.borrow_mut() = ();
278 }
279
280 #[cfg(any(feature = "test-support", test))]
281 pub fn register_test_language(&self, config: LanguageConfig) {
282 self.register_language(
283 config.name.clone(),
284 config.grammar.clone(),
285 config.matcher.clone(),
286 move || Ok((config.clone(), Default::default(), None)),
287 )
288 }
289
290 /// Registers an available language server adapter.
291 ///
292 /// The language server is registered under the language server name, but
293 /// not bound to a particular language.
294 ///
295 /// When a language wants to load this particular language server, it will
296 /// invoke the `load` function.
297 pub fn register_available_lsp_adapter(
298 &self,
299 name: LanguageServerName,
300 load: impl Fn() -> Arc<dyn LspAdapter> + 'static + Send + Sync,
301 ) {
302 self.state.write().available_lsp_adapters.insert(
303 name,
304 Arc::new(move || {
305 let lsp_adapter = load();
306 CachedLspAdapter::new(lsp_adapter)
307 }),
308 );
309 }
310
311 /// Loads the language server adapter for the language server with the given name.
312 pub fn load_available_lsp_adapter(
313 &self,
314 name: &LanguageServerName,
315 ) -> Option<Arc<CachedLspAdapter>> {
316 let state = self.state.read();
317 let load_lsp_adapter = state.available_lsp_adapters.get(name)?;
318
319 Some(load_lsp_adapter())
320 }
321
322 pub fn register_lsp_adapter(
323 &self,
324 language_name: LanguageName,
325 adapter: Arc<dyn LspAdapter>,
326 ) -> Arc<CachedLspAdapter> {
327 let cached = CachedLspAdapter::new(adapter);
328 self.state
329 .write()
330 .lsp_adapters
331 .entry(language_name)
332 .or_default()
333 .push(cached.clone());
334 cached
335 }
336
337 pub fn get_or_register_lsp_adapter(
338 &self,
339 language_name: LanguageName,
340 server_name: LanguageServerName,
341 build_adapter: impl FnOnce() -> Arc<dyn LspAdapter> + 'static,
342 ) -> Arc<CachedLspAdapter> {
343 let registered = self
344 .state
345 .write()
346 .lsp_adapters
347 .entry(language_name.clone())
348 .or_default()
349 .iter()
350 .find(|cached_adapter| cached_adapter.name == server_name)
351 .cloned();
352
353 if let Some(found) = registered {
354 found
355 } else {
356 let adapter = build_adapter();
357 self.register_lsp_adapter(language_name, adapter)
358 }
359 }
360
361 /// Register a fake language server and adapter
362 /// The returned channel receives a new instance of the language server every time it is started
363 #[cfg(any(feature = "test-support", test))]
364 pub fn register_fake_lsp(
365 &self,
366 language_name: impl Into<LanguageName>,
367 mut adapter: crate::FakeLspAdapter,
368 ) -> futures::channel::mpsc::UnboundedReceiver<lsp::FakeLanguageServer> {
369 let language_name = language_name.into();
370 let adapter_name = LanguageServerName(adapter.name.into());
371 let capabilities = adapter.capabilities.clone();
372 let initializer = adapter.initializer.take();
373 self.state
374 .write()
375 .lsp_adapters
376 .entry(language_name.clone())
377 .or_default()
378 .push(CachedLspAdapter::new(Arc::new(adapter)));
379 self.register_fake_language_server(adapter_name, capabilities, initializer)
380 }
381
382 /// Register a fake lsp adapter (without the language server)
383 /// The returned channel receives a new instance of the language server every time it is started
384 #[cfg(any(feature = "test-support", test))]
385 pub fn register_fake_lsp_adapter(
386 &self,
387 language_name: impl Into<LanguageName>,
388 adapter: crate::FakeLspAdapter,
389 ) {
390 let language_name = language_name.into();
391 self.state
392 .write()
393 .lsp_adapters
394 .entry(language_name.clone())
395 .or_default()
396 .push(CachedLspAdapter::new(Arc::new(adapter)));
397 }
398
399 /// Register a fake language server (without the adapter)
400 /// The returned channel receives a new instance of the language server every time it is started
401 #[cfg(any(feature = "test-support", test))]
402 pub fn register_fake_language_server(
403 &self,
404 lsp_name: LanguageServerName,
405 capabilities: lsp::ServerCapabilities,
406 initializer: Option<Box<dyn Fn(&mut lsp::FakeLanguageServer) + Send + Sync>>,
407 ) -> futures::channel::mpsc::UnboundedReceiver<lsp::FakeLanguageServer> {
408 let (servers_tx, servers_rx) = futures::channel::mpsc::unbounded();
409 self.state.write().fake_server_entries.insert(
410 lsp_name,
411 FakeLanguageServerEntry {
412 tx: servers_tx,
413 capabilities,
414 initializer,
415 _server: None,
416 },
417 );
418 servers_rx
419 }
420
421 /// Adds a language to the registry, which can be loaded if needed.
422 pub fn register_language(
423 &self,
424 name: LanguageName,
425 grammar_name: Option<Arc<str>>,
426 matcher: LanguageMatcher,
427 load: impl Fn() -> Result<(
428 LanguageConfig,
429 LanguageQueries,
430 Option<Arc<dyn ContextProvider>>,
431 )>
432 + 'static
433 + Send
434 + Sync,
435 ) {
436 let load = Arc::new(load);
437 let state = &mut *self.state.write();
438
439 for existing_language in &mut state.available_languages {
440 if existing_language.name == name {
441 existing_language.grammar = grammar_name;
442 existing_language.matcher = matcher;
443 existing_language.load = load;
444 return;
445 }
446 }
447
448 state.available_languages.push(AvailableLanguage {
449 id: LanguageId::new(),
450 name,
451 grammar: grammar_name,
452 matcher,
453 load,
454 loaded: false,
455 });
456 state.version += 1;
457 state.reload_count += 1;
458 *state.subscription.0.borrow_mut() = ();
459 }
460
461 /// Adds grammars to the registry. Language configurations reference a grammar by name. The
462 /// grammar controls how the source code is parsed.
463 pub fn register_native_grammars(
464 &self,
465 grammars: impl IntoIterator<Item = (impl Into<Arc<str>>, impl Into<tree_sitter::Language>)>,
466 ) {
467 self.state.write().grammars.extend(
468 grammars
469 .into_iter()
470 .map(|(name, grammar)| (name.into(), AvailableGrammar::Native(grammar.into()))),
471 );
472 }
473
474 /// Adds paths to WASM grammar files, which can be loaded if needed.
475 pub fn register_wasm_grammars(
476 &self,
477 grammars: impl IntoIterator<Item = (impl Into<Arc<str>>, PathBuf)>,
478 ) {
479 let mut state = self.state.write();
480 state.grammars.extend(
481 grammars
482 .into_iter()
483 .map(|(name, path)| (name.into(), AvailableGrammar::Unloaded(path))),
484 );
485 state.version += 1;
486 state.reload_count += 1;
487 *state.subscription.0.borrow_mut() = ();
488 }
489
490 pub fn language_settings(&self) -> AllLanguageSettingsContent {
491 self.state.read().language_settings.clone()
492 }
493
494 pub fn language_names(&self) -> Vec<String> {
495 let state = self.state.read();
496 let mut result = state
497 .available_languages
498 .iter()
499 .filter_map(|l| l.loaded.not().then_some(l.name.to_string()))
500 .chain(state.languages.iter().map(|l| l.config.name.to_string()))
501 .collect::<Vec<_>>();
502 result.sort_unstable_by_key(|language_name| language_name.to_lowercase());
503 result
504 }
505
506 pub fn grammar_names(&self) -> Vec<Arc<str>> {
507 let state = self.state.read();
508 let mut result = state.grammars.keys().cloned().collect::<Vec<_>>();
509 result.sort_unstable_by_key(|grammar_name| grammar_name.to_lowercase());
510 result
511 }
512
513 /// Add a pre-loaded language to the registry.
514 pub fn add(&self, language: Arc<Language>) {
515 let mut state = self.state.write();
516 state.available_languages.push(AvailableLanguage {
517 id: language.id,
518 name: language.name(),
519 grammar: language.config.grammar.clone(),
520 matcher: language.config.matcher.clone(),
521 load: Arc::new(|| Err(anyhow!("already loaded"))),
522 loaded: true,
523 });
524 state.add(language);
525 }
526
527 pub fn subscribe(&self) -> watch::Receiver<()> {
528 self.state.read().subscription.1.clone()
529 }
530
531 /// Returns the number of times that the registry has been changed,
532 /// by adding languages or reloading.
533 pub fn version(&self) -> usize {
534 self.state.read().version
535 }
536
537 /// Returns the number of times that the registry has been reloaded.
538 pub fn reload_count(&self) -> usize {
539 self.state.read().reload_count
540 }
541
542 pub fn set_theme(&self, theme: Arc<Theme>) {
543 let mut state = self.state.write();
544 state.theme = Some(theme.clone());
545 for language in &state.languages {
546 language.set_theme(theme.syntax());
547 }
548 }
549
550 pub fn set_language_server_download_dir(&mut self, path: impl Into<Arc<Path>>) {
551 self.language_server_download_dir = Some(path.into());
552 }
553
554 pub fn language_for_name(
555 self: &Arc<Self>,
556 name: &str,
557 ) -> impl Future<Output = Result<Arc<Language>>> {
558 let name = UniCase::new(name);
559 let rx = self.get_or_load_language(|language_name, _| {
560 if UniCase::new(&language_name.0) == name {
561 1
562 } else {
563 0
564 }
565 });
566 async move { rx.await? }
567 }
568
569 pub fn language_for_name_or_extension(
570 self: &Arc<Self>,
571 string: &str,
572 ) -> impl Future<Output = Result<Arc<Language>>> {
573 let string = UniCase::new(string);
574 let rx = self.get_or_load_language(|name, config| {
575 if UniCase::new(&name.0) == string
576 || config
577 .path_suffixes
578 .iter()
579 .any(|suffix| UniCase::new(suffix) == string)
580 {
581 1
582 } else {
583 0
584 }
585 });
586 async move { rx.await? }
587 }
588
589 pub fn available_language_for_name(
590 self: &Arc<Self>,
591 name: &LanguageName,
592 ) -> Option<AvailableLanguage> {
593 let state = self.state.read();
594 state
595 .available_languages
596 .iter()
597 .find(|l| &l.name == name)
598 .cloned()
599 }
600
601 pub fn language_for_file(
602 self: &Arc<Self>,
603 file: &Arc<dyn File>,
604 content: Option<&Rope>,
605 cx: &AppContext,
606 ) -> Option<AvailableLanguage> {
607 let user_file_types = all_language_settings(Some(file), cx);
608
609 self.language_for_file_internal(
610 &file.full_path(cx),
611 content,
612 Some(&user_file_types.file_types),
613 )
614 }
615
616 pub fn language_for_file_path<'a>(
617 self: &Arc<Self>,
618 path: &'a Path,
619 ) -> impl Future<Output = Result<Arc<Language>>> + 'a {
620 let available_language = self.language_for_file_internal(path, None, None);
621
622 let this = self.clone();
623 async move {
624 if let Some(language) = available_language {
625 this.load_language(&language).await?
626 } else {
627 Err(anyhow!(LanguageNotFound))
628 }
629 }
630 }
631
632 fn language_for_file_internal(
633 self: &Arc<Self>,
634 path: &Path,
635 content: Option<&Rope>,
636 user_file_types: Option<&HashMap<Arc<str>, GlobSet>>,
637 ) -> Option<AvailableLanguage> {
638 let filename = path.file_name().and_then(|name| name.to_str());
639 let extension = path.extension_or_hidden_file_name();
640 let path_suffixes = [extension, filename, path.to_str()];
641 let empty = GlobSet::empty();
642
643 self.find_matching_language(move |language_name, config| {
644 let path_matches_default_suffix = config
645 .path_suffixes
646 .iter()
647 .any(|suffix| path_suffixes.contains(&Some(suffix.as_str())));
648 let custom_suffixes = user_file_types
649 .and_then(|types| types.get(&language_name.0))
650 .unwrap_or(&empty);
651 let path_matches_custom_suffix = path_suffixes
652 .iter()
653 .map(|suffix| suffix.unwrap_or(""))
654 .any(|suffix| custom_suffixes.is_match(suffix));
655 let content_matches = content.zip(config.first_line_pattern.as_ref()).map_or(
656 false,
657 |(content, pattern)| {
658 let end = content.clip_point(Point::new(0, 256), Bias::Left);
659 let end = content.point_to_offset(end);
660 let text = content.chunks_in_range(0..end).collect::<String>();
661 pattern.is_match(&text)
662 },
663 );
664 if path_matches_custom_suffix {
665 2
666 } else if path_matches_default_suffix || content_matches {
667 1
668 } else {
669 0
670 }
671 })
672 }
673
674 fn find_matching_language(
675 self: &Arc<Self>,
676 callback: impl Fn(&LanguageName, &LanguageMatcher) -> usize,
677 ) -> Option<AvailableLanguage> {
678 let state = self.state.read();
679 let available_language = state
680 .available_languages
681 .iter()
682 .filter_map(|language| {
683 let score = callback(&language.name, &language.matcher);
684 if score > 0 {
685 Some((language.clone(), score))
686 } else {
687 None
688 }
689 })
690 .max_by_key(|e| e.1)
691 .clone()
692 .map(|(available_language, _)| available_language);
693 drop(state);
694 available_language
695 }
696
697 pub fn load_language(
698 self: &Arc<Self>,
699 language: &AvailableLanguage,
700 ) -> oneshot::Receiver<Result<Arc<Language>>> {
701 let (tx, rx) = oneshot::channel();
702
703 let mut state = self.state.write();
704
705 // If the language is already loaded, resolve with it immediately.
706 for loaded_language in state.languages.iter() {
707 if loaded_language.id == language.id {
708 tx.send(Ok(loaded_language.clone())).unwrap();
709 return rx;
710 }
711 }
712
713 match state.loading_languages.entry(language.id) {
714 // If the language is already being loaded, then add this
715 // channel to a list that will be sent to when the load completes.
716 hash_map::Entry::Occupied(mut entry) => entry.get_mut().push(tx),
717
718 // Otherwise, start loading the language.
719 hash_map::Entry::Vacant(entry) => {
720 let this = self.clone();
721
722 let id = language.id;
723 let name = language.name.clone();
724 let language_load = language.load.clone();
725
726 self.executor
727 .spawn(async move {
728 let language = async {
729 let (config, queries, provider) = (language_load)()?;
730
731 if let Some(grammar) = config.grammar.clone() {
732 let grammar = Some(this.get_or_load_grammar(grammar).await?);
733 Language::new_with_id(id, config, grammar)
734 .with_context_provider(provider)
735 .with_queries(queries)
736 } else {
737 Ok(Language::new_with_id(id, config, None)
738 .with_context_provider(provider))
739 }
740 }
741 .await;
742
743 match language {
744 Ok(language) => {
745 let language = Arc::new(language);
746 let mut state = this.state.write();
747
748 state.add(language.clone());
749 state.mark_language_loaded(id);
750 if let Some(mut txs) = state.loading_languages.remove(&id) {
751 for tx in txs.drain(..) {
752 let _ = tx.send(Ok(language.clone()));
753 }
754 }
755 }
756 Err(e) => {
757 log::error!("failed to load language {name}:\n{:?}", e);
758 let mut state = this.state.write();
759 state.mark_language_loaded(id);
760 if let Some(mut txs) = state.loading_languages.remove(&id) {
761 for tx in txs.drain(..) {
762 let _ = tx.send(Err(anyhow!(
763 "failed to load language {}: {}",
764 name,
765 e
766 )));
767 }
768 }
769 }
770 };
771 })
772 .detach();
773
774 entry.insert(vec![tx]);
775 }
776 }
777
778 drop(state);
779 rx
780 }
781
782 fn get_or_load_language(
783 self: &Arc<Self>,
784 callback: impl Fn(&LanguageName, &LanguageMatcher) -> usize,
785 ) -> oneshot::Receiver<Result<Arc<Language>>> {
786 let Some(language) = self.find_matching_language(callback) else {
787 let (tx, rx) = oneshot::channel();
788 let _ = tx.send(Err(anyhow!(LanguageNotFound)));
789 return rx;
790 };
791
792 self.load_language(&language)
793 }
794
795 fn get_or_load_grammar(
796 self: &Arc<Self>,
797 name: Arc<str>,
798 ) -> impl Future<Output = Result<tree_sitter::Language>> {
799 let (tx, rx) = oneshot::channel();
800 let mut state = self.state.write();
801
802 if let Some(grammar) = state.grammars.get_mut(name.as_ref()) {
803 match grammar {
804 AvailableGrammar::LoadFailed(error) => {
805 tx.send(Err(error.clone())).ok();
806 }
807 AvailableGrammar::Native(grammar) | AvailableGrammar::Loaded(_, grammar) => {
808 tx.send(Ok(grammar.clone())).ok();
809 }
810 AvailableGrammar::Loading(_, txs) => {
811 txs.push(tx);
812 }
813 AvailableGrammar::Unloaded(wasm_path) => {
814 let this = self.clone();
815 let wasm_path = wasm_path.clone();
816 *grammar = AvailableGrammar::Loading(wasm_path.clone(), vec![tx]);
817 self.executor
818 .spawn(async move {
819 let grammar_result = maybe!({
820 let wasm_bytes = std::fs::read(&wasm_path)?;
821 let grammar_name = wasm_path
822 .file_stem()
823 .and_then(OsStr::to_str)
824 .ok_or_else(|| anyhow!("invalid grammar filename"))?;
825 anyhow::Ok(with_parser(|parser| {
826 let mut store = parser.take_wasm_store().unwrap();
827 let grammar = store.load_language(grammar_name, &wasm_bytes);
828 parser.set_wasm_store(store).unwrap();
829 grammar
830 })?)
831 })
832 .map_err(Arc::new);
833
834 let value = match &grammar_result {
835 Ok(grammar) => AvailableGrammar::Loaded(wasm_path, grammar.clone()),
836 Err(error) => AvailableGrammar::LoadFailed(error.clone()),
837 };
838
839 let old_value = this.state.write().grammars.insert(name, value);
840 if let Some(AvailableGrammar::Loading(_, txs)) = old_value {
841 for tx in txs {
842 tx.send(grammar_result.clone()).ok();
843 }
844 }
845 })
846 .detach();
847 }
848 }
849 } else {
850 tx.send(Err(Arc::new(anyhow!("no such grammar {}", name))))
851 .ok();
852 }
853
854 async move { rx.await?.map_err(|e| anyhow!(e)) }
855 }
856
857 pub fn to_vec(&self) -> Vec<Arc<Language>> {
858 self.state.read().languages.to_vec()
859 }
860
861 pub fn lsp_adapters(&self, language_name: &LanguageName) -> Vec<Arc<CachedLspAdapter>> {
862 self.state
863 .read()
864 .lsp_adapters
865 .get(language_name)
866 .cloned()
867 .unwrap_or_default()
868 }
869
870 pub fn update_lsp_status(
871 &self,
872 server_name: LanguageServerName,
873 status: LanguageServerBinaryStatus,
874 ) {
875 self.lsp_binary_status_tx.send(server_name, status);
876 }
877
878 pub fn next_language_server_id(&self) -> LanguageServerId {
879 self.state.write().next_language_server_id()
880 }
881
882 pub fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
883 self.language_server_download_dir
884 .as_ref()
885 .map(|dir| Arc::from(dir.join(name.0.as_ref())))
886 }
887
888 #[cfg(any(test, feature = "test-support"))]
889 pub fn create_fake_language_server(
890 &self,
891 server_id: LanguageServerId,
892 name: &LanguageServerName,
893 binary: lsp::LanguageServerBinary,
894 cx: gpui::AsyncAppContext,
895 ) -> Option<lsp::LanguageServer> {
896 let mut state = self.state.write();
897 let fake_entry = state.fake_server_entries.get_mut(&name)?;
898 let (server, mut fake_server) = lsp::FakeLanguageServer::new(
899 server_id,
900 binary,
901 name.0.to_string(),
902 fake_entry.capabilities.clone(),
903 cx.clone(),
904 );
905 fake_entry._server = Some(fake_server.clone());
906
907 if let Some(initializer) = &fake_entry.initializer {
908 initializer(&mut fake_server);
909 }
910
911 let tx = fake_entry.tx.clone();
912 cx.background_executor()
913 .spawn(async move {
914 if fake_server
915 .try_receive_notification::<lsp::notification::Initialized>()
916 .await
917 .is_some()
918 {
919 tx.unbounded_send(fake_server.clone()).ok();
920 }
921 })
922 .detach();
923
924 Some(server)
925 }
926
927 pub fn language_server_binary_statuses(
928 &self,
929 ) -> mpsc::UnboundedReceiver<(LanguageServerName, LanguageServerBinaryStatus)> {
930 self.lsp_binary_status_tx.subscribe()
931 }
932
933 pub async fn delete_server_container(&self, name: LanguageServerName) {
934 log::info!("deleting server container");
935 let Some(dir) = self.language_server_download_dir(&name) else {
936 return;
937 };
938
939 smol::fs::remove_dir_all(dir)
940 .await
941 .context("server container removal")
942 .log_err();
943 }
944}
945
946impl LanguageRegistryState {
947 fn next_language_server_id(&mut self) -> LanguageServerId {
948 LanguageServerId(post_inc(&mut self.next_language_server_id))
949 }
950
951 fn add(&mut self, language: Arc<Language>) {
952 if let Some(theme) = self.theme.as_ref() {
953 language.set_theme(theme.syntax());
954 }
955 self.language_settings.languages.insert(
956 language.name(),
957 LanguageSettingsContent {
958 tab_size: language.config.tab_size,
959 hard_tabs: language.config.hard_tabs,
960 soft_wrap: language.config.soft_wrap,
961 ..Default::default()
962 }
963 .clone(),
964 );
965 self.languages.push(language);
966 self.version += 1;
967 *self.subscription.0.borrow_mut() = ();
968 }
969
970 fn reload(&mut self) {
971 self.languages.clear();
972 self.version += 1;
973 self.reload_count += 1;
974 for language in &mut self.available_languages {
975 language.loaded = false;
976 }
977 *self.subscription.0.borrow_mut() = ();
978 }
979
980 /// Reorders the list of language servers for the given language.
981 ///
982 /// Uses the provided list of ordered [`CachedLspAdapters`] as the desired order.
983 ///
984 /// Any existing language servers not present in `ordered_lsp_adapters` will be
985 /// appended to the end.
986 fn reorder_language_servers(
987 &mut self,
988 language_name: &LanguageName,
989 ordered_lsp_adapters: Vec<Arc<CachedLspAdapter>>,
990 ) {
991 let Some(lsp_adapters) = self.lsp_adapters.get_mut(language_name) else {
992 return;
993 };
994
995 let ordered_lsp_adapter_ids = ordered_lsp_adapters
996 .iter()
997 .map(|lsp_adapter| lsp_adapter.name.clone())
998 .collect::<HashSet<_>>();
999
1000 let mut new_lsp_adapters = ordered_lsp_adapters;
1001 for adapter in lsp_adapters.iter() {
1002 if !ordered_lsp_adapter_ids.contains(&adapter.name) {
1003 new_lsp_adapters.push(adapter.clone());
1004 }
1005 }
1006
1007 *lsp_adapters = new_lsp_adapters;
1008 }
1009
1010 fn remove_languages(
1011 &mut self,
1012 languages_to_remove: &[LanguageName],
1013 grammars_to_remove: &[Arc<str>],
1014 ) {
1015 if languages_to_remove.is_empty() && grammars_to_remove.is_empty() {
1016 return;
1017 }
1018
1019 self.languages
1020 .retain(|language| !languages_to_remove.contains(&language.name()));
1021 self.available_languages
1022 .retain(|language| !languages_to_remove.contains(&language.name));
1023 self.grammars
1024 .retain(|name, _| !grammars_to_remove.contains(name));
1025 self.version += 1;
1026 self.reload_count += 1;
1027 *self.subscription.0.borrow_mut() = ();
1028 }
1029
1030 /// Mark the given language as having been loaded, so that the
1031 /// language registry won't try to load it again.
1032 fn mark_language_loaded(&mut self, id: LanguageId) {
1033 for language in &mut self.available_languages {
1034 if language.id == id {
1035 language.loaded = true;
1036 break;
1037 }
1038 }
1039 }
1040}
1041
1042impl LspBinaryStatusSender {
1043 fn subscribe(
1044 &self,
1045 ) -> mpsc::UnboundedReceiver<(LanguageServerName, LanguageServerBinaryStatus)> {
1046 let (tx, rx) = mpsc::unbounded();
1047 self.txs.lock().push(tx);
1048 rx
1049 }
1050
1051 fn send(&self, name: LanguageServerName, status: LanguageServerBinaryStatus) {
1052 let mut txs = self.txs.lock();
1053 txs.retain(|tx| tx.unbounded_send((name.clone(), status.clone())).is_ok());
1054 }
1055}