-
-
Notifications
You must be signed in to change notification settings - Fork 218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Make hyperlinks useable inside a WSL environment #913
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks sensible to me, as long as it's tested this looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, too, let's see what CI says.
If the environment variable "$WSL_DISTRO_NAME" is set, the hyperlink is modified so that the file/folder can be opened directly via Windows Explorer. To open a file in a WSL environmen the link must be as follows: file://wsl$/${WSL_DISTRO_NAME}/{abs_path} Co-authored-by: phlowx <[email protected]> Co-authored-by: Sandro-Alessio Gierens <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, I fixed the fmt, clippy and convco issues, now it passes CI.
Thanks for your contribution @phlowx ... LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't work for Windows paths mounted inside WSL.
I think wslpath -w
should be used here.
This works:
let distro_name = std::env::var("WSL_DISTRO_NAME");
let abs_path_transformed = if distro_name.is_ok() {
std::process::Command::new("wslpath")
.arg("-w")
.arg(&abs_path)
.output()
.map_or(abs_path.clone(), |output| {
String::from_utf8(output.stdout).unwrap_or(abs_path.clone())
})
} else {
abs_path.clone()
};
let hyperlink = format!("{HYPERLINK_START}file://{abs_path_transformed}{HYPERLINK_END}");
bits.push(ANSIString::from(hyperlink));
@opalmay Thanks for the feedback, that's good to know.
Hm, interesting. I'm on Linux so I cannot evaluate this, @daviessm how about you? I am a little worried about performance with this approach though. I mean sure this would only be executed when the WSL env variable is set and hyperlinks are requested, but spawning a process for every file seems like something we should avoid. There are a few crates for wslpath, this one looks particularly interesting: https://crates.io/crates/wslpath-rs because it seems to do the conversion in rust. Update: I just looked at this crate, since its under 200 lines and two functions, so maybe we could even avoid to add another dependency and simply paraphrase the code we need and reference it. |
No WSL here, sorry! Agreed on your other points though. |
I don't actually know Rust, but here's what I came up with: let distro_name = std::env::var("WSL_DISTRO_NAME").ok();
let path = if let Some(distro_name) = distro_name {
if !abs_path.starts_with("/mnt/") {
format!("wsl$/{distro_name}{abs_path}")
} else {
let parts: Vec<&str> = abs_path.split('/').collect();
if parts.len() > 2 && parts[2].len() == 1 && parts[2].chars().next().unwrap().is_ascii_alphabetic() {
let mut windows_path = format!("{}:\\", parts[2].to_uppercase());
for part in &parts[3..] {
if !part.is_empty() {
windows_path.push_str(part);
windows_path.push('\\');
}
}
windows_path
} else {
format!("wsl$/{distro_name}{abs_path}")
}
}
} else {
abs_path
};
let hyperlink = format!("{HYPERLINK_START}file://{path}{HYPERLINK_END}");
bits.push(ANSIString::from(hyperlink)); I guess I could say I know a bit of Rust now |
@opalmay Looks promising! Have you tested each of the code paths to make sure they work, and with different types of paths (directories, files, network shares (if that's possible in WSL) etc.? |
Yes! It works for both types of paths in WSL: Linux and Windows mounted |
Cool, I can't do it myself but hopefully @PThorpe92 can give it a once-over and smash that merge button. |
Should I create a separate PR? |
Yes please. Reference it back to this one. 😄 |
Modification of the --hyperlink parameter so that it also works in a WSL environment
If the environment variable "$WSL_DISTRO_NAME" is set, the hyperlink is modified so that the file/folder can be opened directly via Windows Explorer.
To open a file in a WSL environmen the link must be as follows: file://wsl$/${WSL_DISTRO_NAME}/{abs_path}