Skip to content

Commit 07dbd2b

Browse files
authored
Use rust-analyzer from path if possible (#12418)
Release Notes: - Added support for looking up the `rust-analyzer` binary in `$PATH`. This allows using such tools as `asdf` and nix to configure per-folder rust installations. To enable this behavior, use the `path_lookup` key when configuring the `rust-analyzer` `binary`: `{"lsp": {"rust-analyzer": {"binary": {"path_lookup": true }}}}`.
1 parent 4858116 commit 07dbd2b

4 files changed

Lines changed: 84 additions & 52 deletions

File tree

‎crates/languages/src/c.rs‎

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,28 +35,33 @@ impl super::LspAdapter for CLspAdapter {
3535
.and_then(|s| s.binary.clone())
3636
});
3737

38-
if let Ok(Some(BinarySettings {
39-
path: Some(path),
40-
arguments,
41-
})) = configured_binary
42-
{
43-
Some(LanguageServerBinary {
38+
match configured_binary {
39+
Ok(Some(BinarySettings {
40+
path: Some(path),
41+
arguments,
42+
..
43+
})) => Some(LanguageServerBinary {
4444
path: path.into(),
4545
arguments: arguments
4646
.unwrap_or_default()
4747
.iter()
4848
.map(|arg| arg.into())
4949
.collect(),
5050
env: None,
51-
})
52-
} else {
53-
let env = delegate.shell_env().await;
54-
let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
55-
Some(LanguageServerBinary {
56-
path,
57-
arguments: vec![],
58-
env: Some(env),
59-
})
51+
}),
52+
Ok(Some(BinarySettings {
53+
path_lookup: Some(false),
54+
..
55+
})) => None,
56+
_ => {
57+
let env = delegate.shell_env().await;
58+
let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
59+
Some(LanguageServerBinary {
60+
path,
61+
arguments: vec![],
62+
env: Some(env),
63+
})
64+
}
6065
}
6166
}
6267

‎crates/languages/src/go.rs‎

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -78,28 +78,33 @@ impl super::LspAdapter for GoLspAdapter {
7878
.and_then(|s| s.binary.clone())
7979
});
8080

81-
if let Ok(Some(BinarySettings {
82-
path: Some(path),
83-
arguments,
84-
})) = configured_binary
85-
{
86-
Some(LanguageServerBinary {
81+
match configured_binary {
82+
Ok(Some(BinarySettings {
83+
path: Some(path),
84+
arguments,
85+
..
86+
})) => Some(LanguageServerBinary {
8787
path: path.into(),
8888
arguments: arguments
8989
.unwrap_or_default()
9090
.iter()
9191
.map(|arg| arg.into())
9292
.collect(),
9393
env: None,
94-
})
95-
} else {
96-
let env = delegate.shell_env().await;
97-
let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
98-
Some(LanguageServerBinary {
99-
path,
100-
arguments: server_binary_arguments(),
101-
env: Some(env),
102-
})
94+
}),
95+
Ok(Some(BinarySettings {
96+
path_lookup: Some(false),
97+
..
98+
})) => None,
99+
_ => {
100+
let env = delegate.shell_env().await;
101+
let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
102+
Some(LanguageServerBinary {
103+
path,
104+
arguments: server_binary_arguments(),
105+
env: Some(env),
106+
})
107+
}
103108
}
104109
}
105110

‎crates/languages/src/rust.rs‎

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use http::github::{latest_github_release, GitHubLspBinaryVersion};
77
pub use language::*;
88
use lazy_static::lazy_static;
99
use lsp::LanguageServerBinary;
10-
use project::project_settings::ProjectSettings;
10+
use project::project_settings::{BinarySettings, ProjectSettings};
1111
use regex::Regex;
1212
use settings::Settings;
1313
use smol::fs::{self, File};
@@ -35,29 +35,50 @@ impl LspAdapter for RustLspAdapter {
3535

3636
async fn check_if_user_installed(
3737
&self,
38-
_delegate: &dyn LspAdapterDelegate,
38+
delegate: &dyn LspAdapterDelegate,
3939
cx: &AsyncAppContext,
4040
) -> Option<LanguageServerBinary> {
41-
let binary = cx
42-
.update(|cx| {
43-
ProjectSettings::get_global(cx)
44-
.lsp
45-
.get(Self::SERVER_NAME)
46-
.and_then(|s| s.binary.clone())
47-
})
48-
.ok()??;
49-
50-
let path = binary.path?;
51-
Some(LanguageServerBinary {
52-
path: path.into(),
53-
arguments: binary
54-
.arguments
55-
.unwrap_or_default()
56-
.iter()
57-
.map(|arg| arg.into())
58-
.collect(),
59-
env: None,
60-
})
41+
let configured_binary = cx.update(|cx| {
42+
ProjectSettings::get_global(cx)
43+
.lsp
44+
.get(Self::SERVER_NAME)
45+
.and_then(|s| s.binary.clone())
46+
});
47+
48+
match configured_binary {
49+
Ok(Some(BinarySettings {
50+
path,
51+
arguments,
52+
path_lookup,
53+
})) => {
54+
let (path, env) = match (path, path_lookup) {
55+
(Some(path), lookup) => {
56+
if lookup.is_some() {
57+
log::warn!(
58+
"Both `path` and `path_lookup` are set, ignoring `path_lookup`"
59+
);
60+
}
61+
(Some(path.into()), None)
62+
}
63+
(None, Some(true)) => {
64+
let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
65+
let env = delegate.shell_env().await;
66+
(Some(path), Some(env))
67+
}
68+
(None, Some(false)) | (None, None) => (None, None),
69+
};
70+
path.map(|path| LanguageServerBinary {
71+
path,
72+
arguments: arguments
73+
.unwrap_or_default()
74+
.iter()
75+
.map(|arg| arg.into())
76+
.collect(),
77+
env,
78+
})
79+
}
80+
_ => None,
81+
}
6182
}
6283

6384
async fn fetch_latest_server_version(

‎crates/project/src/project_settings.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ const fn true_value() -> bool {
9494
pub struct BinarySettings {
9595
pub path: Option<String>,
9696
pub arguments: Option<Vec<String>>,
97+
pub path_lookup: Option<bool>,
9798
}
9899

99100
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]

0 commit comments

Comments
 (0)