fix: msys2 path (github #12)

This commit is contained in:
莯凛 2024-11-24 20:00:31 +08:00 committed by GitHub
parent 6feb88d48f
commit 659235bf2e
5 changed files with 80 additions and 13 deletions

2
Cargo.lock generated
View file

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"

View file

@ -11,10 +11,7 @@ repository = "https://github.com/iffse/pay-respects"
keywords = ["cli", "terminal", "utility", "shell"] keywords = ["cli", "terminal", "utility", "shell"]
categories = ["command-line-utilities"] categories = ["command-line-utilities"]
license = "AGPL-3.0" license = "AGPL-3.0"
include = [ include = ["**/*.rs", "**/*.toml"]
"**/*.rs",
"**/*.toml",
]
[dependencies] [dependencies]
colored = "2" colored = "2"

View file

@ -1,34 +1,89 @@
use crate::suggestions::find_similar; use crate::suggestions::find_similar;
pub fn get_path_files() -> Vec<String> { pub fn get_path_files() -> Vec<String> {
let path = std::env::var("PATH").unwrap(); let path_env = if cfg!(windows) {
#[cfg(target_os = "windows")] String::from_utf8_lossy(
let path = path.split(';').collect::<Vec<&str>>(); &std::process::Command::new("bash")
#[cfg(not(target_os = "windows"))] .arg("-c")
let path = path.split(':').collect::<Vec<&str>>(); .arg("echo $PATH")
.output()
.unwrap()
.stdout,
)
.trim()
.to_owned()
} else {
std::env::var("PATH").unwrap()
};
if cfg!(debug_assertions) {
eprintln!("path_env: {path_env}");
}
let path = path_env.split(':').collect::<Vec<&str>>();
let mut all_executable = vec![]; let mut all_executable = vec![];
for p in path { for p in path {
#[cfg(windows)]
let p = msys2_conv_path(p).expect("Failed to convert path for msys");
if cfg!(debug_assertions) {
eprintln!("p={p}");
}
let files = match std::fs::read_dir(p) { let files = match std::fs::read_dir(p) {
Ok(files) => files, Ok(files) => files,
Err(_) => continue, Err(_) => continue,
}; };
for file in files { for file in files {
let file = file.unwrap(); let file = file.unwrap();
let file_name = file.file_name().into_string().unwrap(); #[allow(unused_mut)]
let mut file_name = file.file_name().into_string().unwrap();
#[cfg(windows)]
{
let mut ok = false;
let suffixies = [".exe", ".sh", ".ps1"];
for suffix in suffixies {
if let Some(file_name_strip) = file_name.strip_suffix(suffix) {
file_name = file_name_strip.to_owned();
ok = true;
break;
}
}
if !file_name.contains(".") {
ok = true;
}
if !ok {
continue;
}
}
all_executable.push(file_name); all_executable.push(file_name);
} }
} }
if cfg!(debug_assertions) {
let mut all_executable = all_executable.clone();
all_executable.sort_unstable();
eprintln!("all_executable={all_executable:?}");
}
all_executable all_executable
} }
pub fn get_best_match_file(input: &str) -> Option<String> { pub fn get_best_match_file(input: &str) -> Option<String> {
let mut input = input.trim_matches(|c| c == '\'' || c == '"').to_owned(); let mut input = input.trim_matches(|c| c == '\'' || c == '"').to_owned();
if cfg!(debug_assertions) {
eprintln!("get_best_match_file input: {input}");
}
let mut exit_dirs = Vec::new(); let mut exit_dirs = Vec::new();
let mut files = loop { let mut files = loop {
match std::fs::read_dir(&input) { match std::fs::read_dir(&input) {
Ok(files) => break files, Ok(files) => break files,
Err(_) => { Err(_) => {
if let Some((dirs, exit_dir)) = input.rsplit_once('/') { if let Some((dirs, exit_dir)) = input.rsplit_once(std::path::MAIN_SEPARATOR) {
exit_dirs.push(exit_dir.to_owned()); exit_dirs.push(exit_dir.to_owned());
input = dirs.to_owned(); input = dirs.to_owned();
} else { } else {
@ -61,3 +116,12 @@ pub fn get_best_match_file(input: &str) -> Option<String> {
Some(input) Some(input)
} }
#[cfg(windows)]
fn msys2_conv_path(p: &str) -> std::io::Result<String> {
std::process::Command::new("cygpath")
.arg("-w")
.arg(p)
.output()
.map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned())
}

View file

@ -16,6 +16,9 @@ pub fn highlight_difference(
if split_suggested_command == split_last_command { if split_suggested_command == split_last_command {
return None; return None;
} }
if split_suggested_command.is_empty() {
return None;
}
let privileged = PRIVILEGE_LIST.contains(&split_suggested_command[0].as_str()); let privileged = PRIVILEGE_LIST.contains(&split_suggested_command[0].as_str());

View file

@ -153,6 +153,9 @@ pub fn eval_shell_command(shell: &str, command: &str) -> Vec<String> {
} }
pub fn split_command(command: &str) -> Vec<String> { pub fn split_command(command: &str) -> Vec<String> {
if cfg!(debug_assertions) {
eprintln!("command: {command}")
}
// this regex splits the command separated by spaces, except when the space // this regex splits the command separated by spaces, except when the space
// is escaped by a backslash or surrounded by quotes // is escaped by a backslash or surrounded by quotes
let regex = r#"([^\s"'\\]+|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\\ )+|\\|\n"#; let regex = r#"([^\s"'\\]+|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\\ )+|\\|\n"#;