mirror of
https://github.com/TECHNOFAB11/pay-respects.git
synced 2026-02-02 07:35:10 +01:00
feat: powershell initialization & native windows support (github #15)
This commit is contained in:
parent
fe083a9ddb
commit
5f86ff02a2
4 changed files with 131 additions and 22 deletions
10
README.md
10
README.md
|
|
@ -56,6 +56,16 @@ Please follow the instruction for your shell:
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>PowerShell</summary>
|
||||||
|
|
||||||
|
> Append the following to your profile:
|
||||||
|
> ```pwsh
|
||||||
|
> pay-respects pwsh [--alias <alias>] [--nocnf] [>> $PROFILE] # use the pipe to directly append it to your profile if you like
|
||||||
|
> ```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Custom initialization for arbitrary shell</summary>
|
<summary>Custom initialization for arbitrary shell</summary>
|
||||||
|
|
||||||
|
|
|
||||||
60
src/files.rs
60
src/files.rs
|
|
@ -1,30 +1,56 @@
|
||||||
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_env = if cfg!(windows) {
|
let path_env = {
|
||||||
String::from_utf8_lossy(
|
#[cfg(windows)]
|
||||||
&std::process::Command::new("bash")
|
{
|
||||||
.arg("-c")
|
if is_msystem() {
|
||||||
.arg("echo $PATH")
|
String::from_utf8_lossy(
|
||||||
.output()
|
&std::process::Command::new("bash")
|
||||||
.unwrap()
|
.arg("-c")
|
||||||
.stdout,
|
.arg("echo $PATH")
|
||||||
)
|
.output()
|
||||||
.trim()
|
.unwrap()
|
||||||
.to_owned()
|
.stdout,
|
||||||
} else {
|
)
|
||||||
std::env::var("PATH").unwrap()
|
.trim()
|
||||||
|
.to_owned()
|
||||||
|
} else {
|
||||||
|
std::env::var("PATH").unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
{
|
||||||
|
std::env::var("PATH").unwrap()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
eprintln!("path_env: {path_env}");
|
eprintln!("path_env: {path_env}");
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = path_env.split(':').collect::<Vec<&str>>();
|
let path_env_sep = {
|
||||||
|
#[cfg(windows)]
|
||||||
|
if is_msystem() {
|
||||||
|
":"
|
||||||
|
} else {
|
||||||
|
";"
|
||||||
|
}
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
{
|
||||||
|
":"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let path = path_env.split(path_env_sep).collect::<Vec<&str>>();
|
||||||
let mut all_executable = vec![];
|
let mut all_executable = vec![];
|
||||||
for p in path {
|
for p in path {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let p = msys2_conv_path(p).expect("Failed to convert path for msys");
|
let p = if is_msystem() {
|
||||||
|
msys2_conv_path(p).expect("Failed to convert path for msys")
|
||||||
|
} else {
|
||||||
|
p.to_owned()
|
||||||
|
};
|
||||||
|
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
eprintln!("p={p}");
|
eprintln!("p={p}");
|
||||||
|
|
@ -125,3 +151,7 @@ fn msys2_conv_path(p: &str) -> std::io::Result<String> {
|
||||||
.output()
|
.output()
|
||||||
.map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned())
|
.map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned())
|
||||||
}
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn is_msystem() -> bool {
|
||||||
|
std::env::var("MSYSTEM").is_ok()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,8 +134,12 @@ fn eval_suggest(suggest: &str, last_command: &str, error_msg: &str, shell: &str)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rule(executable: &str) -> Option<String> {
|
fn get_rule(executable: &str) -> Option<String> {
|
||||||
let xdg_config_home = std::env::var("XDG_CONFIG_HOME")
|
let xdg_config_home = if cfg!(windows) {
|
||||||
.unwrap_or_else(|_| std::env::var("HOME").unwrap() + "/.config");
|
std::env::var("APPDATA").unwrap()
|
||||||
|
} else {
|
||||||
|
std::env::var("XDG_CONFIG_HOME")
|
||||||
|
.unwrap_or_else(|_| std::env::var("HOME").unwrap() + "/.config")
|
||||||
|
};
|
||||||
|
|
||||||
let user_rule_dir = format!("{}/pay-respects/rules", xdg_config_home);
|
let user_rule_dir = format!("{}/pay-respects/rules", xdg_config_home);
|
||||||
let user_rule_file = format!("{}/{}.toml", user_rule_dir, executable);
|
let user_rule_file = format!("{}/{}.toml", user_rule_dir, executable);
|
||||||
|
|
|
||||||
75
src/shell.rs
75
src/shell.rs
|
|
@ -164,6 +164,10 @@ pub fn initialization(shell: &str, binary_path: &str, auto_alias: &str, cnf: boo
|
||||||
last_command = "(history | last).command";
|
last_command = "(history | last).command";
|
||||||
alias = "\"\"";
|
alias = "\"\"";
|
||||||
}
|
}
|
||||||
|
"pwsh" | "powershell" => {
|
||||||
|
last_command = "Get-History | Select-Object -Last 1 | ForEach-Object {$_.CommandLine}";
|
||||||
|
alias = ";";
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
println!("Unknown shell: {}", shell);
|
println!("Unknown shell: {}", shell);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
|
|
@ -190,15 +194,45 @@ def --env {} [] {{
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut init = format!(
|
let mut init = match shell {
|
||||||
"\
|
"bash" | "zsh" | "fish" => format!(
|
||||||
|
"\
|
||||||
eval $(_PR_LAST_COMMAND=\"{}\" \
|
eval $(_PR_LAST_COMMAND=\"{}\" \
|
||||||
_PR_ALIAS=\"{}\" \
|
_PR_ALIAS=\"{}\" \
|
||||||
_PR_SHELL=\"{}\" \
|
_PR_SHELL=\"{}\" \
|
||||||
\"{}\")",
|
\"{}\")",
|
||||||
last_command, alias, shell, binary_path
|
last_command, alias, shell, binary_path
|
||||||
);
|
),
|
||||||
|
"pwsh" | "powershell" => format!(
|
||||||
|
r#"& {{
|
||||||
|
try {{
|
||||||
|
# fetch command and error from session history only when not in cnf mode
|
||||||
|
if ($env:_PR_MODE -ne 'cnf') {{
|
||||||
|
$env:_PR_LAST_COMMAND = ({});
|
||||||
|
$err = Get-Error;
|
||||||
|
if ($env:_PR_LAST_COMMAND -eq $err.InvocationInfo.Line) {{
|
||||||
|
$env:_PR_ERROR_MSG = $err.Exception.Message
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
$env:_PR_SHELL = '{}';
|
||||||
|
&'{}';
|
||||||
|
}}
|
||||||
|
finally {{
|
||||||
|
# restore mode from cnf
|
||||||
|
if ($env:_PR_MODE -eq 'cnf') {{
|
||||||
|
$env:_PR_MODE = $env:_PR_PWSH_ORIGIN_MODE;
|
||||||
|
$env:_PR_PWSH_ORIGIN_MODE = $null;
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
"#,
|
||||||
|
last_command, shell, binary_path
|
||||||
|
),
|
||||||
|
_ => {
|
||||||
|
println!("Unsupported shell: {}", shell);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
if auto_alias.is_empty() {
|
if auto_alias.is_empty() {
|
||||||
println!("{}", init);
|
println!("{}", init);
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
|
|
@ -218,6 +252,13 @@ end
|
||||||
auto_alias, init
|
auto_alias, init
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
"pwsh" | "powershell" => {
|
||||||
|
init = format!(
|
||||||
|
"function {} {{\n{}",
|
||||||
|
auto_alias,
|
||||||
|
init.split_once("\n").unwrap().1,
|
||||||
|
);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
println!("Unsupported shell: {}", shell);
|
println!("Unsupported shell: {}", shell);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
@ -250,6 +291,30 @@ end
|
||||||
shell, binary_path, init
|
shell, binary_path, init
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
"pwsh" | "powershell" => {
|
||||||
|
init = format!(
|
||||||
|
r#"{}
|
||||||
|
$ExecutionContext.InvokeCommand.CommandNotFoundAction =
|
||||||
|
{{
|
||||||
|
param(
|
||||||
|
[string]
|
||||||
|
$commandName,
|
||||||
|
[System.Management.Automation.CommandLookupEventArgs]
|
||||||
|
$eventArgs
|
||||||
|
)
|
||||||
|
# powershell does not support run command with specific environment variables
|
||||||
|
# but you must set global variables. so we are memorizing the current mode and the alias function will reset it later.
|
||||||
|
$env:_PR_PWSH_ORIGIN_MODE=$env:_PR_MODE;
|
||||||
|
$env:_PR_MODE='cnf';
|
||||||
|
# powershell may search command with prefix 'get-' or '.\' first when this hook is hit, strip them
|
||||||
|
$env:_PR_LAST_COMMAND=$commandName -replace '^get-|\.\\','';
|
||||||
|
$eventArgs.Command = (Get-Command {});
|
||||||
|
$eventArgs.StopSearch = $True;
|
||||||
|
}}
|
||||||
|
"#,
|
||||||
|
init, auto_alias
|
||||||
|
)
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
println!("Unsupported shell: {}", shell);
|
println!("Unsupported shell: {}", shell);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue