toolchains: Add support for relative paths (#27777)
Closes #ISSUE Release Notes: - N/A
This commit is contained in:
parent
627ae7af6f
commit
edf712d45b
12 changed files with 178 additions and 93 deletions
|
@ -3065,7 +3065,7 @@ impl Project {
|
|||
|
||||
pub fn available_toolchains(
|
||||
&self,
|
||||
worktree_id: WorktreeId,
|
||||
path: ProjectPath,
|
||||
language_name: LanguageName,
|
||||
cx: &App,
|
||||
) -> Task<Option<ToolchainList>> {
|
||||
|
@ -3074,7 +3074,7 @@ impl Project {
|
|||
cx.update(|cx| {
|
||||
toolchain_store
|
||||
.read(cx)
|
||||
.list_toolchains(worktree_id, language_name, cx)
|
||||
.list_toolchains(path, language_name, cx)
|
||||
})
|
||||
.ok()?
|
||||
.await
|
||||
|
@ -3098,20 +3098,18 @@ impl Project {
|
|||
|
||||
pub fn activate_toolchain(
|
||||
&self,
|
||||
worktree_id: WorktreeId,
|
||||
path: ProjectPath,
|
||||
toolchain: Toolchain,
|
||||
cx: &mut App,
|
||||
) -> Task<Option<()>> {
|
||||
let Some(toolchain_store) = self.toolchain_store.clone() else {
|
||||
return Task::ready(None);
|
||||
};
|
||||
toolchain_store.update(cx, |this, cx| {
|
||||
this.activate_toolchain(worktree_id, toolchain, cx)
|
||||
})
|
||||
toolchain_store.update(cx, |this, cx| this.activate_toolchain(path, toolchain, cx))
|
||||
}
|
||||
pub fn active_toolchain(
|
||||
&self,
|
||||
worktree_id: WorktreeId,
|
||||
path: ProjectPath,
|
||||
language_name: LanguageName,
|
||||
cx: &App,
|
||||
) -> Task<Option<Toolchain>> {
|
||||
|
@ -3120,7 +3118,7 @@ impl Project {
|
|||
};
|
||||
toolchain_store
|
||||
.read(cx)
|
||||
.active_toolchain(worktree_id, language_name, cx)
|
||||
.active_toolchain(path, language_name, cx)
|
||||
}
|
||||
pub fn language_server_statuses<'a>(
|
||||
&'a self,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::Project;
|
||||
use crate::{Project, ProjectPath};
|
||||
use anyhow::{Context as _, Result};
|
||||
use collections::HashMap;
|
||||
use gpui::{AnyWindowHandle, App, AppContext as _, Context, Entity, Task, WeakEntity};
|
||||
|
@ -407,14 +407,17 @@ impl Project {
|
|||
cx: &Context<Project>,
|
||||
) -> Task<Option<PathBuf>> {
|
||||
cx.spawn(async move |this, cx| {
|
||||
if let Some((worktree, _)) = this
|
||||
if let Some((worktree, relative_path)) = this
|
||||
.update(cx, |this, cx| this.find_worktree(&abs_path, cx))
|
||||
.ok()?
|
||||
{
|
||||
let toolchain = this
|
||||
.update(cx, |this, cx| {
|
||||
this.active_toolchain(
|
||||
worktree.read(cx).id(),
|
||||
ProjectPath {
|
||||
worktree_id: worktree.read(cx).id(),
|
||||
path: relative_path.into(),
|
||||
},
|
||||
LanguageName::new("Python"),
|
||||
cx,
|
||||
)
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use std::{path::PathBuf, str::FromStr, sync::Arc};
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
str::FromStr,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
|
||||
|
@ -15,7 +19,7 @@ use rpc::{
|
|||
use settings::WorktreeId;
|
||||
use util::ResultExt as _;
|
||||
|
||||
use crate::{worktree_store::WorktreeStore, ProjectEnvironment};
|
||||
use crate::{worktree_store::WorktreeStore, ProjectEnvironment, ProjectPath};
|
||||
|
||||
pub struct ToolchainStore(ToolchainStoreInner);
|
||||
enum ToolchainStoreInner {
|
||||
|
@ -58,56 +62,46 @@ impl ToolchainStore {
|
|||
}
|
||||
pub(crate) fn activate_toolchain(
|
||||
&self,
|
||||
worktree_id: WorktreeId,
|
||||
path: ProjectPath,
|
||||
toolchain: Toolchain,
|
||||
cx: &mut App,
|
||||
) -> Task<Option<()>> {
|
||||
match &self.0 {
|
||||
ToolchainStoreInner::Local(local, _) => local.update(cx, |this, cx| {
|
||||
this.activate_toolchain(worktree_id, toolchain, cx)
|
||||
}),
|
||||
ToolchainStoreInner::Local(local, _) => {
|
||||
local.update(cx, |this, cx| this.activate_toolchain(path, toolchain, cx))
|
||||
}
|
||||
ToolchainStoreInner::Remote(remote) => {
|
||||
remote
|
||||
.read(cx)
|
||||
.activate_toolchain(worktree_id, toolchain, cx)
|
||||
remote.read(cx).activate_toolchain(path, toolchain, cx)
|
||||
}
|
||||
}
|
||||
}
|
||||
pub(crate) fn list_toolchains(
|
||||
&self,
|
||||
worktree_id: WorktreeId,
|
||||
path: ProjectPath,
|
||||
language_name: LanguageName,
|
||||
cx: &App,
|
||||
) -> Task<Option<ToolchainList>> {
|
||||
match &self.0 {
|
||||
ToolchainStoreInner::Local(local, _) => {
|
||||
local
|
||||
.read(cx)
|
||||
.list_toolchains(worktree_id, language_name, cx)
|
||||
local.read(cx).list_toolchains(path, language_name, cx)
|
||||
}
|
||||
ToolchainStoreInner::Remote(remote) => {
|
||||
remote
|
||||
.read(cx)
|
||||
.list_toolchains(worktree_id, language_name, cx)
|
||||
remote.read(cx).list_toolchains(path, language_name, cx)
|
||||
}
|
||||
}
|
||||
}
|
||||
pub(crate) fn active_toolchain(
|
||||
&self,
|
||||
worktree_id: WorktreeId,
|
||||
path: ProjectPath,
|
||||
language_name: LanguageName,
|
||||
cx: &App,
|
||||
) -> Task<Option<Toolchain>> {
|
||||
match &self.0 {
|
||||
ToolchainStoreInner::Local(local, _) => {
|
||||
local
|
||||
.read(cx)
|
||||
.active_toolchain(worktree_id, language_name, cx)
|
||||
local.read(cx).active_toolchain(path, language_name, cx)
|
||||
}
|
||||
ToolchainStoreInner::Remote(remote) => {
|
||||
remote
|
||||
.read(cx)
|
||||
.active_toolchain(worktree_id, language_name, cx)
|
||||
remote.read(cx).active_toolchain(path, language_name, cx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +124,12 @@ impl ToolchainStore {
|
|||
language_name,
|
||||
};
|
||||
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
|
||||
Ok(this.activate_toolchain(worktree_id, toolchain, cx))
|
||||
let path: Arc<Path> = if let Some(path) = envelope.payload.path {
|
||||
Arc::from(path.as_ref())
|
||||
} else {
|
||||
Arc::from("".as_ref())
|
||||
};
|
||||
Ok(this.activate_toolchain(ProjectPath { worktree_id, path }, toolchain, cx))
|
||||
})??
|
||||
.await;
|
||||
Ok(proto::Ack {})
|
||||
|
@ -144,7 +143,14 @@ impl ToolchainStore {
|
|||
.update(&mut cx, |this, cx| {
|
||||
let language_name = LanguageName::from_proto(envelope.payload.language_name);
|
||||
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
|
||||
this.active_toolchain(worktree_id, language_name, cx)
|
||||
this.active_toolchain(
|
||||
ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(envelope.payload.path.as_deref().unwrap_or("").as_ref()),
|
||||
},
|
||||
language_name,
|
||||
cx,
|
||||
)
|
||||
})?
|
||||
.await;
|
||||
|
||||
|
@ -169,7 +175,8 @@ impl ToolchainStore {
|
|||
.update(&mut cx, |this, cx| {
|
||||
let language_name = LanguageName::from_proto(envelope.payload.language_name);
|
||||
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
|
||||
this.list_toolchains(worktree_id, language_name, cx)
|
||||
let path = Arc::from(envelope.payload.path.as_deref().unwrap_or("").as_ref());
|
||||
this.list_toolchains(ProjectPath { worktree_id, path }, language_name, cx)
|
||||
})?
|
||||
.await;
|
||||
let has_values = toolchains.is_some();
|
||||
|
@ -222,7 +229,7 @@ struct LocalToolchainStore {
|
|||
languages: Arc<LanguageRegistry>,
|
||||
worktree_store: Entity<WorktreeStore>,
|
||||
project_environment: Entity<ProjectEnvironment>,
|
||||
active_toolchains: BTreeMap<(WorktreeId, LanguageName), Toolchain>,
|
||||
active_toolchains: BTreeMap<(WorktreeId, LanguageName), BTreeMap<Arc<Path>, Toolchain>>,
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
|
@ -230,12 +237,13 @@ impl language::LanguageToolchainStore for LocalStore {
|
|||
async fn active_toolchain(
|
||||
self: Arc<Self>,
|
||||
worktree_id: WorktreeId,
|
||||
path: Arc<Path>,
|
||||
language_name: LanguageName,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Option<Toolchain> {
|
||||
self.0
|
||||
.update(cx, |this, cx| {
|
||||
this.active_toolchain(worktree_id, language_name, cx)
|
||||
this.active_toolchain(ProjectPath { worktree_id, path }, language_name, cx)
|
||||
})
|
||||
.ok()?
|
||||
.await
|
||||
|
@ -247,12 +255,13 @@ impl language::LanguageToolchainStore for RemoteStore {
|
|||
async fn active_toolchain(
|
||||
self: Arc<Self>,
|
||||
worktree_id: WorktreeId,
|
||||
path: Arc<Path>,
|
||||
language_name: LanguageName,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Option<Toolchain> {
|
||||
self.0
|
||||
.update(cx, |this, cx| {
|
||||
this.active_toolchain(worktree_id, language_name, cx)
|
||||
this.active_toolchain(ProjectPath { worktree_id, path }, language_name, cx)
|
||||
})
|
||||
.ok()?
|
||||
.await
|
||||
|
@ -265,6 +274,7 @@ impl language::LanguageToolchainStore for EmptyToolchainStore {
|
|||
async fn active_toolchain(
|
||||
self: Arc<Self>,
|
||||
_: WorktreeId,
|
||||
_: Arc<Path>,
|
||||
_: LanguageName,
|
||||
_: &mut AsyncApp,
|
||||
) -> Option<Toolchain> {
|
||||
|
@ -284,16 +294,16 @@ impl EventEmitter<ToolchainStoreEvent> for LocalToolchainStore {}
|
|||
impl LocalToolchainStore {
|
||||
pub(crate) fn activate_toolchain(
|
||||
&self,
|
||||
worktree_id: WorktreeId,
|
||||
path: ProjectPath,
|
||||
toolchain: Toolchain,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Option<()>> {
|
||||
cx.spawn(async move |this, cx| {
|
||||
this.update(cx, |this, cx| {
|
||||
this.active_toolchains.insert(
|
||||
(worktree_id, toolchain.language_name.clone()),
|
||||
toolchain.clone(),
|
||||
);
|
||||
this.active_toolchains
|
||||
.entry((path.worktree_id, toolchain.language_name.clone()))
|
||||
.or_default()
|
||||
.insert(path.path, toolchain.clone());
|
||||
cx.emit(ToolchainStoreEvent::ToolchainActivated);
|
||||
})
|
||||
.ok();
|
||||
|
@ -302,7 +312,7 @@ impl LocalToolchainStore {
|
|||
}
|
||||
pub(crate) fn list_toolchains(
|
||||
&self,
|
||||
worktree_id: WorktreeId,
|
||||
path: ProjectPath,
|
||||
language_name: LanguageName,
|
||||
cx: &App,
|
||||
) -> Task<Option<ToolchainList>> {
|
||||
|
@ -310,17 +320,22 @@ impl LocalToolchainStore {
|
|||
let Some(root) = self
|
||||
.worktree_store
|
||||
.read(cx)
|
||||
.worktree_for_id(worktree_id, cx)
|
||||
.worktree_for_id(path.worktree_id, cx)
|
||||
.map(|worktree| worktree.read(cx).abs_path())
|
||||
else {
|
||||
return Task::ready(None);
|
||||
};
|
||||
|
||||
let abs_path = root.join(path.path);
|
||||
let environment = self.project_environment.clone();
|
||||
cx.spawn(async move |cx| {
|
||||
let project_env = environment
|
||||
.update(cx, |environment, cx| {
|
||||
environment.get_environment(Some(worktree_id), Some(root.clone()), cx)
|
||||
environment.get_environment(
|
||||
Some(path.worktree_id),
|
||||
Some(Arc::from(abs_path.as_path())),
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.ok()?
|
||||
.await;
|
||||
|
@ -331,20 +346,26 @@ impl LocalToolchainStore {
|
|||
.await
|
||||
.ok()?;
|
||||
let toolchains = language.toolchain_lister()?;
|
||||
Some(toolchains.list(root.to_path_buf(), project_env).await)
|
||||
Some(toolchains.list(abs_path.to_path_buf(), project_env).await)
|
||||
})
|
||||
.await
|
||||
})
|
||||
}
|
||||
pub(crate) fn active_toolchain(
|
||||
&self,
|
||||
worktree_id: WorktreeId,
|
||||
path: ProjectPath,
|
||||
language_name: LanguageName,
|
||||
_: &App,
|
||||
) -> Task<Option<Toolchain>> {
|
||||
let ancestors = path.path.ancestors();
|
||||
Task::ready(
|
||||
self.active_toolchains
|
||||
.get(&(worktree_id, language_name))
|
||||
.get(&(path.worktree_id, language_name))
|
||||
.and_then(|paths| {
|
||||
ancestors
|
||||
.into_iter()
|
||||
.find_map(|root_path| paths.get(root_path))
|
||||
})
|
||||
.cloned(),
|
||||
)
|
||||
}
|
||||
|
@ -357,24 +378,25 @@ struct RemoteToolchainStore {
|
|||
impl RemoteToolchainStore {
|
||||
pub(crate) fn activate_toolchain(
|
||||
&self,
|
||||
worktree_id: WorktreeId,
|
||||
project_path: ProjectPath,
|
||||
toolchain: Toolchain,
|
||||
cx: &App,
|
||||
) -> Task<Option<()>> {
|
||||
let project_id = self.project_id;
|
||||
let client = self.client.clone();
|
||||
cx.spawn(async move |_| {
|
||||
cx.background_spawn(async move {
|
||||
let path = PathBuf::from(toolchain.path.to_string());
|
||||
let _ = client
|
||||
.request(proto::ActivateToolchain {
|
||||
project_id,
|
||||
worktree_id: worktree_id.to_proto(),
|
||||
worktree_id: project_path.worktree_id.to_proto(),
|
||||
language_name: toolchain.language_name.into(),
|
||||
toolchain: Some(proto::Toolchain {
|
||||
name: toolchain.name.into(),
|
||||
path: path.to_proto(),
|
||||
raw_json: toolchain.as_json.to_string(),
|
||||
}),
|
||||
path: Some(project_path.path.to_string_lossy().into_owned()),
|
||||
})
|
||||
.await
|
||||
.log_err()?;
|
||||
|
@ -384,18 +406,19 @@ impl RemoteToolchainStore {
|
|||
|
||||
pub(crate) fn list_toolchains(
|
||||
&self,
|
||||
worktree_id: WorktreeId,
|
||||
path: ProjectPath,
|
||||
language_name: LanguageName,
|
||||
cx: &App,
|
||||
) -> Task<Option<ToolchainList>> {
|
||||
let project_id = self.project_id;
|
||||
let client = self.client.clone();
|
||||
cx.spawn(async move |_| {
|
||||
cx.background_spawn(async move {
|
||||
let response = client
|
||||
.request(proto::ListToolchains {
|
||||
project_id,
|
||||
worktree_id: worktree_id.to_proto(),
|
||||
worktree_id: path.worktree_id.to_proto(),
|
||||
language_name: language_name.clone().into(),
|
||||
path: Some(path.path.to_string_lossy().into_owned()),
|
||||
})
|
||||
.await
|
||||
.log_err()?;
|
||||
|
@ -435,18 +458,19 @@ impl RemoteToolchainStore {
|
|||
}
|
||||
pub(crate) fn active_toolchain(
|
||||
&self,
|
||||
worktree_id: WorktreeId,
|
||||
path: ProjectPath,
|
||||
language_name: LanguageName,
|
||||
cx: &App,
|
||||
) -> Task<Option<Toolchain>> {
|
||||
let project_id = self.project_id;
|
||||
let client = self.client.clone();
|
||||
cx.spawn(async move |_| {
|
||||
cx.background_spawn(async move {
|
||||
let response = client
|
||||
.request(proto::ActiveToolchain {
|
||||
project_id,
|
||||
worktree_id: worktree_id.to_proto(),
|
||||
worktree_id: path.worktree_id.to_proto(),
|
||||
language_name: language_name.clone().into(),
|
||||
path: Some(path.path.to_string_lossy().into_owned()),
|
||||
})
|
||||
.await
|
||||
.log_err()?;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue