toolchains: Use language-specific terms in UI (#20985)
Closes #ISSUE Release Notes: - N/A
This commit is contained in:
parent
75c545aa1e
commit
0b373d43dc
6 changed files with 76 additions and 9 deletions
|
@ -31,6 +31,8 @@ pub trait ToolchainLister: Send + Sync {
|
||||||
worktree_root: PathBuf,
|
worktree_root: PathBuf,
|
||||||
project_env: Option<HashMap<String, String>>,
|
project_env: Option<HashMap<String, String>>,
|
||||||
) -> ToolchainList;
|
) -> ToolchainList;
|
||||||
|
// Returns a term which we should use in UI to refer to a toolchain.
|
||||||
|
fn term(&self) -> SharedString;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
|
|
|
@ -2,8 +2,8 @@ use anyhow::ensure;
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use gpui::AsyncAppContext;
|
|
||||||
use gpui::{AppContext, Task};
|
use gpui::{AppContext, Task};
|
||||||
|
use gpui::{AsyncAppContext, SharedString};
|
||||||
use language::language_settings::language_settings;
|
use language::language_settings::language_settings;
|
||||||
use language::LanguageName;
|
use language::LanguageName;
|
||||||
use language::LanguageToolchainStore;
|
use language::LanguageToolchainStore;
|
||||||
|
@ -498,8 +498,17 @@ fn python_module_name_from_relative_path(relative_path: &str) -> String {
|
||||||
.to_string()
|
.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
pub(crate) struct PythonToolchainProvider {
|
||||||
pub(crate) struct PythonToolchainProvider {}
|
term: SharedString,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PythonToolchainProvider {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
term: SharedString::new_static("Virtual Environment"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ENV_PRIORITY_LIST: &'static [PythonEnvironmentKind] = &[
|
static ENV_PRIORITY_LIST: &'static [PythonEnvironmentKind] = &[
|
||||||
// Prioritize non-Conda environments.
|
// Prioritize non-Conda environments.
|
||||||
|
@ -604,6 +613,9 @@ impl ToolchainLister for PythonToolchainProvider {
|
||||||
groups: Default::default(),
|
groups: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn term(&self) -> SharedString {
|
||||||
|
self.term.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EnvironmentApi<'a> {
|
pub struct EnvironmentApi<'a> {
|
||||||
|
|
|
@ -425,6 +425,19 @@ impl<D: PickerDelegate> Picker<D> {
|
||||||
self.cancel(&menu::Cancel, cx);
|
self.cancel(&menu::Cancel, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn refresh_placeholder(&mut self, cx: &mut WindowContext<'_>) {
|
||||||
|
match &self.head {
|
||||||
|
Head::Editor(view) => {
|
||||||
|
let placeholder = self.delegate.placeholder_text(cx);
|
||||||
|
view.update(cx, |this, cx| {
|
||||||
|
this.set_placeholder_text(placeholder, cx);
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Head::Empty(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn refresh(&mut self, cx: &mut ViewContext<Self>) {
|
pub fn refresh(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
let query = self.query(cx);
|
let query = self.query(cx);
|
||||||
self.update_matches(query, cx);
|
self.update_matches(query, cx);
|
||||||
|
|
|
@ -2464,6 +2464,19 @@ impl Project {
|
||||||
Task::ready(None)
|
Task::ready(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn toolchain_term(
|
||||||
|
languages: Arc<LanguageRegistry>,
|
||||||
|
language_name: LanguageName,
|
||||||
|
) -> Option<SharedString> {
|
||||||
|
languages
|
||||||
|
.language_for_name(&language_name.0)
|
||||||
|
.await
|
||||||
|
.ok()?
|
||||||
|
.toolchain_lister()
|
||||||
|
.map(|lister| lister.term())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn activate_toolchain(
|
pub fn activate_toolchain(
|
||||||
&self,
|
&self,
|
||||||
worktree_id: WorktreeId,
|
worktree_id: WorktreeId,
|
||||||
|
|
|
@ -4,14 +4,15 @@ use gpui::{
|
||||||
ViewContext, WeakModel, WeakView,
|
ViewContext, WeakModel, WeakView,
|
||||||
};
|
};
|
||||||
use language::{Buffer, BufferEvent, LanguageName, Toolchain};
|
use language::{Buffer, BufferEvent, LanguageName, Toolchain};
|
||||||
use project::WorktreeId;
|
use project::{Project, WorktreeId};
|
||||||
use ui::{Button, ButtonCommon, Clickable, FluentBuilder, LabelSize, Tooltip};
|
use ui::{Button, ButtonCommon, Clickable, FluentBuilder, LabelSize, SharedString, Tooltip};
|
||||||
use workspace::{item::ItemHandle, StatusItemView, Workspace};
|
use workspace::{item::ItemHandle, StatusItemView, Workspace};
|
||||||
|
|
||||||
use crate::ToolchainSelector;
|
use crate::ToolchainSelector;
|
||||||
|
|
||||||
pub struct ActiveToolchain {
|
pub struct ActiveToolchain {
|
||||||
active_toolchain: Option<Toolchain>,
|
active_toolchain: Option<Toolchain>,
|
||||||
|
term: SharedString,
|
||||||
workspace: WeakView<Workspace>,
|
workspace: WeakView<Workspace>,
|
||||||
active_buffer: Option<(WorktreeId, WeakModel<Buffer>, Subscription)>,
|
active_buffer: Option<(WorktreeId, WeakModel<Buffer>, Subscription)>,
|
||||||
_update_toolchain_task: Task<Option<()>>,
|
_update_toolchain_task: Task<Option<()>>,
|
||||||
|
@ -22,6 +23,7 @@ impl ActiveToolchain {
|
||||||
Self {
|
Self {
|
||||||
active_toolchain: None,
|
active_toolchain: None,
|
||||||
active_buffer: None,
|
active_buffer: None,
|
||||||
|
term: SharedString::new_static("Toolchain"),
|
||||||
workspace: workspace.weak_handle(),
|
workspace: workspace.weak_handle(),
|
||||||
|
|
||||||
_update_toolchain_task: Self::spawn_tracker_task(cx),
|
_update_toolchain_task: Self::spawn_tracker_task(cx),
|
||||||
|
@ -44,7 +46,17 @@ impl ActiveToolchain {
|
||||||
.update(&mut cx, |this, _| Some(this.language()?.name()))
|
.update(&mut cx, |this, _| Some(this.language()?.name()))
|
||||||
.ok()
|
.ok()
|
||||||
.flatten()?;
|
.flatten()?;
|
||||||
|
let term = workspace
|
||||||
|
.update(&mut cx, |workspace, cx| {
|
||||||
|
let languages = workspace.project().read(cx).languages();
|
||||||
|
Project::toolchain_term(languages.clone(), language_name.clone())
|
||||||
|
})
|
||||||
|
.ok()?
|
||||||
|
.await?;
|
||||||
|
let _ = this.update(&mut cx, |this, cx| {
|
||||||
|
this.term = term;
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
let worktree_id = active_file
|
let worktree_id = active_file
|
||||||
.update(&mut cx, |this, cx| Some(this.file()?.worktree_id(cx)))
|
.update(&mut cx, |this, cx| Some(this.file()?.worktree_id(cx)))
|
||||||
.ok()
|
.ok()
|
||||||
|
@ -133,6 +145,7 @@ impl ActiveToolchain {
|
||||||
impl Render for ActiveToolchain {
|
impl Render for ActiveToolchain {
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||||
div().when_some(self.active_toolchain.as_ref(), |el, active_toolchain| {
|
div().when_some(self.active_toolchain.as_ref(), |el, active_toolchain| {
|
||||||
|
let term = self.term.clone();
|
||||||
el.child(
|
el.child(
|
||||||
Button::new("change-toolchain", active_toolchain.name.clone())
|
Button::new("change-toolchain", active_toolchain.name.clone())
|
||||||
.label_size(LabelSize::Small)
|
.label_size(LabelSize::Small)
|
||||||
|
@ -143,7 +156,7 @@ impl Render for ActiveToolchain {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.tooltip(|cx| Tooltip::text("Select Toolchain", cx)),
|
.tooltip(move |cx| Tooltip::text(format!("Select {}", &term), cx)),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,7 @@ pub struct ToolchainSelectorDelegate {
|
||||||
workspace: WeakView<Workspace>,
|
workspace: WeakView<Workspace>,
|
||||||
worktree_id: WorktreeId,
|
worktree_id: WorktreeId,
|
||||||
worktree_abs_path_root: Arc<Path>,
|
worktree_abs_path_root: Arc<Path>,
|
||||||
|
placeholder_text: Arc<str>,
|
||||||
_fetch_candidates_task: Task<Option<()>>,
|
_fetch_candidates_task: Task<Option<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +145,17 @@ impl ToolchainSelectorDelegate {
|
||||||
let _fetch_candidates_task = cx.spawn({
|
let _fetch_candidates_task = cx.spawn({
|
||||||
let project = project.clone();
|
let project = project.clone();
|
||||||
move |this, mut cx| async move {
|
move |this, mut cx| async move {
|
||||||
|
let term = project
|
||||||
|
.update(&mut cx, |this, _| {
|
||||||
|
Project::toolchain_term(this.languages().clone(), language_name.clone())
|
||||||
|
})
|
||||||
|
.ok()?
|
||||||
|
.await?;
|
||||||
|
let placeholder_text = format!("Select a {}…", term.to_lowercase()).into();
|
||||||
|
let _ = this.update(&mut cx, move |this, cx| {
|
||||||
|
this.delegate.placeholder_text = placeholder_text;
|
||||||
|
this.refresh_placeholder(cx);
|
||||||
|
});
|
||||||
let available_toolchains = project
|
let available_toolchains = project
|
||||||
.update(&mut cx, |this, cx| {
|
.update(&mut cx, |this, cx| {
|
||||||
this.available_toolchains(worktree_id, language_name, cx)
|
this.available_toolchains(worktree_id, language_name, cx)
|
||||||
|
@ -153,6 +165,7 @@ impl ToolchainSelectorDelegate {
|
||||||
|
|
||||||
let _ = this.update(&mut cx, move |this, cx| {
|
let _ = this.update(&mut cx, move |this, cx| {
|
||||||
this.delegate.candidates = available_toolchains;
|
this.delegate.candidates = available_toolchains;
|
||||||
|
|
||||||
if let Some(active_toolchain) = active_toolchain {
|
if let Some(active_toolchain) = active_toolchain {
|
||||||
if let Some(position) = this
|
if let Some(position) = this
|
||||||
.delegate
|
.delegate
|
||||||
|
@ -170,7 +183,7 @@ impl ToolchainSelectorDelegate {
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
let placeholder_text = "Select a toolchain…".to_string().into();
|
||||||
Self {
|
Self {
|
||||||
toolchain_selector: language_selector,
|
toolchain_selector: language_selector,
|
||||||
candidates: Default::default(),
|
candidates: Default::default(),
|
||||||
|
@ -179,6 +192,7 @@ impl ToolchainSelectorDelegate {
|
||||||
workspace,
|
workspace,
|
||||||
worktree_id,
|
worktree_id,
|
||||||
worktree_abs_path_root,
|
worktree_abs_path_root,
|
||||||
|
placeholder_text,
|
||||||
_fetch_candidates_task,
|
_fetch_candidates_task,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +210,7 @@ impl PickerDelegate for ToolchainSelectorDelegate {
|
||||||
type ListItem = ListItem;
|
type ListItem = ListItem;
|
||||||
|
|
||||||
fn placeholder_text(&self, _cx: &mut WindowContext) -> Arc<str> {
|
fn placeholder_text(&self, _cx: &mut WindowContext) -> Arc<str> {
|
||||||
"Select a toolchain...".into()
|
self.placeholder_text.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_count(&self) -> usize {
|
fn match_count(&self) -> usize {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue