Compare commits

..

No commits in common. "main" and "qdls" have entirely different histories.
main ... qdls

48 changed files with 65 additions and 1095 deletions

View file

@ -1,2 +1 @@
/target
Cargo.lock

View file

@ -1,26 +1,7 @@
# Winure: WSL inurement tools
These are tools I use to use Windows primarily through WSL. Many are
cross-dependent.
## `dos-var`
Gets Windows environment variables from DOS.
## `env-share`
A hacked-together utility for sending WSL variables back to Windows
shells. The utility runs in WSL, and companion scripts run in Windows.
## `hug`
A barebones command wrapper for turning binary-output text into normal text.
## `mkwin`
A Linux utility to quickly make a bash script to run a Windows executable with
certain parameters.
These are tools I use to use Windows primarily through WSL.
## `path-convert`
@ -32,27 +13,5 @@ their normal DOS form.
## `qdls`
A feature-barren DOS clone of `ls` that hides Windows hidden files. Relies on
`dotnet-warp` as a build dependency.
---
## Scripts
- `charmap.sh`: Simple wrapper for Character Map.
- `cmd.sh`: Simple wrapper for `cmd.exe`.
- `dos.sh`: Simple wrapper for executing Windows commands directly.
- `elevate.sh`: Elevate WSL (`-l`) or Windows (`-w`) commands from WSL.
- `explorer.sh`: Launch explorer from WSL.
- `pwsh.sh`: Launch PowerShell Core.
- `sqlcmd.sh`: Simple wrapper for `sqlcmd.exe`.
- `wsl.sh`: A wrapper for `wsl.exe` that wraps in `hug` when piped.
- `wt.sh`: Launch Windows Terminal.
---
## Windows Man Pages
- `cmd(8)`: `cmd.exe`
- `wt(1)`: Windows Terminal
A DOS clone of `ls` that hides Windows hidden files.

View file

@ -1,15 +0,0 @@
[package]
name = "dos-var"
version = "0.0.2"
edition = "2021"
[dependencies]
pico-args = "0.5.0"
[profile.release]
opt-level = 's'
codegen-units = 1
debug = false
lto = true
panic = "abort"
strip = "symbols"

View file

@ -1,10 +0,0 @@
alias b := build
alias i := install
build:
cargo build --release
install DIR: build
cp ./target/release/dos-var "{{DIR}}/dos-var"

View file

@ -1,13 +0,0 @@
use std::process::exit;
pub fn not_found(target: &String) {
eprintln!("dos-var: %{target}% has no value");
exit(1);
}
pub fn missing_arg() {
eprintln!("dos-var: no argument found");
exit(2);
}

View file

@ -1,40 +0,0 @@
use std::process::Command;
use pico_args::Arguments;
mod error;
const CMD: &str = "/mnt/c/Windows/System32/cmd.exe";
const FLAG_PATH: [&str; 2] = [ "-p", "--path" ];
pub fn main() {
let mut args = Arguments::from_env();
let convert_path = args.contains(FLAG_PATH);
if let Ok(Some(target)) = args.subcommand() {
let cmd = Command::new(CMD)
.current_dir("/mnt/c/")
.arg( format!("/C echo %{target}%") )
.output();
if let Ok(output) = cmd {
if let Ok(stdout) = String::from_utf8(output.stdout) {
// trim output
let stdout = stdout.trim_end_matches("\"\r\n");
// catch empty variable case
if stdout == format!("%{target}%") { error::not_found(&target); }
// handle path flag and write
let path =
if convert_path {
stdout
.replace("\\", "/")
.replace("C:/", "/mnt/c/")
} else { stdout.to_owned() };
println!("{path}");
}
}
} else { error::missing_arg(); }
}

View file

@ -1,2 +0,0 @@
/target
Cargo.lock

View file

@ -1,12 +0,0 @@
[package]
name = "env-share"
version = "0.0.2"
edition = "2021"
[profile.release]
opt-level = 's'
codegen-units = 1
debug = false
lto = true
panic = "abort"
strip = "symbols"

View file

@ -1,11 +0,0 @@
alias b := build
alias i := install
build:
cargo build --release
install DIR: build
cp ./target/release/env-share "{{DIR}}/env-share"

View file

@ -1,18 +0,0 @@
# make sure the file exists
$file = $env:ENV_SHARE_FILE
if(-not (Test-Path $file)) {
exit
}
# insert values into env
foreach($line in Get-Content $file) {
$parts = $line -split ' = '
$var = $parts[0]
$value = $parts[1]
Set-Item env:$var -Value $value
}
# delete the file
Remove-Item $file

View file

@ -1,19 +0,0 @@
#!/usr/bin/bash
# make sure file is present
file=$ENV_SHARE_FILE
if [[ ! -r "$file" ]]; then
return
fi
# read lines and set variables
IFS=' = '
while read line; do
var=${line%$IFS*}
value=${line#*$IFS}
export $var=$value
done <$file
# delete file
rm $file

View file

@ -1,18 +0,0 @@
use std::process::exit;
pub fn file_unset() {
eprintln!("env-share: ENV_SHARE_FILE is unset");
exit(1);
}
pub fn vars_unset() {
eprintln!("env-share: ENV_SHARE_VARS is unset");
exit(1);
}
pub fn write_fail(file: &String) {
eprintln!("env-share: failed to write to '{file}'");
exit(2);
}

View file

@ -1,31 +0,0 @@
use std::{
env,
fs::write
};
mod error;
fn main() {
// try to get share file variable
if let Ok(file) = env::var("ENV_SHARE_FILE") {
if let Ok(var_string) = env::var("ENV_SHARE_VARS") {
// build output
let mut output = String::new();
let vars = var_string.split(':');
for var in vars {
let value = env::var(var).unwrap_or(String::new());
if value.is_empty() { continue; }
output += &format!("{var} = {value}\n");
}
// write to file
let result = write(&file, output);
match result {
Err(_) => error::write_fail(&file),
_ => { }
}
} else { error::vars_unset(); }
} else { error::file_unset(); }
}

2
hug/.gitignore vendored
View file

@ -1,2 +0,0 @@
/target
Cargo.lock

View file

@ -1,13 +0,0 @@
[package]
name = "hug"
version = "0.0.1"
edition = "2021"
[profile.release]
opt-level = 's'
codegen-units = 1
debug = false
lto = true
panic = "abort"
strip = "symbols"

View file

@ -1,10 +0,0 @@
alias b := build
alias i := install
build:
cargo build --release
install DIR: build
cp ./target/release/hug "{{DIR}}/hug"

View file

@ -1,32 +0,0 @@
use std::{
env,
process::{ Command, Stdio }
};
fn main() {
let mut args: Vec<String> = env::args().collect();
args.remove(0);
let target = args.remove(0);
let command = Command::new(target)
.args(args)
.stderr(Stdio::inherit())
.output();
if let Ok(output) = command {
let mut line = String::new();
for byte in output.stdout {
match char::from_u32(byte.into()) {
Some('\n') => {
println!("{line}");
line = String::new();
},
Some('\0') |
None => continue,
Some(c) => line.push(c),
}
}
}
}

View file

@ -1,22 +0,0 @@
alias b := build
alias i := install
build TARGET:
just {{TARGET}}/build
install TARGET='all' DIR="/usr/local/bin":
#!/usr/bin/bash
if [[ {{TARGET}} == 'all' ]]; then
just install scripts {{DIR}}
just install dos-var {{DIR}}
just install env-share {{DIR}}
just install hug {{DIR}}
just install mkwin {{DIR}}
just install path-convert {{DIR}}
just install qdls {{DIR}}
just install man
else
just {{TARGET}}/install `realpath {{DIR}}`
fi

107
man/cmd.8
View file

@ -1,107 +0,0 @@
.Dd $Mdocdate$
.Dt CMD 8
.Os MICROSOFT WINDOWS
.Sh NAME
.Nm cmd
.Nd Windows Command Prompt
.Sh SYNOPSIS
.Nm
.Op Fl DQ
.Op Fl A|U
.Op Oo Fl S Oc Fl C|K Ar command
.Op Fl E Ns = Ns Ar ON|OFF
.Op Fl T Ns = Ns Ar fb
.Op Fl V Ns = Ns Ar ON|OFF
.Sh DESCRIPTION
.Nm
is a Linux wrapper for Windows Command Prompt. Its options are as follows:
.Bl -tag -width Ds
.It Fl ?
Displays a fairly unhelpful and incomplete help text.
.It Fl A
Standard outputs will be redirected in ANSI.
.It Fl C Ar command
Executes the specified command and exits.
.It Fl D
Disables autorun commands. See
.Sx AUTORUN
below.
.It Fl E Ns = Ns Ar ON|OFF
Enable or disable command extensions. See
.Sx COMMAND EXTENSIONS
below.
.It Fl F Ns = Ns Ar ON|OFF
Enable or disable filename completion. See
.Sx FILENAME COMPLETION
below.
.It Fl K Ar command
Executes the specified command, then become interactive.
.It Fl Q
Disables echoing commands for non-interactive modes.
.It Fl S
Modifies input handling. See
.Sx MODIFIED INPUT HANDLING
below.
.It Fl T Ns = Ns Ar fb
Output will use colors as if 'color xx' was called; the first digit sets the foreground color, and the second digit sets the background color.
.It Fl U
Standard outputs will be redirected in Unicode.
.It Fl V Ns = Ns Ar ON|OFF
Enable or disable execution-time environment variable expansion. See
.Sx EXECUTION-TIME ENVIRONMENT VARIABLE EXPANSION
below.
.Sh BEHAVIORS
.Ss AUTORUN
Autorun is enabled by default, and can be disabled with the
.Fl D
flag. If enabled, the program will search registry variables
.Cd HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
and
.Cd HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun
for commands at startup and execute them if present.
.Ss COMMAND EXTENSIONS
Command extensions are enabled by default, and can be disabled by setting
.Fl E Ns = Ns OFF .
Extensions can modify the following commands:
.Pp
.Ic DEL or Ic ERASE ,
.Ic COLOR ,
.Ic CD or Ic CHDIR ,
.Ic MD or Ic MKDIR ,
.Ic PROMPT ,
.Ic PUSHD ,
.Ic POPD ,
.Ic SET ,
.Ic SETLOCAL ,
.Ic ENDLOCAL ,
.Ic IF ,
.Ic FOR ,
.Ic CALL ,
.Ic SHIFT ,
.Ic GOTO ,
.Ic START ,
.Ic ASSOC ,
.Ic FTYPE
.Ss EXECUTION-TIME ENVIRONMENT VARIABLE EXPANSION
Execution-time environment variable expansion is disabled by default, and can be enabled by setting
.Fl V Ns = Ns OFF .
If enabled, enclosing a variable name with '!' characters will substitute the variable's value at command execution time.
.Ss FILENAME COMPLETION
Filename completion is disabled by default, and can be enabled by setting
.Fl F Ns = Ns ON .
If enabled, Ctrl-D and Ctrl-F can be used for directory and file completion respectively.
.Ss MODIFIED INPUT HANDLING
If the
.Fl S
flag is present, the program will strip the leading and trailing quotes from the
.Ar command
supplied to
.Fl C
or
.Fl K
and pass the remaining string literally as if it was typed directly into the prompt, ignoring special characters.
.Sh BUGS
.Nm
lacks escape characters, meaning arguments with special characters
.Em must
be enclosed in quotes.

View file

@ -1,35 +0,0 @@
.Dd $Mdocdate$
.Dt DOS-VAR 1
.Os WSL
.Sh NAME
.Nm dos-var
.Nd gets DOS environment variables from WSL
.Sh SYNOPSIS
.Nm
.Op Fl p
.Ar variable
.Sh DESCRIPTION
The
.Nm
utility gets a DOS environment variable from within WSL. It can also convert paths to UNIX.
.Bl -tag -width Ds
.It Fl p , Fl -path
The target DOS variable contains a path, and will be converted.
.It Ar variable
The name of the target DOS variable.
.El
.Sh EXIT STATUS
.Bl -tag -width Ds
.It 1
The target variable is empty.
.It 2
No target variable was provided.
.El
.Sh EXAMPLES
Navigate to the Windows user directory:
.Pp
.Dl $ cd `dos-var -p USERPROFILE`
.Pp
.Sh Authors
.An -nosplit
.An Valerie Wolfe Aq Mt sleeplessval@gmail.com

View file

@ -1,30 +0,0 @@
.Dd $Mdocdate$
.Dt ENV-SHARE 1
.Os WSL
.Sh NAME
.Nm env-share
.Nd share environment variables back to Windows from WSL
.Sh SYNOPSIS
.Nm env-share
.Sh DESCRIPTION
The
.Nm
utility writes environment variables to a file to be loaded by a companion script in the target process.
.Sh ENVIRONMENT
.Bl -tag -width Ds
.It Ev ENV_SHARE_FILE
The file to write variables to.
.It Ev ENV_SHARE_VARS
A colon-separated list of variables to copy.
.El
.Sh EXIT STATUS
.Bl -tag -width Ds
.It 1
An environment variable is unset.
.It 2
Failed to write to the file at
.Ev ENV_SHARE_FILE
.El
.Sh AUTHORS
.An -nosplit
.An Valerie Wolfe Aq Mt sleeplessval@gmail.com

View file

@ -1,25 +0,0 @@
.Dd $Mdocdate$
.Dt HUG 1
.Os WSL
.Sh NAME
.Nm hug
.Nd wraps processes and converts binary output to text
.Sh SYNOPSIS
.Nm
.Ar target
.Op Ar args...
.Sh DESCRIPTION
The
.Nm
utility runs a process and emits bytes from standard output to text.
.Sh EXAMPLES
WSL's help text is output as binary content, preventing piping to utilities like
.Xr less 1
or
.Xr bat 1 :
.Pp
.Dl $ hug wsl --help | less
.Pp
.Sh Authors
.An -nosplit
.An Valerie Wolfe Aq Mt sleeplessval@gmail.com

View file

@ -1,7 +0,0 @@
alias i := install
install DIR="(unused)":
sudo cp ./*.1 /usr/share/man/man1/
sudo cp ./*.8 /usr/share/man/man8/

View file

@ -1,71 +0,0 @@
.Dd $Mdocdate$
.Dt MKWIN 1
.Os WSL
.Sh NAME
.Nm mkwin
.Nd generate bash scripts for running Windows programs from WSL
.Sh SYNOPSIS
.Nm mkwin
.Op Fl heEq
.Op Fl -find Ar root
.Op Fl -pc Ar flags
.Ar target
.Op Fl -or Ar alt
.Op Ar --\ args
.Sh DESCRIPTION
The
.Nm
utility generates bash scripts for executing Windows executables from WSL, and prints them to the standard output. The options are as follows:
.Bl -tag -width Ds
.It Ar --\ args
The resulting script will forward the provided arguments.
.It Fl e , Fl -empty
The resulting script will not pass arguments to the target binary.
.It Fl E , Fl -env-share
The resulting script will call the
.Xr env-share 1
utility.
.It Fl -find Ar root
The resulting script will locate the target binary in the given directory using
.Xr find 1 .
.It Fl h , Fl -help
Print a short help message.
.It Fl -or Ar fallback
The resulting script will fall back to the provided argument if the target is not executable.
.It Fl -pc Ar flags
The resulting script will pass the arguments converted with
.Xr path-convert 1 . path-convert will be invoked with the provided flags forwarded (use 'x' to forward no flags).
.It Fl q , Fl -quiet
The resulting script will redirect output to /dev/null and send the target to the background.
.El
.Sh EXIT STATUS
.Bl -tag -width Ds
.It 1
No
.Ar target
was provided.
.It 2
Path canonicalization failed; this typically indicates the
.Ar target
points to a file or directory that does not exist.
.El
.Sh EXAMPLES
Windows Explorer does not accept paths with spaces when executed from WSL. To generate a script to launch Windows Explorer:
.Pp
.Dl $ mkwin --pc=sqq /mnt/c/Windows/System32/explorer.exe > explorer.sh
.Pp
Windows Terminal's executable moves when updated. To generate a script to launch Windows Terminal:
.Pp
.Dl $ mkwin --empty --find='/mnt/c/Program Files/WindowsApps/Microsoft.WindowsTerminal*' WindowsTerminal.exe > wt.sh
.Pp
PowerShell has two versions (Core is user-installed) and doesn't inherit environment variables from WSL. To generate a script to call PowerShell Core with a fallback to Windows PowerShell and shared environment variables:
.Pp
.Dl $ mkwin -E '/mnt/c/Program Files/PowerShell/7/pwsh.exe' --or '/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe'
.Pp
.Sh SEE ALSO
.Xr env-share 1 ,
.Xr find 1 ,
.Xr path-convert 1
.Sh AUTHORS
.An -nosplit
.An Valerie Wolfe Aq Mt sleeplessval@gmail.com .

View file

@ -1,36 +0,0 @@
.Dd $Mdocdate$
.Dt PATH-CONVERT 1
.Os WSL
.Sh NAME
.Nm path-convert
.Nd canonicalize and convert Unix paths for use with DOS programs
.Sh SYNOPSIS
.Nm path-convert
.Op Fl hnqs
.Ar
.Sh DESCRIPTION
The
.Nm
utility converts UNIX paths to DOS, for command substituting paths when invoking Windows executables from the terminal in WSL.
.Pp
Arguments that fail to canonicalize will be passed through as-is.
.Pp
Its options are as follows:
.Bl -tag -width Ds
.It Fl h , Fl -help
Displays a short help text.
.It Fl n , Fl -network
Adds the WSL network path where appropriate.
.It Fl q , Fl -quotes
Surrounds each converted path with single quotes (-q) or double quotes (-qq).
.It Fl s , Fl -no-space
Uses DOS shortening for directories in the path whose name contains spaces.
.El
.Sh ENVIRONMENT
.Bl -tag -width Ds
.It Ev WSL_DISTRO_NAME
This should be auto-set by WSL, and contains the name of the current distribution.
.El
.Sh AUTHORS
.An -nosplit
.An Valerie Wolfe Aq Mt sleeplessval@gmail.com .

View file

@ -1,47 +0,0 @@
.Dd $Mdocdate$
.Dt WT 1
.Os MICROSOFT WINDOWS
.Sh NAME
.Nm wt
.Nd Windows Terminal
.Sh SYNOPSIS
.Nm
.Op Fl hfv
.Op Fl F|M
.Op Fl -pos Ar x,y
.Op Fl -profile Ar name
.Op Fl -size Ar c,r
.Op Ar commandline
.Sh DESCRIPTION
.Nm
is a Linux wrapper for Windows Terminal. Its options are as follows:
.Bl -tag -width Ds
.It Fl h , Fl -help
Opens a dialog displaying help information.
.It Fl e
Launches the program with administrator privileges.
.It Fl f , Fl -focus
Launches the program with no title or tab bar.
.It Fl F , Fl -fullscreen
Launches the program in fullscreen mode. Conflicts with
.Fl -maximized .
.It Fl M , Fl -maximized
Launches the program in a maximized window. Conflicts with
.Fl -fullscreen .
.It Fl -pos Ar x,y
Launches the program at the given screen position.
.It Fl -profile Ar name
Launches the profile with the given
.Ar name
.
.It Fl -size Ar c,r
Launches the program with the given size in columns and rows respectively.
.It Fl v , Fl -version
Opens a dialog displaying version information.
.It Ar commandline
Attempt to run the given Windows command as the command line.
.El
.Sh BUGS
The official documentations (online and via
.Fl h )
contain a variety of errors, including deprecated/unsupported flags, and subcommands, which do not work.

2
mkwin/.gitignore vendored
View file

@ -1,2 +0,0 @@
/target
Cargo.lock

View file

@ -1,16 +0,0 @@
[package]
name = "mkwin"
version = "0.2.0"
edition = "2021"
[dependencies]
pico-args = { version = "0.5.0", features = [ "eq-separator" ] }
[profile.release]
opt-level = 's'
codegen-units = 1
debug = false
lto = true
panic = "abort"
strip = "symbols"

View file

@ -1,10 +0,0 @@
alias b := build
alias i := install
build:
cargo build --release
install DIR: build
cp ./target/release/mkwin "{{DIR}}/mkwin"

View file

@ -1,16 +0,0 @@
//! error handling code
use std::process::exit;
/// no argument for target; code 1
pub fn missing_target() -> ! {
eprintln!("mkwin: missing target");
exit(1);
}
/// failed to canonicalize target path; code 2
pub fn canonicalize_fail(target: String) -> ! {
eprintln!("mkwin: failed to canonicalze '{target}'--does the file exist?");
exit(2);
}

View file

@ -1,10 +0,0 @@
//! constants for flag arguments
pub const HELP: [&str;2] = ["-h", "--help"];
pub const EMPTY: [&str;2] = ["-e", "--empty"];
pub const ENV_SHARE: [&str;2] = ["-E", "--env-share"];
pub const FIND_BIN: &str = "--find";
pub const OR: &str = "--or";
pub const PATH_CONVERT: &str = "--pc";
pub const QUIET: [&str;2] = ["-q", "--quiet"];

View file

@ -1,152 +0,0 @@
use std::path::Path;
use pico_args::Arguments;
mod error;
mod flag;
pub fn main() {
let mut args = Arguments::from_env();
// build reference string
let mut arg_string = String::new();
let mut arg_vec = args.clone().finish();
for arg in &arg_vec {
arg_string += &format!(" {}", arg.to_str().unwrap());
}
// drain forwarded arguments
let forwarded: String;
if let Some(position) = arg_vec.iter().position(|a| a == "--") {
let mut build = String::new();
for arg in arg_vec.drain(position+1..) {
build = format!("{build} {}", arg.to_str().unwrap());
}
arg_vec.pop();
args = Arguments::from_vec(arg_vec);
forwarded = build;
} else { forwarded = String::new(); }
// consume breaking flags
if args.contains(flag::HELP) {
help_text();
return;
}
// consume path convert flag
let path_convert: bool;
let path_convert_flags: Option<String>;
match args.value_from_str(flag::PATH_CONVERT) {
Ok(flags) => {
path_convert = true;
path_convert_flags = if flags != "x" { Some(flags) } else { None };
},
Err(pico_args::Error::OptionWithoutAValue(_)) => {
path_convert = true;
path_convert_flags = None;
},
_ => {
path_convert = false;
path_convert_flags = None;
}
}
// consume find binary flag
let find_bin: Option<String>;
match args.value_from_str::<&str, String>(flag::FIND_BIN) {
Ok(inner) => find_bin = Some(inner),
_ => find_bin = None
}
// consume simple flags
let empty = args.contains(flag::EMPTY);
let env_share = args.contains(flag::ENV_SHARE);
let quiet = args.contains(flag::QUIET);
// get target executable
let target: String;
if let Ok(Some(arg)) = args.subcommand() {
if let Some(root) = &find_bin { // handle find binary flag
target = format!("`find {root} -name '{arg}'`");
} else { // handle normal path
let path = Path::new(&arg);
if let Ok(path) = path.canonicalize() {
let path: String = path.to_string_lossy().into();
target = format!("'{path}'");
} else { error::canonicalize_fail(arg); }
}
} else { error::missing_target(); }
let exec =
if let Ok(alt) = args.value_from_str::<&str, String>(flag::OR) {
format!("target={target}\nif [ ! -x \"$target\" ]; then\n\ttarget='{alt}'\nfi\n\n\"$target\"")
} else if find_bin.is_some() {
format!("\"{target}\"")
} else { target };
// construct output
println!("#!/usr/bin/bash\n# generated with: mkwin{arg_string}\n");
if env_share { println!("env-share 2> /dev/null\n"); }
print!("{exec}");
// handle forwarded arguments
if !forwarded.is_empty() {
print!("{forwarded}");
}
// handle empty flag
if !empty {
// handle path convert flag
if path_convert {
let flags = if let Some(i) = path_convert_flags { format!(" -{i}") } else { String::new() };
print!(" `path-convert{flags} $@`");
} else {
print!(" $@");
}
}
// handle quiet flag
if quiet {
print!(" > /dev/null 2>&1 &");
}
println!();
}
pub fn help_text() {
println!("mkwin v{}
Valerie Wolfe <sleeplessval@gmail.com>
Quickly make bash scripts to run Windows programs from WSL.
usage: mkwin [flags] <target> [-- args]
args:
<target> The target program the resulting script will run.
[-- args] Arguments forwarded to the target program. These are placed
before any other arguments in the resulting script.
flags:
-h, --help Show this help text and exit.
-e, --empty The resulting script will not pass arguments.
-E, --env-share The resulting script will use the 'env-share' utility to
share environment variables before calling the target
binary.
--find=<root> The resulting script will use the 'find' utility to locate
the target binary in the given directory. The value given by
root is passed verbatim to 'find', unexpanded.
--pc=<flags> The resulting script will use the 'path-convert' tool to
convert arguments from UNIX to DOS, with the provided set of
flags ('x' for no flags).
-q, --quiet The resulting script will run the target program in the
background and redirect all output to '/dev/null'.",
env!("CARGO_PKG_VERSION"));
}

View file

@ -1,2 +1 @@
/target
Cargo.lock

View file

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

View file

@ -1,10 +0,0 @@
alias b := build
alias i := install
build:
cargo build --release
install DIR: build
cp ./target/release/path-convert "{{DIR}}/path-convert"

View file

@ -2,15 +2,9 @@ use std::path::{ Path, PathBuf };
use pico_args::Arguments;
// - HELPER -
const DRIVE: &str = "/mnt/c/";
// - ENV -
const DISTRO: &str = "WSL_DISTRO_NAME";
// - FLAGS -
const HELP: [&str;2] = [ "-h", "--help" ];
const NET_PATH: [&str;2] = [ "-n", "--network" ];
const NO_SPACES: [&str;2] = [ "-s", "--no-space" ];
const QUOTED: [&str;2] = [ "-q", "--quotes" ];
@ -25,82 +19,75 @@ pub fn main() {
// handle quote flag
let quotes: &str =
if args.contains(QUOTED) {
if args.contains(QUOTED) { "\"" } // -qq -> "..." (output with double quotes)
else { "'" } // -q -> '...' (output with single quotes)
} else { "" }; // _ -> ... (output with no quotes)
if args.contains(QUOTED) {
if args.contains(QUOTED) { "\"" } // -qq -> "..." (output with double quotes)
else { "'" } // -q -> '...' (output with single quotes)
} else { "" }; // _ -> ... (output with no quotes)
// consume simple flags
// collect no-space flag
let no_spaces = args.contains(NO_SPACES);
let network_path = args.contains(NET_PATH);
let mut targets = args.finish();
// for empty args, just do cwd
if targets.len() == 0 { targets.push(".".into()) ; }
for target in targets {
let target = target.to_string_lossy().to_string();
// canonicalize; windows doesn't recognize symlinks
let path = Path::new(&target).canonicalize();
let mut output: String =
if let Ok(canonical) = path {
canonical.to_string_lossy().to_string()
loop {
let next = args.subcommand().unwrap();
if let Some(arg) = next {
let mut output: String;
// canonicalize; windows doesn't recognize symlinks
let path = Path::new(&arg).canonicalize();
if let Ok(target) = path {
output = target.to_string_lossy().to_string();
} else {
println!("{quotes}{target}{quotes}");
continue;
};
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 a space is found, use short version
if let Some(index) = space {
// find cut point and slice
let cut = usize::min(len, index).min(6);
let replace = &(part[..cut]);
// 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 shortened index
let mut index = 0;
let children = current.read_dir();
if !children.is_ok() { continue; }
// 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().to_string();
// matching names increment index
if name.to_lowercase().starts_with(&replace.to_lowercase()) { index += 1; }
// ... and break when we hit the target
if name == part { break; }
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);
}
output = output.replacen(part, &format!("{replace}~{index}"), 1);
current.push(part);
}
current.push(part);
}
}
// very basic C-drive substitution
if output.starts_with(DRIVE) {
output = output.replace(DRIVE, "C:\\");
} else if network_path {
let name = std::env::var(DISTRO);
if let Ok(name) = name {
output = format!("//wsl.localhost/{name}{output}");
// simple C-drive substitution
if output.starts_with(DRIVE) {
output = output.replace(DRIVE, "C:\\");
}
// switch out separators
output = output.replace("/", "\\");
// emit to stdout
println!("{quotes}{output}{quotes}");
} else {
break;
}
// switch out separators
output = output.replace("/", "\\");
// emit to stdout
println!("{quotes}{output}{quotes}");
}
}
@ -113,13 +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
-n, --network Add the network path where appropriate
-q, --quotes Surround the output strings with quotes (-qq for double quotes)
-s, --no-space Don't allow paths to have spaces
-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"));
}

2
qdls/.gitignore vendored
View file

@ -1,4 +1,4 @@
obj/
bin/
.idea/
qdls.exe

View file

@ -1,11 +0,0 @@
alias b := build
alias i := install
build:
dos dotnet warp
install DIR: build
chmod +x qdls.exe
mv qdls.exe {{DIR}}/qdls

View file

@ -1,4 +0,0 @@
#!/usr/bin/bash
# generated with: mkwin /mnt/c/Windows/System32/charmap.exe -eq
'/mnt/c/Windows/System32/charmap.exe' $@

View file

@ -1,21 +0,0 @@
#!/usr/bin/bash
if [ "$#" -ne 0 ]; then
args=''
for arg in $@; do
if [[ $arg =~ ^-.+$ ]]; then
transform=(${arg//-//})
if [[ $arg =~ ^-.+=.+$ ]]; then
transform=(${transform//=/:})
fi
args="$args $transform"
else
args="$args $arg"
fi
done
/mnt/c/Windows/System32/cmd.exe $args
else
/mnt/c/Windows/System32/cmd.exe
fi

View file

@ -1,8 +0,0 @@
#!/usr/bin/bash
if [ "$#" -eq 0 ]; then
pwsh
else
pwsh -C "$@"
fi

View file

@ -1,42 +0,0 @@
#!/usr/bin/bash
# error if 'pwsh' not in path
if [ ! which pwsh > /dev/null 2>&1 ]; then
echo "no 'pwsh' in \$PATH"
exit 1
fi
# set mode (linux/dos)
if [[ "$1" == "-l" ]]; then
mode='linux'
shift
elif [[ "$1" == "-w" ]]; then
mode='dos'
shift
# error if no target for DOS
if [ "$#" -eq 0 ]; then
echo "elevate: DOS mode requires a target"
exit 3
fi
fi
# consume target based on mode
if [[ "$mode" == "linux" ]]; then
target='wsl.exe'
elif [[ "$mode" == "dos" ]]; then
target="$1"
shift
else
echo "elevate: no mode set; use '-l' or '-w'"
exit 2
fi
# consume remaining arguments
arglist=''
if [ "$#" -ne 0 ]; then
arglist="-ArgumentList '$@'"
fi
# execute
pwsh -C "Start-Process -Verb runas $target $arglist"

View file

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

View file

@ -1,13 +0,0 @@
alias i := install
install DIR="/usr/local/bin":
cp charmap {{DIR}}/charmap
cp cmd.sh {{DIR}}/cmd
cp dos.sh {{DIR}}/dos
cp elevate.sh {{DIR}}/elevate
cp explorer.sh {{DIR}}/explorer
cp pwsh.sh {{DIR}}/pwsh
cp wsl.sh {{DIR}}/wsl
cp wt.sh {{DIR}}/wt

View file

@ -1,11 +0,0 @@
#!/usr/bin/bash
# generated with: mkwin /mnt/c/Program Files/PowerShell/7/pwsh.exe -E --or /mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe
env-share 2> /dev/null
target='/mnt/c/Program Files/PowerShell/7/pwsh.exe'
if [ ! -x "$target" ]; then
target='/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe'
fi
"$target" $@

View file

@ -1,4 +0,0 @@
#!/usr/bin/bash
# generated with: mkwin /mnt/c/Program Files/SqlCmd/sqlcmd.exe
'/mnt/c/Program Files/SqlCmd/sqlcmd.exe' $@

View file

@ -1,7 +0,0 @@
#!/usr/bin/bash
if [[ ! -t 1 ]]; then
WRAPPER='hug'
fi
$WRAPPER '/mnt/c/Windows/System32/wsl.exe' $@

View file

@ -1,11 +0,0 @@
#!/usr/bin/bash
if [[ "$1" == "-e" ]]; then
elevate -l wt
exit
fi
cd '/mnt/c/Program Files/WindowsApps/'
target=`find Microsoft.WindowsTerminal* -name 'WindowsTerminal.exe'`
dos "$target" $@