From 07dbee8651b5e563fd1232627310761b143d759d Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 18 Mar 2024 12:18:42 +0100 Subject: [PATCH] task: Add ZED_PACKAGE task variable in Rust files. (#9491) This variable is experimental, as I expect it to be superseded by whatever the extensions can provide (once we get them) Release Notes: - Added experimental ZED_PACKAGE task variable which contains name of the current crate in Rust files. --------- Co-authored-by: Kirill --- crates/languages/src/lib.rs | 10 +++++++-- crates/languages/src/rust.rs | 42 ++++++++++++++++++++++++++++++++++++ crates/tasks_ui/src/lib.rs | 3 +++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/crates/languages/src/lib.rs b/crates/languages/src/lib.rs index c7b7527ef0a91e0f8c7d1f8a0b2ddfa8c402f779..f9c1dcd0affb2aaed772cd5a936b323c9cbf9ecf 100644 --- a/crates/languages/src/lib.rs +++ b/crates/languages/src/lib.rs @@ -7,6 +7,8 @@ use settings::Settings; use std::{str, sync::Arc}; use util::asset_str; +use crate::rust::RustContextProvider; + use self::{deno::DenoSettings, elixir::ElixirSettings}; mod astro; @@ -150,7 +152,7 @@ pub fn init( let config = load_config($name); // typeck helper let adapters: Vec> = $adapters; - for adapter in $adapters { + for adapter in adapters { languages.register_lsp_adapter(config.name.clone(), adapter); } languages.register_language( @@ -240,7 +242,11 @@ pub fn init( node_runtime.clone(), ))] ); - language!("rust", vec![Arc::new(rust::RustLspAdapter)]); + language!( + "rust", + vec![Arc::new(rust::RustLspAdapter)], + RustContextProvider + ); language!("toml", vec![Arc::new(toml::TaploLspAdapter)]); match &DenoSettings::get(None, cx).enable { true => { diff --git a/crates/languages/src/rust.rs b/crates/languages/src/rust.rs index 5b83249fb326bcc3b7f0452789b5ba5314655e1c..383ebbde535484ae9efe27b0752ea93f1f995339 100644 --- a/crates/languages/src/rust.rs +++ b/crates/languages/src/rust.rs @@ -317,6 +317,48 @@ impl LspAdapter for RustLspAdapter { } } +pub(crate) struct RustContextProvider; + +impl LanguageContextProvider for RustContextProvider { + fn build_context( + &self, + location: Location, + cx: &mut gpui::AppContext, + ) -> Result { + let mut context = DefaultContextProvider.build_context(location.clone(), cx)?; + if context.package.is_none() { + if let Some(path) = location.buffer.read(cx).file().and_then(|file| { + let local_file = file.as_local()?.abs_path(cx); + local_file.parent().map(PathBuf::from) + }) { + // src/ + // main.rs + // lib.rs + // foo/ + // bar/ + // baz.rs <|> + // /bin/ + // bin_1.rs + // + let Some(pkgid) = std::process::Command::new("cargo") + .current_dir(path) + .arg("pkgid") + .output() + .log_err() + else { + return Ok(context); + }; + let package_name = String::from_utf8(pkgid.stdout) + .map(|name| name.trim().to_owned()) + .ok(); + + context.package = package_name; + } + } + Ok(context) + } +} + async fn get_cached_server_binary(container_dir: PathBuf) -> Option { async_maybe!({ let mut last = None; diff --git a/crates/tasks_ui/src/lib.rs b/crates/tasks_ui/src/lib.rs index 4632cf1b5c2de0896b3be471ee20792305c8f9d8..80861f5657febd0967e9a9e90d37849ef35eb6cf 100644 --- a/crates/tasks_ui/src/lib.rs +++ b/crates/tasks_ui/src/lib.rs @@ -171,6 +171,9 @@ fn task_context( if let Some(symbol) = language_context.symbol { env.insert("ZED_SYMBOL".into(), symbol); } + if let Some(symbol) = language_context.package { + env.insert("ZED_PACKAGE".into(), symbol); + } } Some(TaskContext {