Skip to content
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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

phlowx
Copy link

@phlowx phlowx commented Mar 29, 2024

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}

@phlowx phlowx requested a review from PThorpe92 as a code owner March 29, 2024 04:11
Copy link
Contributor

@daviessm daviessm left a 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.

gierens
gierens previously approved these changes Mar 29, 2024
Copy link
Member

@gierens gierens left a 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 <phlowx@googlemail.com>
Co-authored-by: Sandro-Alessio Gierens <sandro@gierens.de>
Copy link
Member

@gierens gierens left a 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

@gierens gierens added os › windows enhancement New feature or request features › ui rust Pull requests that update Rust code labels Mar 29, 2024
Copy link

@opalmay opalmay left a 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));

@gierens
Copy link
Member

gierens commented Apr 1, 2024

This doesn't work for Windows paths mounted inside WSL.

@opalmay Thanks for the feedback, that's good to know.

I think wslpath -w should be used here. This works:

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.

@daviessm
Copy link
Contributor

daviessm commented Apr 1, 2024

Hm, interesting. I'm on Linux so I cannot evaluate this, @daviessm how about you?

No WSL here, sorry! Agreed on your other points though.

@opalmay
Copy link

opalmay commented Apr 1, 2024

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

@daviessm
Copy link
Contributor

daviessm commented Apr 2, 2024

@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.?

@opalmay
Copy link

opalmay commented Apr 7, 2024

@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

@daviessm
Copy link
Contributor

daviessm commented Apr 7, 2024

Cool, I can't do it myself but hopefully @PThorpe92 can give it a once-over and smash that merge button.

@opalmay
Copy link

opalmay commented Apr 8, 2024

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?

@daviessm
Copy link
Contributor

daviessm commented Apr 8, 2024

Should I create a separate PR?

Yes please. Reference it back to this one. 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request features › ui os › windows rust Pull requests that update Rust code
Projects
Status: 🆕 New
Development

Successfully merging this pull request may close these issues.

4 participants