-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: cross platform terminal settings (#22)
* feat: handle cross platform terminal and use local storage * feat: handle cross platform terminal and use local storage * feat: improve the code and made review adjsutments * fix: error handler in command output
- Loading branch information
Showing
11 changed files
with
500 additions
and
603 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,3 +22,4 @@ dist-ssr | |
*.njsproj | ||
*.sln | ||
*.sw? | ||
package-lock.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
pub mod container; | ||
pub mod extra; | ||
pub mod image; | ||
pub mod volume; | ||
pub mod network; | ||
pub mod extra; | ||
pub mod terminal; | ||
pub mod volume; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
use crate::utils::terminal::Terminal; | ||
#[tauri::command] | ||
pub fn get_available_terminals() -> Vec<String> { | ||
let current_os = if cfg!(target_os = "windows") { | ||
"windows" | ||
} else if cfg!(target_os = "macos") { | ||
"macos" | ||
} else { | ||
"linux" | ||
}; | ||
|
||
let variants = Terminal::variants(); | ||
|
||
variants | ||
.iter() | ||
.filter(|t| t.os() == current_os) | ||
.map(|t| t.app_name().to_string()) | ||
.collect() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,13 @@ | ||
|
||
|
||
pub const STORAGE_NAME: &str = "store.bin"; | ||
pub const DOCKER_TERMINAL: &str = "docker_terminal"; | ||
|
||
pub const MACOS_COMMAND_TEMPLATE: &str = r#" | ||
osascript -e 'tell application "System Events" | ||
do shell script "open -F -n -a {app_name}" | ||
delay 1.0 | ||
tell application "System Events" to tell process "{app_name}" to keystroke "{cmd}" & return | ||
end tell' | ||
"#; | ||
|
||
pub const DOCKER_TERMINAL_APP: &str = "docker_terminal"; | ||
pub const LINUX_COMMAND_TEMPLATE: &str = "{app_name} -e '{cmd}'"; | ||
pub const WINDOWS_COMMAND_TEMPLATE: &str = "{app_name} /C {cmd}"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
pub mod storage; | ||
|
||
pub mod utils; | ||
|
||
pub use utils::*; | ||
pub mod terminal; | ||
pub mod storage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
use crate::constants::DOCKER_TERMINAL; | ||
use crate::constants::{LINUX_COMMAND_TEMPLATE, MACOS_COMMAND_TEMPLATE, WINDOWS_COMMAND_TEMPLATE}; | ||
use crate::utils::storage::get_storage_path; | ||
use std::process::Command; | ||
use tauri::Manager; | ||
use tauri::{AppHandle, Wry}; | ||
use tauri_plugin_store::with_store; | ||
use tauri_plugin_store::Error; | ||
use tauri_plugin_store::StoreCollection; | ||
|
||
macro_rules! define_terminals { | ||
($($name:ident => $app_name:expr, $template:expr, $os:expr),*) => { | ||
#[derive(Debug, Clone, Copy)] | ||
pub enum Terminal { | ||
$($name),* | ||
} | ||
|
||
impl Terminal { | ||
pub fn app_name(&self) -> &'static str { | ||
match self { | ||
$(Terminal::$name => $app_name),* | ||
} | ||
} | ||
|
||
pub fn command_template(&self) -> &'static str { | ||
match self { | ||
$(Terminal::$name => $template),* | ||
} | ||
} | ||
|
||
pub fn os(&self) -> &'static str { | ||
match self { | ||
$(Terminal::$name => $os),* | ||
} | ||
} | ||
|
||
pub fn from_str(s: &str) -> Result<Self, String> { | ||
match s { | ||
$($app_name => Ok(Terminal::$name)),*, | ||
_ => Err(format!("Unknown terminal: {}", s)), | ||
} | ||
} | ||
|
||
pub fn variants() -> &'static [Terminal] { | ||
&[ | ||
$(Terminal::$name),* | ||
] | ||
} | ||
} | ||
}; | ||
} | ||
|
||
define_terminals!( | ||
GnomeTerminal => "gnome-terminal", LINUX_COMMAND_TEMPLATE, "linux", | ||
Konsole => "konsole", LINUX_COMMAND_TEMPLATE, "linux", | ||
Alacritty => "alacritty", LINUX_COMMAND_TEMPLATE, "linux", | ||
Xterm => "xterm", LINUX_COMMAND_TEMPLATE, "linux", | ||
Terminator => "terminator", LINUX_COMMAND_TEMPLATE, "linux", | ||
Xfce4Terminal => "xfce4-terminal", LINUX_COMMAND_TEMPLATE, "linux", | ||
Cmd => "cmd.exe", WINDOWS_COMMAND_TEMPLATE, "windows", | ||
Powershell => "powershell.exe", WINDOWS_COMMAND_TEMPLATE, "windows", | ||
Terminal => "Terminal", MACOS_COMMAND_TEMPLATE, "macos", | ||
ITerm => "iTerm", MACOS_COMMAND_TEMPLATE, "macos", | ||
WezTerm => "WezTerm", MACOS_COMMAND_TEMPLATE, "macos" | ||
); | ||
|
||
pub async fn get_terminal(app: &AppHandle<Wry>) -> Result<Terminal, String> { | ||
let stores = app.state::<StoreCollection<Wry>>(); | ||
let path = get_storage_path(); | ||
|
||
let terminal_str = with_store(app.clone(), stores, path.clone(), |store| { | ||
match store.get(DOCKER_TERMINAL) { | ||
Some(value) => Ok(value.clone()), | ||
None => Err(Error::NotFound(path.clone())), | ||
} | ||
}) | ||
.map_err(|e| format!("Failed to retrieve terminal from storage: {}", e))?; | ||
|
||
let terminal_str = terminal_str.as_str().unwrap_or_default().to_string(); | ||
|
||
Terminal::from_str(&terminal_str).map_err(|e| format!("Invalid terminal string: {}", e)) | ||
} | ||
|
||
pub fn open_terminal( | ||
term_app: &Terminal, | ||
command: Option<&str>, | ||
container_name: Option<&str>, | ||
) -> Result<String, String> { | ||
let command = match command { | ||
Some("exec") => match container_name { | ||
Some(container) => format!("docker exec -it {} sh", container), | ||
None => return Err("Container name must be provided for 'exec' command".to_string()), | ||
}, | ||
Some(cmd) => cmd.to_string(), | ||
None => return Err("No command provided".to_string()), | ||
}; | ||
|
||
let command_template = term_app.command_template(); | ||
let shell_command = command_template | ||
.replace("{cmd}", &command) | ||
.replace("{app_name}", term_app.app_name()); | ||
|
||
let (shell, args) = if cfg!(target_os = "windows") { | ||
("cmd.exe", vec!["/C", &shell_command]) | ||
} else { | ||
("sh", vec!["-c", &shell_command]) | ||
}; | ||
|
||
let output = Command::new(shell) | ||
.args(&args) | ||
.output() | ||
.map_err(|err| format!("Failed to execute terminal command: {}", err))?; | ||
|
||
if !output.stderr.is_empty() { | ||
let stderr = String::from_utf8_lossy(&output.stderr); | ||
return Err(format!("Terminal command error: {}", stderr)); | ||
} | ||
|
||
Ok(format!("Opening terminal with command: '{}'", command)) | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.