diff --git a/README.md b/README.md index 7b29690..8c8ca23 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ These are tools I use to use Windows primarily through WSL. A Linux utility to canonicalize and convert paths from Unix to DOS, which makes it easier to open programs like explorer from WSL. This solves hiccups from -paths like missing support for symbolic links, mismatched path separators, and -resolves C-drive paths to their normal DOS forms. +paths like missing support for symbolic links, mismatched path separators, +inability to handle spaces in directory names, and resolves C-drive paths to +their normal DOS form. diff --git a/path-convert/Cargo.toml b/path-convert/Cargo.toml index 796c545..f8813a4 100644 --- a/path-convert/Cargo.toml +++ b/path-convert/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "path-convert" -version = "0.0.3" +version = "0.0.4" edition = "2021" [dependencies] diff --git a/path-convert/src/main.rs b/path-convert/src/main.rs index 4f464f5..6f8f841 100644 --- a/path-convert/src/main.rs +++ b/path-convert/src/main.rs @@ -1,11 +1,12 @@ -use std::path::Path; +use std::path::{ Path, PathBuf }; use pico_args::Arguments; const DRIVE: &str = "/mnt/c/"; -const HELP: [&str;2] = [ "-h", "--help" ]; -const QUOTED: [&str;2] = [ "-q", "--quotes" ]; +const HELP: [&str;2] = [ "-h", "--help" ]; +const NO_SPACES: [&str;2] = [ "-s", "--no-space" ]; +const QUOTED: [&str;2] = [ "-q", "--quotes" ]; pub fn main() { let mut args = Arguments::from_env(); @@ -23,6 +24,9 @@ pub fn main() { else { "'" } // -q -> '...' (output with single quotes) } else { "" }; // _ -> ... (output with no quotes) + // collect no-space flag + let no_spaces = args.contains(NO_SPACES); + loop { let next = args.subcommand().unwrap(); if let Some(arg) = next { @@ -35,6 +39,42 @@ pub fn main() { output = arg; } + // handle no-space flag + if no_spaces { + let tmp = output.clone(); + let parts = tmp.split('/'); + let mut current = PathBuf::new(); + current.push("/"); + for part in parts { + if part.is_empty() { continue; } + let space = part.chars().position(|c| c == ' '); + let len = part.len(); + // if space is found, use short version + if let Some(index) = space { + // find cut point and make slice + let cut = usize::min(len, index).min(6); + let replace = &(part[..cut]); + + // determine number for shortening + let mut index = 0; + let children = current.read_dir(); + if !children.is_ok() { continue; } + + for child in children.unwrap() { + if let Ok(child) = child { + let name: String = child.file_name().to_string_lossy().into(); + // matches increment + if name.to_lowercase().starts_with(&replace.to_lowercase()) { index += 1; } + // ... and break when we hit the target + if name == part { break; } + } + } + output = output.replacen(part, &format!("{replace}~{index}"), 1); + } + current.push(part); + } + } + // simple C-drive substitution if output.starts_with(DRIVE) { output = output.replace(DRIVE, "C:\\"); @@ -60,11 +100,12 @@ Canonicalize and convert Unix paths for DOS programs. usage: path-convert [flags] args: - one or more paths to convert + one or more paths to convert flags: - -h, --help show this help text - -q, --quotes surround the output strings with quotes (-qq for double quotes) + -h, --help show this help text + -q, --quotes surround the output strings with quotes (-qq for double quotes) + -s, --no-space don't allow paths to have spaces ", env!("CARGO_PKG_VERSION")); } diff --git a/scripts/explorer.sh b/scripts/explorer.sh index 41281bd..3eff002 100755 --- a/scripts/explorer.sh +++ b/scripts/explorer.sh @@ -1,5 +1,5 @@ #!/usr/bin/bash # launch explorer with converted path(s) -'/mnt/c/Windows/explorer.exe' `path-convert -q $@` +'/mnt/c/Windows/explorer.exe' `path-convert -s $@`