intelli_shell/utils/
process.rs1use std::{ops::Deref, process, sync::LazyLock};
2
3use sysinfo::{Pid, System};
4
5#[derive(Clone, Debug, PartialEq, Eq, strum::Display, strum::EnumString)]
6pub enum ShellType {
7 #[strum(serialize = "cmd", serialize = "cmd.exe")]
8 Cmd,
9 #[strum(serialize = "powershell", serialize = "powershell.exe")]
10 WindowsPowerShell,
11 #[strum(serialize = "pwsh", serialize = "pwsh.exe")]
12 PowerShellCore,
13 #[strum(to_string = "bash", serialize = "bash.exe")]
14 Bash,
15 #[strum(serialize = "sh")]
16 Sh,
17 #[strum(serialize = "fish")]
18 Fish,
19 #[strum(serialize = "zsh")]
20 Zsh,
21 #[strum(default, to_string = "{0}")]
22 Other(String),
23}
24
25static PARENT_SHELL: LazyLock<ShellType> = LazyLock::new(|| {
26 let parent_name = {
27 let pid = Pid::from_u32(process::id());
28
29 tracing::debug!("Retrieving info for pid {pid}");
30 let sys = System::new_all();
31
32 sys.process(Pid::from_u32(process::id()))
33 .expect("Couldn't retrieve current process from pid")
34 .parent()
35 .and_then(|parent_pid| sys.process(parent_pid))
36 .and_then(|parent_process| parent_process.name().to_str().map(|s| s.trim().to_lowercase()))
37 };
38
39 ShellType::try_from(
40 parent_name
41 .as_deref()
42 .inspect(|shell| tracing::info!("Detected shell: {shell}"))
43 .unwrap_or_else(|| {
44 let default = if cfg!(target_os = "windows") {
45 "powershell"
46 } else {
47 "sh"
48 };
49 tracing::warn!("Couldn't detect shell, assuming {default}");
50 default
51 }),
52 )
53 .expect("infallible")
54});
55
56pub fn get_shell() -> &'static ShellType {
58 PARENT_SHELL.deref()
59}
60
61static WORING_DIR: LazyLock<String> = LazyLock::new(|| {
62 std::env::current_dir()
63 .inspect_err(|err| tracing::warn!("Couldn't retrieve current dir: {err}"))
64 .ok()
65 .and_then(|p| p.to_str().map(|s| s.to_owned()))
66 .unwrap_or_default()
67});
68
69pub fn get_working_dir() -> &'static str {
71 WORING_DIR.deref()
72}
73
74pub fn format_env_var(var: impl AsRef<str>) -> String {
76 let var = var.as_ref();
77 match get_shell() {
78 ShellType::Cmd => format!("%{var}%"),
79 ShellType::WindowsPowerShell | ShellType::PowerShellCore => format!("$env:{var}"),
80 _ => format!("${var}"),
81 }
82}