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
62 if Trimmed.starts_with('/') && !Trimmed.starts_with('#') {
63 let AlreadyAdded = Profiles.iter().any(|P| P.get("path").and_then(|V| V.as_str()) == Some(Trimmed));
64
65 if !AlreadyAdded && std::path::Path::new(Trimmed).exists() {
66 let Name = std::path::Path::new(Trimmed)
67 .file_name()
68 .and_then(|N| N.to_str())
69 .unwrap_or("shell");
70
71 Profiles.push(json!({
72 "profileName": Name,
73 "path": Trimmed,
74 "isDefault": Trimmed == DefaultShell.as_str(),
75 "Arguments": [],
76 "env": {},
77 "icon": "terminal"
78 }));
79 }
80 }
81 }
82 }
83 }
84
85 #[cfg(target_os = "windows")]
86 {
87 let SystemRoot = std::env::var("SystemRoot").unwrap_or_else(|_| "C:\\Windows".to_string());
88
89 let ProgramFiles = std::env::var("ProgramFiles").unwrap_or_else(|_| "C:\\Program Files".to_string());
90
91 let LocalAppData =
92 std::env::var("LOCALAPPDATA").unwrap_or_else(|_| "C:\\Users\\User\\AppData\\Local".to_string());
93
94 let WindowsShells:Vec<(&str, String, Vec<&str>)> = vec![
95 (
96 "PowerShell",
97 format!("{}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", SystemRoot),
98 vec!["-NoLogo"],
99 ),
100 (
101 "PowerShell 7",
102 format!("{}\\PowerShell\\7\\pwsh.exe", ProgramFiles),
103 vec!["-NoLogo"],
104 ),
105 ("Command Prompt", format!("{}\\System32\\cmd.exe", SystemRoot), vec![]),
106 (
107 "Git Bash",
108 format!("{}\\Git\\bin\\bash.exe", ProgramFiles),
109 vec!["--login", "-i"],
110 ),
111 (
112 "Git Bash (User)",
113 format!("{}\\Programs\\Git\\bin\\bash.exe", LocalAppData),
114 vec!["--login", "-i"],
115 ),
116 ("WSL", format!("{}\\System32\\wsl.exe", SystemRoot), vec![]),
117 ("MSYS2", "C:\\msys64\\usr\\bin\\bash.exe".to_string(), vec!["--login", "-i"]),
118 ("Cygwin", "C:\\cygwin64\\bin\\bash.exe".to_string(), vec!["--login", "-i"]),
119 ];
120
121 let mut IsFirstFound = true;
122
123 for (Name, Path, Args) in &WindowsShells {
124 if std::path::Path::new(Path).exists() {
125 Profiles.push(json!({
126 "profileName": Name,
127 "path": Path,
128 "isDefault": IsFirstFound,
129 "Arguments": Args,
130 "env": {},
131 "icon": "terminal"
132 }));
133
134 IsFirstFound = false;
135 }
136 }
137 }
138
139 Ok(json!(Profiles))
140}