path-convert: added support for programs that don't handle spaces in paths

This commit is contained in:
Valerie Wolfe 2024-06-05 14:12:42 -04:00
parent 46b81db6dc
commit d5e81e285f
4 changed files with 52 additions and 10 deletions

View file

@ -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 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 it easier to open programs like explorer from WSL. This solves hiccups from
paths like missing support for symbolic links, mismatched path separators, and paths like missing support for symbolic links, mismatched path separators,
resolves C-drive paths to their normal DOS forms. inability to handle spaces in directory names, and resolves C-drive paths to
their normal DOS form.

View file

@ -1,6 +1,6 @@
[package] [package]
name = "path-convert" name = "path-convert"
version = "0.0.3" version = "0.0.4"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View file

@ -1,11 +1,12 @@
use std::path::Path; use std::path::{ Path, PathBuf };
use pico_args::Arguments; use pico_args::Arguments;
const DRIVE: &str = "/mnt/c/"; const DRIVE: &str = "/mnt/c/";
const HELP: [&str;2] = [ "-h", "--help" ]; const HELP: [&str;2] = [ "-h", "--help" ];
const QUOTED: [&str;2] = [ "-q", "--quotes" ]; const NO_SPACES: [&str;2] = [ "-s", "--no-space" ];
const QUOTED: [&str;2] = [ "-q", "--quotes" ];
pub fn main() { pub fn main() {
let mut args = Arguments::from_env(); let mut args = Arguments::from_env();
@ -23,6 +24,9 @@ pub fn main() {
else { "'" } // -q -> '...' (output with single quotes) else { "'" } // -q -> '...' (output with single quotes)
} else { "" }; // _ -> ... (output with no quotes) } else { "" }; // _ -> ... (output with no quotes)
// collect no-space flag
let no_spaces = args.contains(NO_SPACES);
loop { loop {
let next = args.subcommand().unwrap(); let next = args.subcommand().unwrap();
if let Some(arg) = next { if let Some(arg) = next {
@ -35,6 +39,42 @@ pub fn main() {
output = arg; 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 // simple C-drive substitution
if output.starts_with(DRIVE) { if output.starts_with(DRIVE) {
output = output.replace(DRIVE, "C:\\"); output = output.replace(DRIVE, "C:\\");
@ -60,11 +100,12 @@ Canonicalize and convert Unix paths for DOS programs.
usage: path-convert [flags] <paths...> usage: path-convert [flags] <paths...>
args: args:
<paths...> one or more paths to convert <paths...> one or more paths to convert
flags: flags:
-h, --help show this help text -h, --help show this help text
-q, --quotes surround the output strings with quotes (-qq for double quotes) -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")); ", env!("CARGO_PKG_VERSION"));
} }

View file

@ -1,5 +1,5 @@
#!/usr/bin/bash #!/usr/bin/bash
# launch explorer with converted path(s) # launch explorer with converted path(s)
'/mnt/c/Windows/explorer.exe' `path-convert -q $@` '/mnt/c/Windows/explorer.exe' `path-convert -s $@`