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