Mountain/IPC/WindServiceHandler/
Terminal.rs1#![allow(non_snake_case)]
2
3use std::{collections::HashMap, sync::Arc};
6
7use serde_json::{Value, json};
8use CommonLibrary::Terminal::TerminalProvider::TerminalProvider;
9
10use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, dev_log};
11
12pub async fn handle_terminal_create(Runtime:Arc<ApplicationRunTime>, Args:Vec<Value>) -> Result<Value, String> {
14 let Options = Args.first().cloned().unwrap_or(Value::Null);
15 Runtime
16 .Environment
17 .CreateTerminal(Options)
18 .await
19 .map_err(|Error| format!("terminal:create failed: {}", Error))
20}
21
22pub async fn handle_terminal_send_text(Runtime:Arc<ApplicationRunTime>, Args:Vec<Value>) -> Result<Value, String> {
24 let TerminalId = Args
25 .first()
26 .and_then(|V| V.as_u64())
27 .ok_or_else(|| "terminal:sendText requires terminal_id as first argument".to_string())?;
28 let Text = Args.get(1).and_then(|V| V.as_str()).unwrap_or("").to_string();
29
30 Runtime
31 .Environment
32 .SendTextToTerminal(TerminalId, Text)
33 .await
34 .map(|()| Value::Null)
35 .map_err(|Error| format!("terminal:sendText failed: {}", Error))
36}
37
38pub async fn handle_terminal_dispose(Runtime:Arc<ApplicationRunTime>, Args:Vec<Value>) -> Result<Value, String> {
40 let TerminalId = Args
41 .first()
42 .and_then(|V| V.as_u64())
43 .ok_or_else(|| "terminal:dispose requires terminal_id as first argument".to_string())?;
44
45 Runtime
46 .Environment
47 .DisposeTerminal(TerminalId)
48 .await
49 .map(|()| Value::Null)
50 .map_err(|Error| format!("terminal:dispose failed: {}", Error))
51}
52
53pub async fn handle_terminal_show(Runtime:Arc<ApplicationRunTime>, Args:Vec<Value>) -> Result<Value, String> {
55 let TerminalId = Args.first().and_then(|V| V.as_u64()).unwrap_or(0);
56 let PreserveFocus = Args.get(1).and_then(|V| V.as_bool()).unwrap_or(false);
57
58 Runtime
59 .Environment
60 .ShowTerminal(TerminalId, PreserveFocus)
61 .await
62 .map(|()| Value::Null)
63 .map_err(|Error| format!("terminal:show failed: {}", Error))
64}
65
66pub async fn handle_terminal_hide(Runtime:Arc<ApplicationRunTime>, Args:Vec<Value>) -> Result<Value, String> {
68 let TerminalId = Args.first().and_then(|V| V.as_u64()).unwrap_or(0);
69
70 Runtime
71 .Environment
72 .HideTerminal(TerminalId)
73 .await
74 .map(|()| Value::Null)
75 .map_err(|Error| format!("terminal:hide failed: {}", Error))
76}
77
78pub async fn handle_local_pty_get_profiles() -> Result<Value, String> {
84 let mut Profiles = Vec::new();
85
86 #[cfg(unix)]
87 {
88 let DefaultShell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string());
89
90 let UnixShells = [
91 "/bin/zsh",
92 "/bin/bash",
93 "/bin/sh",
94 "/usr/bin/zsh",
95 "/usr/bin/bash",
96 "/usr/bin/fish",
97 "/usr/local/bin/fish",
98 "/usr/local/bin/zsh",
99 "/usr/local/bin/bash",
100 "/bin/dash",
101 "/usr/bin/ksh",
102 "/usr/bin/tcsh",
103 "/bin/csh",
104 "/usr/bin/pwsh",
105 "/usr/local/bin/pwsh",
106 ];
107
108 for Shell in &UnixShells {
109 if std::path::Path::new(Shell).exists() {
110 let Name = std::path::Path::new(Shell)
111 .file_name()
112 .and_then(|N| N.to_str())
113 .unwrap_or("shell");
114
115 Profiles.push(json!({
116 "profileName": Name,
117 "path": Shell,
118 "isDefault": *Shell == DefaultShell.as_str(),
119 "args": [],
120 "env": {},
121 "icon": "terminal"
122 }));
123 }
124 }
125
126 if let Ok(ShellsFile) = std::fs::read_to_string("/etc/shells") {
127 for Line in ShellsFile.lines() {
128 let Trimmed = Line.trim();
129 if Trimmed.starts_with('/') && !Trimmed.starts_with('#') {
130 let AlreadyAdded = Profiles.iter().any(|P| P.get("path").and_then(|V| V.as_str()) == Some(Trimmed));
131 if !AlreadyAdded && std::path::Path::new(Trimmed).exists() {
132 let Name = std::path::Path::new(Trimmed)
133 .file_name()
134 .and_then(|N| N.to_str())
135 .unwrap_or("shell");
136
137 Profiles.push(json!({
138 "profileName": Name,
139 "path": Trimmed,
140 "isDefault": Trimmed == DefaultShell.as_str(),
141 "args": [],
142 "env": {},
143 "icon": "terminal"
144 }));
145 }
146 }
147 }
148 }
149 }
150
151 #[cfg(target_os = "windows")]
152 {
153 let SystemRoot = std::env::var("SystemRoot").unwrap_or_else(|_| "C:\\Windows".to_string());
154 let ProgramFiles = std::env::var("ProgramFiles").unwrap_or_else(|_| "C:\\Program Files".to_string());
155 let LocalAppData =
156 std::env::var("LOCALAPPDATA").unwrap_or_else(|_| "C:\\Users\\User\\AppData\\Local".to_string());
157
158 let WindowsShells:Vec<(&str, String, Vec<&str>)> = vec![
159 (
160 "PowerShell",
161 format!("{}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", SystemRoot),
162 vec!["-NoLogo"],
163 ),
164 (
165 "PowerShell 7",
166 format!("{}\\PowerShell\\7\\pwsh.exe", ProgramFiles),
167 vec!["-NoLogo"],
168 ),
169 ("Command Prompt", format!("{}\\System32\\cmd.exe", SystemRoot), vec![]),
170 (
171 "Git Bash",
172 format!("{}\\Git\\bin\\bash.exe", ProgramFiles),
173 vec!["--login", "-i"],
174 ),
175 (
176 "Git Bash (User)",
177 format!("{}\\Programs\\Git\\bin\\bash.exe", LocalAppData),
178 vec!["--login", "-i"],
179 ),
180 ("WSL", format!("{}\\System32\\wsl.exe", SystemRoot), vec![]),
181 ("MSYS2", "C:\\msys64\\usr\\bin\\bash.exe".to_string(), vec!["--login", "-i"]),
182 ("Cygwin", "C:\\cygwin64\\bin\\bash.exe".to_string(), vec!["--login", "-i"]),
183 ];
184
185 let mut IsFirstFound = true;
186 for (Name, Path, Args) in &WindowsShells {
187 if std::path::Path::new(Path).exists() {
188 Profiles.push(json!({
189 "profileName": Name,
190 "path": Path,
191 "isDefault": IsFirstFound,
192 "args": Args,
193 "env": {},
194 "icon": "terminal"
195 }));
196 IsFirstFound = false;
197 }
198 }
199 }
200
201 Ok(json!(Profiles))
202}
203
204pub async fn handle_local_pty_get_default_shell() -> Result<Value, String> {
206 #[cfg(unix)]
207 {
208 let Shell = std::env::var("SHELL").unwrap_or_else(|_| {
209 for Path in &["/bin/zsh", "/bin/bash", "/bin/sh"] {
210 if std::path::Path::new(Path).exists() {
211 return Path.to_string();
212 }
213 }
214 "/bin/sh".to_string()
215 });
216 Ok(json!(Shell))
217 }
218
219 #[cfg(target_os = "windows")]
220 {
221 let SystemRoot = std::env::var("SystemRoot").unwrap_or_else(|_| "C:\\Windows".to_string());
222 let PwshPath = format!("{}\\PowerShell\\7\\pwsh.exe", std::env::var("ProgramFiles").unwrap_or_default());
223 if std::path::Path::new(&PwshPath).exists() {
224 return Ok(json!(PwshPath));
225 }
226 Ok(json!(format!(
227 "{}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
228 SystemRoot
229 )))
230 }
231
232 #[cfg(not(any(unix, target_os = "windows")))]
233 {
234 Ok(json!("/bin/sh"))
235 }
236}
237
238pub async fn handle_local_pty_get_environment() -> Result<Value, String> {
240 let Env:HashMap<String, String> = std::env::vars().collect();
241 Ok(json!(Env))
242}