Skip to content

Commit

Permalink
fix(windows): remove leading drive letter slash
Browse files Browse the repository at this point in the history
  • Loading branch information
vonPB authored and pr2502 committed Aug 5, 2024
1 parent 247736b commit 474705a
Showing 1 changed file with 43 additions and 20 deletions.
63 changes: 43 additions & 20 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,49 @@ async fn connect(
Ok(())
}

// Parse a file path as String out of a LSP `URI` type.
fn parse_root_uri(root_uri: &str) -> Result<String> {
let (scheme, _, mut path, _, _) = URI::try_from(root_uri)
.context("failed to parse URI")?
.into_parts();

if scheme != uriparse::Scheme::File {
bail!("only `file://` URIs are supported");
}

path.normalize(false);

let root = percent_decode_str(&path.to_string())
.decode_utf8()
.context("decoded URI was not valid utf-8")?
.to_string();

// On windows the drive letter `C:/` gets interpreted as the first
// segment of an absolute path which results in an extra `/` at the
// beginning of the string representation which needs to be removed.
let root = match root.as_bytes() {
#[cfg(any(windows, test))]
[b'/', drive, b':', b'/', ..] if drive.is_ascii_alphabetic() => {
root.strip_prefix('/').unwrap().to_owned()
}
_ => root,
};

Ok(root)
}

#[cfg(test)]
#[test]
fn parsing_root_uris() {
use parse_root_uri as p;
assert_eq!(p("file:///home/user/proj").unwrap(), "/home/user/proj");
assert_eq!(p("file:///c:/dev/proj").unwrap(), "c:/dev/proj");
assert_eq!(p("file:///proj").unwrap(), "/proj");
assert_eq!(p("file:///d:/proj").unwrap(), "d:/proj");
assert_eq!(p("file:///").unwrap(), "/");
assert_eq!(p("file:///e:/").unwrap(), "e:/");
}

fn select_workspace_root<'a>(
init_params: &'a InitializeParams,
proxy_cwd: Option<&'a str>,
Expand All @@ -246,26 +289,6 @@ fn select_workspace_root<'a>(
debug!(workspace_folders = ?init_params.workspace_folders);
}

// Parse a file path as String out of a LSP `URI` type.
fn parse_root_uri(root_uri: &str) -> Result<String> {
let (scheme, _, mut path, _, _) = URI::try_from(root_uri)
.context("failed to parse URI")?
.into_parts();

if scheme != uriparse::Scheme::File {
bail!("only `file://` URIs are supported");
}

path.normalize(false);

let root = percent_decode_str(&path.to_string())
.decode_utf8()
.context("decoded URI was not valid utf-8")?
.to_string();

Ok(root)
}

if init_params.workspace_folders.len() == 1 {
return parse_root_uri(&init_params.workspace_folders[0].uri)
.context("parse initParams.workspaceFolders[0].uri");
Expand Down

0 comments on commit 474705a

Please sign in to comment.