Auto merge of #14689 - Veykril:patch-vscode-paths, r=Veykril
fix: Force InitializeParams windows path drives to uppercase Should fix https://github.com/rust-lang/rust-analyzer/issues/14683 cc `@jyn514`
This commit is contained in:
commit
7bcb4c2ef2
@ -7,7 +7,11 @@
|
||||
mod logger;
|
||||
mod rustc_wrapper;
|
||||
|
||||
use std::{env, fs, path::Path, process};
|
||||
use std::{
|
||||
env, fs,
|
||||
path::{Path, PathBuf},
|
||||
process,
|
||||
};
|
||||
|
||||
use lsp_server::Connection;
|
||||
use rust_analyzer::{cli::flags, config::Config, from_json, Result};
|
||||
@ -149,12 +153,18 @@ fn run_server() -> Result<()> {
|
||||
|
||||
let (initialize_id, initialize_params) = connection.initialize_start()?;
|
||||
tracing::info!("InitializeParams: {}", initialize_params);
|
||||
let initialize_params =
|
||||
from_json::<lsp_types::InitializeParams>("InitializeParams", &initialize_params)?;
|
||||
let lsp_types::InitializeParams {
|
||||
root_uri,
|
||||
capabilities,
|
||||
workspace_folders,
|
||||
initialization_options,
|
||||
client_info,
|
||||
..
|
||||
} = from_json::<lsp_types::InitializeParams>("InitializeParams", &initialize_params)?;
|
||||
|
||||
let root_path = match initialize_params
|
||||
.root_uri
|
||||
let root_path = match root_uri
|
||||
.and_then(|it| it.to_file_path().ok())
|
||||
.map(patch_path_prefix)
|
||||
.and_then(|it| AbsPathBuf::try_from(it).ok())
|
||||
{
|
||||
Some(it) => it,
|
||||
@ -164,19 +174,19 @@ fn run_server() -> Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
let workspace_roots = initialize_params
|
||||
.workspace_folders
|
||||
let workspace_roots = workspace_folders
|
||||
.map(|workspaces| {
|
||||
workspaces
|
||||
.into_iter()
|
||||
.filter_map(|it| it.uri.to_file_path().ok())
|
||||
.map(patch_path_prefix)
|
||||
.filter_map(|it| AbsPathBuf::try_from(it).ok())
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.filter(|workspaces| !workspaces.is_empty())
|
||||
.unwrap_or_else(|| vec![root_path.clone()]);
|
||||
let mut config = Config::new(root_path, initialize_params.capabilities, workspace_roots);
|
||||
if let Some(json) = initialize_params.initialization_options {
|
||||
let mut config = Config::new(root_path, capabilities, workspace_roots);
|
||||
if let Some(json) = initialization_options {
|
||||
if let Err(e) = config.update(json) {
|
||||
use lsp_types::{
|
||||
notification::{Notification, ShowMessage},
|
||||
@ -205,7 +215,7 @@ fn run_server() -> Result<()> {
|
||||
|
||||
connection.initialize_finish(initialize_id, initialize_result)?;
|
||||
|
||||
if let Some(client_info) = initialize_params.client_info {
|
||||
if let Some(client_info) = client_info {
|
||||
tracing::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
|
||||
}
|
||||
|
||||
@ -219,3 +229,42 @@ fn run_server() -> Result<()> {
|
||||
tracing::info!("server did shut down");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn patch_path_prefix(path: PathBuf) -> PathBuf {
|
||||
use std::path::{Component, Prefix};
|
||||
if cfg!(windows) {
|
||||
// VSCode might report paths with the file drive in lowercase, but this can mess
|
||||
// with env vars set by tools and build scripts executed by r-a such that it invalidates
|
||||
// cargo's compilations unnecessarily. https://github.com/rust-lang/rust-analyzer/issues/14683
|
||||
// So we just uppercase the drive letter here unconditionally.
|
||||
// (doing it conditionally is a pain because std::path::Prefix always reports uppercase letters on windows)
|
||||
let mut comps = path.components();
|
||||
match comps.next() {
|
||||
Some(Component::Prefix(prefix)) => {
|
||||
let prefix = match prefix.kind() {
|
||||
Prefix::Disk(d) => {
|
||||
format!("{}:", d.to_ascii_uppercase() as char)
|
||||
}
|
||||
Prefix::VerbatimDisk(d) => {
|
||||
format!(r"\\?\{}:\", d.to_ascii_uppercase() as char)
|
||||
}
|
||||
_ => return path,
|
||||
};
|
||||
let mut path = PathBuf::new();
|
||||
path.push(prefix);
|
||||
path.extend(comps);
|
||||
path
|
||||
}
|
||||
_ => path,
|
||||
}
|
||||
} else {
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(windows)]
|
||||
fn patch_path_prefix_works() {
|
||||
assert_eq!(patch_path_prefix(r"c:\foo\bar".into()), PathBuf::from(r"C:\foo\bar"));
|
||||
assert_eq!(patch_path_prefix(r"\\?\c:\foo\bar".into()), PathBuf::from(r"\\?\C:\foo\bar"));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user