1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
// region: auto_md_to_doc_comments include README.md A //!
//! # wsl_open_browser
//!
//! **Inside WSL2 opens a html file in the browser that is in Win10. The local file path is transformed between Linux and Win10 notation.**
//! ***[repository](https://github.com/LucianoBestia/wsl_open_browser); version: 2021.823.702 date: 2021-08-23 authors: Luciano Bestia***
//!
//! [![Lines in Rust code](https://img.shields.io/badge/Lines_in_Rust-45-green.svg)](https://github.com/LucianoBestia/wsl_open_browser/)
//! [![Lines in Doc comments](https://img.shields.io/badge/Lines_in_Doc_comments-150-blue.svg)](https://github.com/LucianoBestia/wsl_open_browser/)
//! [![Lines in Comments](https://img.shields.io/badge/Lines_in_comments-15-purple.svg)](https://github.com/LucianoBestia/wsl_open_browser/)
//! [![Lines in examples](https://img.shields.io/badge/Lines_in_examples-0-yellow.svg)](https://github.com/LucianoBestia/wsl_open_browser/)
//! [![Lines in tests](https://img.shields.io/badge/Lines_in_tests-0-orange.svg)](https://github.com/LucianoBestia/wsl_open_browser/)
//!
//! [![crates.io](https://img.shields.io/crates/v/cargo-auto.svg)](https://crates.io/crates/wsl_open_browser) [![Documentation](https://docs.rs/wsl_open_browser/badge.svg)](https://docs.rs/wsl_open_browser/) [![crev reviews](https://web.crev.dev/rust-reviews/badge/crev_count/wsl_open_browser.svg)](https://web.crev.dev/rust-reviews/crate/wsl_open_browser/) [![Lib.rs](https://img.shields.io/badge/Lib.rs-rust-orange.svg)](https://lib.rs/crates/wsl_open_browser/) [![Licence](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/LucianoBestia/wsl_open_browser/blob/master/LICENSE) [![Rust](https://github.com/LucianoBestia/wsl_open_browser/workflows/RustAction/badge.svg)](https://github.com/LucianoBestia/wsl_open_browser/)
//!
//! ## Try it
//!
//! Install it from crates.io and add 2 symbolic links and one env variable:
//!
//! ```bash
//! cargo install wsl_open_browser
//! sudo ln -sf "/mnt/c/Program Files/Mozilla Firefox/firefox.exe" /usr/bin/browser_in_win
//! export BROWSER='/usr/bin/wsl_open_browser'
//! # I like to use the short command `www` to open a browser
//! ln -sf "/usr/bin/wsl_open_browser" www
//!
//! # go to a directory that contains a subdirectory with index.html
//! cd ~/rustprojects/wsl_open_browser
//! www docs/index.html
//! # or
//! www docs
//! # or go inside the directory that contains index.html
//! cd docs
//! www .
//! # or simply
//! www
//! # if you want to open an URL
//! www rust-lang.org
//! ```
//!
//! Congratulations! You have just opened a windows browser from WSL2.
//!
//! ## Motivation
//!
//! Inside WSL2 I want to open a html file in the browser. But the browser is in Win10.
//! This is useful in Rust for the documentation:
//!
//! ```bash
//! cargo doc --open
//! ```
//!
//! or for simply open a file in a browser from bash:
//!
//! ```bash
//! www index.html
//! ```
//!
//! ## Open URL in Win10 Browser (first attempt)
//!
//! I prepared a symbolic link to the firefox exe.
//!
//! ```bash
//! ln -s "/mnt/c/Program Files/Mozilla Firefox/firefox.exe" /usr/bin/browser_in_win
//! # now I can open a page like this
//! browser_in_win http://github.com
//! # I want to open it with xdg-open
//! # xdg-open is the "Open any file" for linux
//! export BROWSER='/usr/bin/browser_in_win'
//! # now I can use
//! xdg-open http://rust-lang.org
//! ```
//!
//! This works great for URL, but it does not work for local files, because Linux and Windows see the same file with different paths.
//! The command `ln -sf` is permanent and persistent. It makes a file that stays there forever.
//! But `export BROWSER=` is NOT persistent. You need to add this command to `~/.bashrc` that runs it on every start of terminal.
//!
//! ## Open local file in Win10 Browser
//!
//! For example:
//! Linux: `/home/luciano/index.html`
//! Win10: `\\wsl$\Debian\home\luciano\index.html`
//! OR:
//! Linux: `/mnt/c/Users/Luciano/Downloads\index.html`
//! Win10: `c:\Users\Luciano\Downloads\index.html`
//!
//! I need a way to transform the path prior to call the browser.
//! Let's make a Rust CLI for that.
//!
//! ## Development
//!
//! This is a simple binary. For good habit I separated the lib from the bin.
//! Use [cargo auto](https://crates.io/crates/cargo-auto) to run automation tasks: build, release, doc, copy_to_usr_bin,....
//! After `cargo auto copy_to_usr_bin` we can now open the browser like this:
//!
//! ```bash
//! wsl_open_browser http://rust-lang.org
//! wsl_open_browser /home/luciano/index.html
//! wsl_open_browser /mnt/c/Users/Luciano/Downloads/index.html
//! wsl_open_browser docs/index.html
//! ```
//!
//! ## Open with xdg-open
//!
//! But I want to use xdg-open.
//! xdg-open is the "Open any file" for linux.
//! For that I need to set the environment variable BROWSER.
//! To make it persistent, copy this line to `~/.bashrc`.
//!
//! ```bash
//! export BROWSER='/usr/bin/wsl_open_browser'
//! ```
//!
//! Finally we can open the browser like this:
//!
//! ```bash
//! xdg-open http://rust-lang.org
//! xdg-open /home/luciano/index.html
//! xdg-open /mnt/c/Users/Luciano/Downloads/index.html
//! ```
//!
//! and the Rust documentation works fine:
//!
//! ```bash
//! cargo doc --open
//! ```
//!
//! ## simply: `www docs` or `www .`
//!
//! I am still not satisfied.
//! I want to open the browser from Debian bash terminal with this simple syntax:
//!
//! ```bash
//! www docs
//! www .
//! www rust-lang.org
//! ```
//!
//! I will make another alias:
//!
//! ```bash
//! ln -sf "/usr/bin/wsl_open_browser" www
//! ```
//!
//! The command `ln -sf` is permanent and persistent. It makes a file that stays there forever.
//!
// endregion: auto_md_to_doc_comments include README.md A //!
use unwrap::unwrap;
/// Inside WSL2 opens a html file in the browser that is in Win10
/// The local file path is transformed between Linux and Win10 notation.
/// If the argument is a directory then add index.html
/// If the argument is . then use the current directory
/// If there is no file, and the name contains something similar to an url, then open page on internet
pub fn open_browser(arg_1: &str) {
// region: Linux path
// expand the relative path to absolute Linux path
// canonicalize guarantee that the path exists
// if the path does not exist it is probably an url
let path = std::fs::canonicalize(arg_1);
match path {
Ok(path) => open_browser_from_path(path.as_path()),
Err(_err) => new_process_for_browser(arg_1),
}
}
/// open browser from absolute Linux path
fn open_browser_from_path(path: &std::path::Path) {
let path = if path.is_file() {
unwrap!(path.to_str()).to_string()
} else {
format!("{}/index.html", unwrap!(path.to_str()))
};
println!("path: {}", &path);
let mut arg = String::new();
if path.starts_with("/mnt/c/") {
// Linux: /mnt/c/Users/Luciano/Downloads\index.html
// Win10: c:\Users\Luciano\Downloads\index.html
arg = format!(r#"file:///c:/{}"#, path.trim_start_matches("/mnt/c/"));
} else if path.starts_with("/mnt/d/") {
// Linux: /mnt/d/Users/Luciano/Downloads\index.html
// Win10: d:\Users\Luciano\Downloads\index.html
arg = format!(r#"file:///d:/{}"#, path.trim_start_matches("/mnt/d/"));
} else if path.starts_with("/") {
// Linux: /home/luciano/index.html
// Win10: \\wsl$\Debian\home\luciano\index.html
arg = format!(r#"file://///wsl$/Debian{}"#, path.replace(r#"\"#, "/"));
}
println!("uri: {}", &arg);
new_process_for_browser(&arg);
}
/// open browser in new child process
fn new_process_for_browser(arg: &str) {
let child = unwrap!(std::process::Command::new("/usr/bin/browser_in_win")
.arg(arg)
// ignore stderr
.stderr(std::process::Stdio::null())
.spawn());
std::mem::forget(child);
}