Mountain/IPC/WindServiceHandlers/Terminal/
LocalPTYGetProfiles.rs1#![allow(non_snake_case)]
2
3use serde_json::{Value, json};
14
15pub async fn LocalPTYGetProfiles() -> Result<Value, String> {
16 let mut Profiles = Vec::new();
17
18 #[cfg(unix)]
19 {
20 let DefaultShell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string());
21
22 let UnixShells = [
23 "/bin/zsh",
24 "/bin/bash",
25 "/bin/sh",
26 "/usr/bin/zsh",
27 "/usr/bin/bash",
28 "/usr/bin/fish",
29 "/usr/local/bin/fish",
30 "/usr/local/bin/zsh",
31 "/usr/local/bin/bash",
32 "/bin/dash",
33 "/usr/bin/ksh",
34 "/usr/bin/tcsh",
35 "/bin/csh",
36 "/usr/bin/pwsh",
37 "/usr/local/bin/pwsh",
38 ];
39
40 for Shell in &UnixShells {
41 if std::path::Path::new(Shell).exists() {
42 let Name = std::path::Path::new(Shell)
43 .file_name()
44 .and_then(|N| N.to_str())
45 .unwrap_or("shell");
46
47 Profiles.push(json!({
48 "profileName": Name,
49 "path": Shell,
50 "isDefault": *Shell == DefaultShell.as_str(),
51 "Arguments": [],
52 "env": {},
53 "icon": "terminal"
54 }));
55 }
56 }
57
58 if let Ok(ShellsFile) = std::fs::read_to_string("/etc/shells") {
59 for Line in ShellsFile.lines() {
60 let Trimmed = Line.trim();
61 if Trimmed.starts_with('/') && !Trimmed.starts_with('#') {
62 let AlreadyAdded = Profiles.iter().any(|P| P.get("path").and_then(|V| V.as_str()) == Some(Trimmed));
63 if !AlreadyAdded && std::path::Path::new(Trimmed).exists() {
64 let Name = std::path::Path::new(Trimmed)
65 .file_name()
66 .and_then(|N| N.to_str())
67 .unwrap_or("shell");
68
69 Profiles.push(json!({
70 "profileName": Name,
71 "path": Trimmed,
72 "isDefault": Trimmed == DefaultShell.as_str(),
73 "Arguments": [],
74 "env": {},
75 "icon": "terminal"
76 }));
77 }
78 }
79 }
80 }
81 }
82
83 #[cfg(target_os = "windows")]
84 {
85 let SystemRoot = std::env::var("SystemRoot").unwrap_or_else(|_| "C:\\Windows".to_string());
86 let ProgramFiles = std::env::var("ProgramFiles").unwrap_or_else(|_| "C:\\Program Files".to_string());
87 let LocalAppData =
88 std::env::var("LOCALAPPDATA").unwrap_or_else(|_| "C:\\Users\\User\\AppData\\Local".to_string());
89
90 let WindowsShells:Vec<(&str, String, Vec<&str>)> = vec![
91 (
92 "PowerShell",
93 format!("{}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", SystemRoot),
94 vec!["-NoLogo"],
95 ),
96 (
97 "PowerShell 7",
98 format!("{}\\PowerShell\\7\\pwsh.exe", ProgramFiles),
99 vec!["-NoLogo"],
100 ),
101 ("Command Prompt", format!("{}\\System32\\cmd.exe", SystemRoot), vec![]),
102 (
103 "Git Bash",
104 format!("{}\\Git\\bin\\bash.exe", ProgramFiles),
105 vec!["--login", "-i"],
106 ),
107 (
108 "Git Bash (User)",
109 format!("{}\\Programs\\Git\\bin\\bash.exe", LocalAppData),
110 vec!["--login", "-i"],
111 ),
112 ("WSL", format!("{}\\System32\\wsl.exe", SystemRoot), vec![]),
113 ("MSYS2", "C:\\msys64\\usr\\bin\\bash.exe".to_string(), vec!["--login", "-i"]),
114 ("Cygwin", "C:\\cygwin64\\bin\\bash.exe".to_string(), vec!["--login", "-i"]),
115 ];
116
117 let mut IsFirstFound = true;
118 for (Name, Path, Args) in &WindowsShells {
119 if std::path::Path::new(Path).exists() {
120 Profiles.push(json!({
121 "profileName": Name,
122 "path": Path,
123 "isDefault": IsFirstFound,
124 "Arguments": Args,
125 "env": {},
126 "icon": "terminal"
127 }));
128 IsFirstFound = false;
129 }
130 }
131 }
132
133 Ok(json!(Profiles))
134}