1//! Provides support for language toolchains.
2//!
3//! A language can have associated toolchains,
4//! which is a set of tools used to interact with the projects written in said language.
5//! For example, a Python project can have an associated virtual environment; a Rust project can have a toolchain override.
6
7use std::{path::PathBuf, sync::Arc};
8
9use async_trait::async_trait;
10use collections::HashMap;
11
12use futures::future::BoxFuture;
13use gpui::{App, AsyncApp};
14use settings::WorktreeId;
15use task::ShellKind;
16use util::rel_path::RelPath;
17
18use crate::LanguageName;
19
20// Re-export core data types from language_core.
21pub use language_core::{Toolchain, ToolchainList, ToolchainMetadata, ToolchainScope};
22
23#[async_trait]
24pub trait ToolchainLister: Send + Sync + 'static {
25 /// List all available toolchains for a given path.
26 async fn list(
27 &self,
28 worktree_root: PathBuf,
29 subroot_relative_path: Arc<RelPath>,
30 project_env: Option<HashMap<String, String>>,
31 ) -> ToolchainList;
32
33 /// Given a user-created toolchain, resolve lister-specific details.
34 /// Put another way: fill in the details of the toolchain so the user does not have to.
35 async fn resolve(
36 &self,
37 path: PathBuf,
38 project_env: Option<HashMap<String, String>>,
39 ) -> anyhow::Result<Toolchain>;
40
41 fn activation_script(
42 &self,
43 toolchain: &Toolchain,
44 shell: ShellKind,
45 cx: &App,
46 ) -> BoxFuture<'static, Vec<String>>;
47
48 /// Returns various "static" bits of information about this toolchain lister. This function should be pure.
49 fn meta(&self) -> ToolchainMetadata;
50}
51
52#[async_trait(?Send)]
53pub trait LanguageToolchainStore: Send + Sync + 'static {
54 async fn active_toolchain(
55 self: Arc<Self>,
56 worktree_id: WorktreeId,
57 relative_path: Arc<RelPath>,
58 language_name: LanguageName,
59 cx: &mut AsyncApp,
60 ) -> Option<Toolchain>;
61}
62
63pub trait LocalLanguageToolchainStore: Send + Sync + 'static {
64 fn active_toolchain(
65 self: Arc<Self>,
66 worktree_id: WorktreeId,
67 relative_path: &Arc<RelPath>,
68 language_name: LanguageName,
69 cx: &mut AsyncApp,
70 ) -> Option<Toolchain>;
71}
72
73#[async_trait(?Send)]
74impl<T: LocalLanguageToolchainStore> LanguageToolchainStore for T {
75 async fn active_toolchain(
76 self: Arc<Self>,
77 worktree_id: WorktreeId,
78 relative_path: Arc<RelPath>,
79 language_name: LanguageName,
80 cx: &mut AsyncApp,
81 ) -> Option<Toolchain> {
82 self.active_toolchain(worktree_id, &relative_path, language_name, cx)
83 }
84}