diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-04-13 23:45:46 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-04-13 23:45:46 +0300 |
| commit | b24abba471db0fe618cedfe0ed1059ede8118c64 (patch) | |
| tree | b7d4889ea18a3435835b977494a137a20baa1677 /src/app/input.rs | |
| parent | 1535a7117a47019f78d306ed4bba2300717357c1 (diff) | |
refactor extract app api and runtime command modules
Diffstat (limited to 'src/app/input.rs')
| -rw-r--r-- | src/app/input.rs | 138 |
1 files changed, 0 insertions, 138 deletions
diff --git a/src/app/input.rs b/src/app/input.rs index 67f84108..10e5a007 100644 --- a/src/app/input.rs +++ b/src/app/input.rs @@ -1,7 +1,5 @@ //! Input handling — translates crossterm key/mouse events into state mutations. -use std::process::{Command, Stdio}; - use bytes::Bytes; use crossterm::event::{KeyCode, KeyEvent, MouseButton, MouseEvent, MouseEventKind}; @@ -219,142 +217,6 @@ impl App { } } - fn launch_custom_command(&mut self, binding: crate::config::CustomCommandKeybind) { - let previous_toast = self.state.toast.clone(); - let result = match binding.action { - crate::config::CustomCommandAction::Shell => self.spawn_custom_command(&binding), - crate::config::CustomCommandAction::Pane => self.spawn_pane_command(&binding.command), - }; - match result { - Ok(()) => leave_navigate_mode(&mut self.state), - Err(err) => { - self.state.toast = Some(crate::app::state::ToastNotification { - kind: crate::app::state::ToastKind::NeedsAttention, - title: "custom command failed".to_string(), - context: err.to_string(), - }); - self.sync_toast_deadline(previous_toast); - } - } - } - - fn custom_command_env(&self) -> (Vec<(String, String)>, Option<std::path::PathBuf>) { - let mut env = vec![( - crate::api::SOCKET_PATH_ENV_VAR.to_string(), - crate::api::socket_path().display().to_string(), - )]; - if let Ok(current_exe) = std::env::current_exe() { - env.push(( - "HERDR_BIN_PATH".to_string(), - current_exe.display().to_string(), - )); - } - - let mut cwd = None; - if let Some(ws_idx) = self.state.active { - env.push(( - "HERDR_ACTIVE_WORKSPACE_ID".to_string(), - self.public_workspace_id(ws_idx), - )); - if let Some(workspace) = self.state.workspaces.get(ws_idx) { - let tab_idx = workspace.active_tab_index(); - if let Some(tab_id) = self.public_tab_id(ws_idx, tab_idx) { - env.push(("HERDR_ACTIVE_TAB_ID".to_string(), tab_id)); - } - if let Some(pane_id) = workspace.focused_pane_id() { - if let Some(public_pane_id) = self.public_pane_id(ws_idx, pane_id) { - env.push(("HERDR_ACTIVE_PANE_ID".to_string(), public_pane_id)); - } - if let Some(pane_cwd) = workspace - .active_tab() - .and_then(|tab| tab.cwd_for_pane(pane_id)) - { - env.push(( - "HERDR_ACTIVE_PANE_CWD".to_string(), - pane_cwd.display().to_string(), - )); - if pane_cwd.is_dir() { - cwd = Some(pane_cwd); - } - } - } - } - } - (env, cwd) - } - - fn spawn_custom_command( - &self, - binding: &crate::config::CustomCommandKeybind, - ) -> std::io::Result<()> { - let mut command = Command::new("/bin/sh"); - command - .arg("-lc") - .arg(&binding.command) - .stdin(Stdio::null()) - .stdout(Stdio::null()) - .stderr(Stdio::null()); - let (env, cwd) = self.custom_command_env(); - command.envs(env); - if let Some(cwd) = cwd { - command.current_dir(cwd); - } - command.spawn()?; - Ok(()) - } - - fn spawn_pane_command(&mut self, command: &str) -> std::io::Result<()> { - let Some(ws_idx) = self.state.active else { - return Err(std::io::Error::other("no active workspace")); - }; - let (rows, cols) = self.state.estimate_pane_size(); - let new_rows = rows.max(4); - let new_cols = cols.max(10); - let (env, _) = self.custom_command_env(); - - let ws = self - .state - .workspaces - .get_mut(ws_idx) - .ok_or_else(|| std::io::Error::other("active workspace disappeared"))?; - let tab_idx = ws.active_tab_index(); - let previous_focus = ws - .focused_pane_id() - .ok_or_else(|| std::io::Error::other("no focused pane"))?; - let previous_zoomed = ws.active_tab().map(|tab| tab.zoomed).unwrap_or(false); - let cwd = ws - .active_tab() - .and_then(|tab| tab.cwd_for_pane(previous_focus)); - let new_pane_id = ws.split_focused_command( - Direction::Horizontal, - new_rows, - new_cols, - cwd, - command, - &env, - self.state.pane_scrollback_limit_bytes, - self.state.host_terminal_theme, - )?; - ws.active_tab_mut() - .expect("workspace must have an active tab") - .layout - .focus_pane(new_pane_id); - ws.active_tab_mut() - .expect("workspace must have an active tab") - .zoomed = true; - self.overlay_panes.insert( - new_pane_id, - super::OverlayPaneState { - ws_idx, - tab_idx, - previous_focus, - previous_zoomed, - }, - ); - self.state.mode = Mode::Terminal; - Ok(()) - } - pub(super) fn handle_mouse(&mut self, mouse: MouseEvent) { if self.state.mode == Mode::ReleaseNotes { match mouse.kind { |
