task: Add ZED_PACKAGE task variable in Rust files. (#9491)
Piotr Osiewicz
and
Kirill
created 2 years ago
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 <kirill@zed.dev>
Change summary
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(-)
Detailed changes
@@ -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<Arc<dyn LspAdapter>> = $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 => {
@@ -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<LanguageContext> {
+ 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<LanguageServerBinary> {
async_maybe!({
let mut last = None;
@@ -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 {