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

View file

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

View file

@ -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] <paths...>
args:
<paths...> one or more paths to convert
<paths...> 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"));
}

View file

@ -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 $@`