project: Track manifest locations per unique manifest locator (#27194)
This pull request paves way for exposing manifest tracking to extensions. - Project tree was renamed to manifest tree to better reflect it's intent (and avoid confusion). - Language server adapters now provide a name of their *manifest locator*. If multiple language servers refer to the same locator, the locating code will run just once for a given path. Release Notes: - N/A *or* Added/Fixed/Improved ... --------- Co-authored-by: Anthony <anthony@zed.dev>
This commit is contained in:
parent
6bced3a834
commit
05aa8880a4
10 changed files with 241 additions and 154 deletions
|
@ -6,9 +6,9 @@ use crate::{
|
|||
buffer_store::{BufferStore, BufferStoreEvent},
|
||||
environment::ProjectEnvironment,
|
||||
lsp_command::{self, *},
|
||||
manifest_tree::{AdapterQuery, LanguageServerTree, LaunchDisposition, ManifestTree},
|
||||
prettier_store::{self, PrettierStore, PrettierStoreEvent},
|
||||
project_settings::{LspSettings, ProjectSettings},
|
||||
project_tree::{AdapterQuery, LanguageServerTree, LaunchDisposition, ProjectTree},
|
||||
relativize_path, resolve_path,
|
||||
toolchain_store::{EmptyToolchainStore, ToolchainStoreEvent},
|
||||
worktree_store::{WorktreeStore, WorktreeStoreEvent},
|
||||
|
@ -3349,7 +3349,7 @@ impl LspStore {
|
|||
sender,
|
||||
)
|
||||
};
|
||||
let project_tree = ProjectTree::new(worktree_store.clone(), cx);
|
||||
let manifest_tree = ManifestTree::new(worktree_store.clone(), cx);
|
||||
Self {
|
||||
mode: LspStoreMode::Local(LocalLspStore {
|
||||
weak: cx.weak_entity(),
|
||||
|
@ -3375,7 +3375,7 @@ impl LspStore {
|
|||
_subscription: cx.on_app_quit(|this, cx| {
|
||||
this.as_local_mut().unwrap().shutdown_language_servers(cx)
|
||||
}),
|
||||
lsp_tree: LanguageServerTree::new(project_tree, languages.clone(), cx),
|
||||
lsp_tree: LanguageServerTree::new(manifest_tree, languages.clone(), cx),
|
||||
registered_buffers: Default::default(),
|
||||
}),
|
||||
last_formatting_failure: None,
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
//! This module defines a Project Tree.
|
||||
//! This module defines a Manifest Tree.
|
||||
//!
|
||||
//! A Project Tree is responsible for determining where the roots of subprojects are located in a project.
|
||||
//! A Manifest Tree is responsible for determining where the manifests for subprojects are located in a project.
|
||||
//! This then is used to provide those locations to language servers & determine locations eligible for toolchain selection.
|
||||
|
||||
mod manifest_store;
|
||||
mod path_trie;
|
||||
mod server_tree;
|
||||
|
||||
|
@ -14,8 +16,8 @@ use std::{
|
|||
|
||||
use collections::HashMap;
|
||||
use gpui::{App, AppContext as _, Context, Entity, EventEmitter, Subscription};
|
||||
use language::{CachedLspAdapter, LspAdapterDelegate};
|
||||
use lsp::LanguageServerName;
|
||||
use language::{LspAdapterDelegate, ManifestName, ManifestQuery};
|
||||
pub use manifest_store::ManifestProviders;
|
||||
use path_trie::{LabelPresence, RootPathTrie, TriePath};
|
||||
use settings::{SettingsStore, WorktreeId};
|
||||
use worktree::{Event as WorktreeEvent, Worktree};
|
||||
|
@ -28,7 +30,7 @@ use crate::{
|
|||
pub(crate) use server_tree::{AdapterQuery, LanguageServerTree, LaunchDisposition};
|
||||
|
||||
struct WorktreeRoots {
|
||||
roots: RootPathTrie<LanguageServerName>,
|
||||
roots: RootPathTrie<ManifestName>,
|
||||
worktree_store: Entity<WorktreeStore>,
|
||||
_worktree_subscription: Subscription,
|
||||
}
|
||||
|
@ -70,55 +72,21 @@ impl WorktreeRoots {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ProjectTree {
|
||||
pub struct ManifestTree {
|
||||
root_points: HashMap<WorktreeId, Entity<WorktreeRoots>>,
|
||||
worktree_store: Entity<WorktreeStore>,
|
||||
_subscriptions: [Subscription; 2],
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct AdapterWrapper(Arc<CachedLspAdapter>);
|
||||
impl PartialEq for AdapterWrapper {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.name.eq(&other.0.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for AdapterWrapper {}
|
||||
|
||||
impl std::hash::Hash for AdapterWrapper {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.0.name.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for AdapterWrapper {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.0.name.cmp(&other.0.name))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for AdapterWrapper {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.0.name.cmp(&other.0.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<LanguageServerName> for AdapterWrapper {
|
||||
fn borrow(&self) -> &LanguageServerName {
|
||||
&self.0.name
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub(crate) enum ProjectTreeEvent {
|
||||
pub(crate) enum ManifestTreeEvent {
|
||||
WorktreeRemoved(WorktreeId),
|
||||
Cleared,
|
||||
}
|
||||
|
||||
impl EventEmitter<ProjectTreeEvent> for ProjectTree {}
|
||||
impl EventEmitter<ManifestTreeEvent> for ManifestTree {}
|
||||
|
||||
impl ProjectTree {
|
||||
impl ManifestTree {
|
||||
pub(crate) fn new(worktree_store: Entity<WorktreeStore>, cx: &mut App) -> Entity<Self> {
|
||||
cx.new(|cx| Self {
|
||||
root_points: Default::default(),
|
||||
|
@ -130,26 +98,22 @@ impl ProjectTree {
|
|||
worktree_roots.roots = RootPathTrie::new();
|
||||
})
|
||||
}
|
||||
cx.emit(ProjectTreeEvent::Cleared);
|
||||
cx.emit(ManifestTreeEvent::Cleared);
|
||||
}),
|
||||
],
|
||||
worktree_store,
|
||||
})
|
||||
}
|
||||
#[allow(clippy::mutable_key_type)]
|
||||
fn root_for_path(
|
||||
&mut self,
|
||||
ProjectPath { worktree_id, path }: ProjectPath,
|
||||
adapters: Vec<Arc<CachedLspAdapter>>,
|
||||
manifests: &mut dyn Iterator<Item = ManifestName>,
|
||||
delegate: Arc<dyn LspAdapterDelegate>,
|
||||
cx: &mut App,
|
||||
) -> BTreeMap<AdapterWrapper, ProjectPath> {
|
||||
) -> BTreeMap<ManifestName, ProjectPath> {
|
||||
debug_assert_eq!(delegate.worktree_id(), worktree_id);
|
||||
#[allow(clippy::mutable_key_type)]
|
||||
let mut roots = BTreeMap::from_iter(
|
||||
adapters
|
||||
.into_iter()
|
||||
.map(|adapter| (AdapterWrapper(adapter), (None, LabelPresence::KnownAbsent))),
|
||||
manifests.map(|manifest| (manifest, (None, LabelPresence::KnownAbsent))),
|
||||
);
|
||||
let worktree_roots = match self.root_points.entry(worktree_id) {
|
||||
Entry::Occupied(occupied_entry) => occupied_entry.get().clone(),
|
||||
|
@ -182,7 +146,8 @@ impl ProjectTree {
|
|||
ControlFlow::Continue(())
|
||||
});
|
||||
});
|
||||
for (adapter, (root_path, presence)) in &mut roots {
|
||||
|
||||
for (manifest_name, (root_path, presence)) in &mut roots {
|
||||
if *presence == LabelPresence::Present {
|
||||
continue;
|
||||
}
|
||||
|
@ -198,12 +163,22 @@ impl ProjectTree {
|
|||
.unwrap_or_else(|| path.components().count() + 1);
|
||||
|
||||
if depth > 0 {
|
||||
let root = adapter.0.find_project_root(&path, depth, &delegate);
|
||||
let Some(provider) = ManifestProviders::global(cx).get(manifest_name.borrow())
|
||||
else {
|
||||
log::warn!("Manifest provider `{}` not found", manifest_name.as_ref());
|
||||
continue;
|
||||
};
|
||||
|
||||
let root = provider.search(ManifestQuery {
|
||||
path: path.clone(),
|
||||
depth,
|
||||
delegate: delegate.clone(),
|
||||
});
|
||||
match root {
|
||||
Some(known_root) => worktree_roots.update(cx, |this, _| {
|
||||
let root = TriePath::from(&*known_root);
|
||||
this.roots
|
||||
.insert(&root, adapter.0.name(), LabelPresence::Present);
|
||||
.insert(&root, manifest_name.clone(), LabelPresence::Present);
|
||||
*presence = LabelPresence::Present;
|
||||
*root_path = Some(ProjectPath {
|
||||
worktree_id,
|
||||
|
@ -212,7 +187,7 @@ impl ProjectTree {
|
|||
}),
|
||||
None => worktree_roots.update(cx, |this, _| {
|
||||
this.roots
|
||||
.insert(&key, adapter.0.name(), LabelPresence::KnownAbsent);
|
||||
.insert(&key, manifest_name.clone(), LabelPresence::KnownAbsent);
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +210,7 @@ impl ProjectTree {
|
|||
match evt {
|
||||
WorktreeStoreEvent::WorktreeRemoved(_, worktree_id) => {
|
||||
self.root_points.remove(&worktree_id);
|
||||
cx.emit(ProjectTreeEvent::WorktreeRemoved(*worktree_id));
|
||||
cx.emit(ManifestTreeEvent::WorktreeRemoved(*worktree_id));
|
||||
}
|
||||
_ => {}
|
||||
}
|
48
crates/project/src/manifest_tree/manifest_store.rs
Normal file
48
crates/project/src/manifest_tree/manifest_store.rs
Normal file
|
@ -0,0 +1,48 @@
|
|||
use collections::HashMap;
|
||||
use gpui::{App, Global, SharedString};
|
||||
use parking_lot::RwLock;
|
||||
use std::{ops::Deref, sync::Arc};
|
||||
|
||||
use language::{ManifestName, ManifestProvider};
|
||||
|
||||
#[derive(Default)]
|
||||
struct ManifestProvidersState {
|
||||
providers: HashMap<ManifestName, Arc<dyn ManifestProvider>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ManifestProviders(Arc<RwLock<ManifestProvidersState>>);
|
||||
|
||||
#[derive(Default)]
|
||||
struct GlobalManifestProvider(ManifestProviders);
|
||||
|
||||
impl Deref for GlobalManifestProvider {
|
||||
type Target = ManifestProviders;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Global for GlobalManifestProvider {}
|
||||
|
||||
impl ManifestProviders {
|
||||
/// Returns the global [`ManifestStore`].
|
||||
///
|
||||
/// Inserts a default [`ManifestStore`] if one does not yet exist.
|
||||
pub fn global(cx: &mut App) -> Self {
|
||||
cx.default_global::<GlobalManifestProvider>().0.clone()
|
||||
}
|
||||
|
||||
pub fn register(&self, provider: Arc<dyn ManifestProvider>) {
|
||||
self.0.write().providers.insert(provider.name(), provider);
|
||||
}
|
||||
|
||||
pub fn unregister(&self, name: &SharedString) {
|
||||
self.0.write().providers.remove(name);
|
||||
}
|
||||
|
||||
pub(super) fn get(&self, name: &SharedString) -> Option<Arc<dyn ManifestProvider>> {
|
||||
self.0.read().providers.get(name).cloned()
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
|
||||
/// [RootPathTrie] is a workhorse of [super::ProjectTree]. It is responsible for determining the closest known project root for a given path.
|
||||
/// [RootPathTrie] is a workhorse of [super::ManifestTree]. It is responsible for determining the closest known project root for a given path.
|
||||
/// It also determines how much of a given path is unexplored, thus letting callers fill in that gap if needed.
|
||||
/// Conceptually, it allows one to annotate Worktree entries with arbitrary extra metadata and run closest-ancestor searches.
|
||||
///
|
|
@ -6,7 +6,6 @@
|
|||
//! LSP Tree is transparent to RPC peers; when clients ask host to spawn a new language server, the host will perform LSP Tree lookup for provided path; it may decide
|
||||
//! to reuse existing language server. The client maintains it's own LSP Tree that is a subset of host LSP Tree. Done this way, the client does not need to
|
||||
//! ask about suitable language server for each path it interacts with; it can resolve most of the queries locally.
|
||||
//! This module defines a Project Tree.
|
||||
|
||||
use std::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
|
@ -16,10 +15,9 @@ use std::{
|
|||
|
||||
use collections::{HashMap, IndexMap};
|
||||
use gpui::{App, AppContext as _, Entity, Subscription};
|
||||
use itertools::Itertools;
|
||||
use language::{
|
||||
language_settings::AllLanguageSettings, Attach, LanguageName, LanguageRegistry,
|
||||
LspAdapterDelegate,
|
||||
language_settings::AllLanguageSettings, Attach, CachedLspAdapter, LanguageName,
|
||||
LanguageRegistry, LspAdapterDelegate,
|
||||
};
|
||||
use lsp::LanguageServerName;
|
||||
use settings::{Settings, SettingsLocation, WorktreeId};
|
||||
|
@ -27,7 +25,7 @@ use std::sync::OnceLock;
|
|||
|
||||
use crate::{project_settings::LspSettings, LanguageServerId, ProjectPath};
|
||||
|
||||
use super::{AdapterWrapper, ProjectTree, ProjectTreeEvent};
|
||||
use super::{ManifestTree, ManifestTreeEvent};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct ServersForWorktree {
|
||||
|
@ -38,7 +36,7 @@ struct ServersForWorktree {
|
|||
}
|
||||
|
||||
pub struct LanguageServerTree {
|
||||
project_tree: Entity<ProjectTree>,
|
||||
manifest_tree: Entity<ManifestTree>,
|
||||
instances: BTreeMap<WorktreeId, ServersForWorktree>,
|
||||
attach_kind_cache: HashMap<LanguageServerName, Attach>,
|
||||
languages: Arc<LanguageRegistry>,
|
||||
|
@ -133,30 +131,20 @@ pub(crate) enum AdapterQuery<'a> {
|
|||
|
||||
impl LanguageServerTree {
|
||||
pub(crate) fn new(
|
||||
project_tree: Entity<ProjectTree>,
|
||||
manifest_tree: Entity<ManifestTree>,
|
||||
languages: Arc<LanguageRegistry>,
|
||||
cx: &mut App,
|
||||
) -> Entity<Self> {
|
||||
cx.new(|cx| Self {
|
||||
_subscriptions: cx.subscribe(
|
||||
&project_tree,
|
||||
|_: &mut Self, _, event, _| {
|
||||
if event == &ProjectTreeEvent::Cleared {}
|
||||
},
|
||||
),
|
||||
project_tree,
|
||||
_subscriptions: cx.subscribe(&manifest_tree, |_: &mut Self, _, event, _| {
|
||||
if event == &ManifestTreeEvent::Cleared {}
|
||||
}),
|
||||
manifest_tree,
|
||||
instances: Default::default(),
|
||||
attach_kind_cache: Default::default(),
|
||||
languages,
|
||||
})
|
||||
}
|
||||
/// Memoize calls to attach_kind on LspAdapter (which might be a WASM extension, thus ~expensive to call).
|
||||
fn attach_kind(&mut self, adapter: &AdapterWrapper) -> Attach {
|
||||
*self
|
||||
.attach_kind_cache
|
||||
.entry(adapter.0.name.clone())
|
||||
.or_insert_with(|| adapter.0.attach_kind())
|
||||
}
|
||||
|
||||
/// Get all language server root points for a given path and language; the language servers might already be initialized at a given path.
|
||||
pub(crate) fn get<'a>(
|
||||
|
@ -174,10 +162,14 @@ impl LanguageServerTree {
|
|||
AdapterQuery::Language(language_name) => {
|
||||
self.adapters_for_language(settings_location, language_name, cx)
|
||||
}
|
||||
AdapterQuery::Adapter(language_server_name) => IndexMap::from_iter(
|
||||
self.adapter_for_name(language_server_name)
|
||||
.map(|adapter| (adapter, (LspSettings::default(), BTreeSet::new()))),
|
||||
),
|
||||
AdapterQuery::Adapter(language_server_name) => {
|
||||
IndexMap::from_iter(self.adapter_for_name(language_server_name).map(|adapter| {
|
||||
(
|
||||
adapter.name(),
|
||||
(LspSettings::default(), BTreeSet::new(), adapter),
|
||||
)
|
||||
}))
|
||||
}
|
||||
};
|
||||
self.get_with_adapters(path, adapters, delegate, cx)
|
||||
}
|
||||
|
@ -185,41 +177,48 @@ impl LanguageServerTree {
|
|||
fn get_with_adapters<'a>(
|
||||
&'a mut self,
|
||||
path: ProjectPath,
|
||||
adapters: IndexMap<AdapterWrapper, (LspSettings, BTreeSet<LanguageName>)>,
|
||||
adapters: IndexMap<
|
||||
LanguageServerName,
|
||||
(LspSettings, BTreeSet<LanguageName>, Arc<CachedLspAdapter>),
|
||||
>,
|
||||
delegate: Arc<dyn LspAdapterDelegate>,
|
||||
cx: &mut App,
|
||||
) -> impl Iterator<Item = LanguageServerTreeNode> + 'a {
|
||||
let worktree_id = path.worktree_id;
|
||||
#[allow(clippy::mutable_key_type)]
|
||||
let mut roots = self.project_tree.update(cx, |this, cx| {
|
||||
|
||||
let mut manifest_to_adapters = BTreeMap::default();
|
||||
for (_, _, adapter) in adapters.values() {
|
||||
if let Some(manifest_name) = adapter.manifest_name() {
|
||||
manifest_to_adapters
|
||||
.entry(manifest_name)
|
||||
.or_insert_with(Vec::default)
|
||||
.push(adapter.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let roots = self.manifest_tree.update(cx, |this, cx| {
|
||||
this.root_for_path(
|
||||
path,
|
||||
adapters
|
||||
.iter()
|
||||
.map(|(adapter, _)| adapter.0.clone())
|
||||
.collect(),
|
||||
&mut manifest_to_adapters.keys().cloned(),
|
||||
delegate,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
let mut root_path = None;
|
||||
// Backwards-compat: Fill in any adapters for which we did not detect the root as having the project root at the root of a worktree.
|
||||
for (adapter, _) in adapters.iter() {
|
||||
roots.entry(adapter.clone()).or_insert_with(|| {
|
||||
root_path
|
||||
.get_or_insert_with(|| ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from("".as_ref()),
|
||||
})
|
||||
.clone()
|
||||
});
|
||||
}
|
||||
|
||||
roots
|
||||
let root_path = std::cell::LazyCell::new(move || ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from("".as_ref()),
|
||||
});
|
||||
adapters
|
||||
.into_iter()
|
||||
.filter_map(move |(adapter, root_path)| {
|
||||
let attach = self.attach_kind(&adapter);
|
||||
let (index, _, (settings, new_languages)) = adapters.get_full(&adapter)?;
|
||||
.map(move |(_, (settings, new_languages, adapter))| {
|
||||
// Backwards-compat: Fill in any adapters for which we did not detect the root as having the project root at the root of a worktree.
|
||||
let root_path = adapter
|
||||
.manifest_name()
|
||||
.and_then(|name| roots.get(&name))
|
||||
.cloned()
|
||||
.unwrap_or_else(|| root_path.clone());
|
||||
let attach = adapter.attach_kind();
|
||||
|
||||
let inner_node = self
|
||||
.instances
|
||||
.entry(root_path.worktree_id)
|
||||
|
@ -227,27 +226,25 @@ impl LanguageServerTree {
|
|||
.roots
|
||||
.entry(root_path.path.clone())
|
||||
.or_default()
|
||||
.entry(adapter.0.name.clone());
|
||||
let (node, languages) = inner_node.or_insert_with(move || {
|
||||
.entry(adapter.name());
|
||||
let (node, languages) = inner_node.or_insert_with(|| {
|
||||
(
|
||||
Arc::new(InnerTreeNode::new(
|
||||
adapter.0.name(),
|
||||
adapter.name(),
|
||||
attach,
|
||||
root_path,
|
||||
root_path.clone(),
|
||||
settings.clone(),
|
||||
)),
|
||||
Default::default(),
|
||||
)
|
||||
});
|
||||
languages.extend(new_languages.iter().cloned());
|
||||
Some((index, Arc::downgrade(&node).into()))
|
||||
Arc::downgrade(&node).into()
|
||||
})
|
||||
.sorted_by_key(|(index, _)| *index)
|
||||
.map(|(_, node)| node)
|
||||
}
|
||||
|
||||
fn adapter_for_name(&self, name: &LanguageServerName) -> Option<AdapterWrapper> {
|
||||
self.languages.adapter_for_name(name).map(AdapterWrapper)
|
||||
fn adapter_for_name(&self, name: &LanguageServerName) -> Option<Arc<CachedLspAdapter>> {
|
||||
self.languages.adapter_for_name(name)
|
||||
}
|
||||
|
||||
fn adapters_for_language(
|
||||
|
@ -255,7 +252,8 @@ impl LanguageServerTree {
|
|||
settings_location: SettingsLocation,
|
||||
language_name: &LanguageName,
|
||||
cx: &App,
|
||||
) -> IndexMap<AdapterWrapper, (LspSettings, BTreeSet<LanguageName>)> {
|
||||
) -> IndexMap<LanguageServerName, (LspSettings, BTreeSet<LanguageName>, Arc<CachedLspAdapter>)>
|
||||
{
|
||||
let settings = AllLanguageSettings::get(Some(settings_location), cx).language(
|
||||
Some(settings_location),
|
||||
Some(language_name),
|
||||
|
@ -297,10 +295,11 @@ impl LanguageServerTree {
|
|||
.cloned()
|
||||
.unwrap_or_default();
|
||||
Some((
|
||||
AdapterWrapper(adapter),
|
||||
adapter.name(),
|
||||
(
|
||||
adapter_settings,
|
||||
BTreeSet::from_iter([language_name.clone()]),
|
||||
adapter,
|
||||
),
|
||||
))
|
||||
})
|
||||
|
@ -314,8 +313,8 @@ impl LanguageServerTree {
|
|||
self.languages.reorder_language_servers(
|
||||
&language_name,
|
||||
adapters_with_settings
|
||||
.keys()
|
||||
.map(|wrapper| wrapper.0.clone())
|
||||
.values()
|
||||
.map(|(_, _, adapter)| adapter.clone())
|
||||
.collect(),
|
||||
);
|
||||
|
||||
|
@ -392,11 +391,16 @@ impl<'tree> ServerTreeRebase<'tree> {
|
|||
self.new_tree
|
||||
.adapters_for_language(settings_location, language_name, cx)
|
||||
}
|
||||
AdapterQuery::Adapter(language_server_name) => IndexMap::from_iter(
|
||||
self.new_tree
|
||||
.adapter_for_name(language_server_name)
|
||||
.map(|adapter| (adapter, (LspSettings::default(), BTreeSet::new()))),
|
||||
),
|
||||
AdapterQuery::Adapter(language_server_name) => {
|
||||
IndexMap::from_iter(self.new_tree.adapter_for_name(language_server_name).map(
|
||||
|adapter| {
|
||||
(
|
||||
adapter.name(),
|
||||
(LspSettings::default(), BTreeSet::new(), adapter),
|
||||
)
|
||||
},
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
self.new_tree
|
|
@ -7,9 +7,9 @@ pub mod git_store;
|
|||
pub mod image_store;
|
||||
pub mod lsp_command;
|
||||
pub mod lsp_store;
|
||||
mod manifest_tree;
|
||||
pub mod prettier_store;
|
||||
pub mod project_settings;
|
||||
mod project_tree;
|
||||
pub mod search;
|
||||
mod task_inventory;
|
||||
pub mod task_store;
|
||||
|
@ -73,6 +73,7 @@ use lsp::{
|
|||
};
|
||||
use lsp_command::*;
|
||||
use lsp_store::{CompletionDocumentation, LspFormatTarget, OpenLspBufferHandle};
|
||||
pub use manifest_tree::ManifestProviders;
|
||||
use node_runtime::NodeRuntime;
|
||||
use parking_lot::Mutex;
|
||||
pub use prettier_store::PrettierStore;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue