diff --git a/CHANGELOG.md b/CHANGELOG.md index a7c6ee12..3bdad9ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed * use [tombi](https://github.com/tombi-toml/tombi) for all toml file formatting +* open the external editor from the status diff view [[@WaterWhisperer](https://github.com/WaterWhisperer)] ([#2805](https://github.com/gitui-org/gitui/issues/2805)) ### Fixes * crash when opening submodule ([#2895](https://github.com/gitui-org/gitui/issues/2895)) diff --git a/src/components/diff.rs b/src/components/diff.rs index 2eb492db..04779caa 100644 --- a/src/components/diff.rs +++ b/src/components/diff.rs @@ -152,6 +152,10 @@ impl DiffComponent { (self.current.path.clone(), self.current.is_stage) } /// + const fn can_edit_file(&self) -> bool { + !self.is_immutable && !self.current.path.is_empty() + } + /// pub fn clear(&mut self, pending: bool) { self.current = Current::default(); self.diff = None; @@ -770,6 +774,11 @@ impl Component for DiffComponent { ); if !self.is_immutable { + out.push(CommandInfo::new( + strings::commands::edit_item(&self.key_config), + self.can_edit_file(), + self.focused() && self.can_edit_file(), + )); out.push(CommandInfo::new( strings::commands::diff_hunk_remove(&self.key_config), self.selected_hunk.is_some(), @@ -876,6 +885,15 @@ impl Component for DiffComponent { ) { self.diff_hunk_move_up_down(-1); Ok(EventState::Consumed) + } else if key_match(e, self.key_config.keys.edit_file) + && self.can_edit_file() + { + self.queue.push( + InternalEvent::OpenExternalEditor(Some( + self.current.path.clone(), + )), + ); + Ok(EventState::Consumed) } else if key_match( e, self.key_config.keys.stage_unstage_item, @@ -945,7 +963,10 @@ impl Component for DiffComponent { #[cfg(test)] mod tests { use super::*; - use crate::ui::style::Theme; + use crate::{ + app::Environment, queue::InternalEvent, ui::style::Theme, + }; + use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers}; use std::io::Write; use std::rc::Rc; use tempfile::NamedTempFile; @@ -1012,4 +1033,30 @@ mod tests { ); } } + + #[test] + fn diff_component_opens_editor_for_current_file() { + let env = Environment::test_env(); + let mut diff = DiffComponent::new(&env, false); + + diff.focus(true); + diff.current.path = String::from("src/main.rs"); + + let event = Event::Key(KeyEvent::new( + KeyCode::Char('e'), + KeyModifiers::empty(), + )); + + assert!(matches!( + diff.event(&event).unwrap(), + EventState::Consumed + )); + + let event = env.queue.pop(); + assert!(matches!( + event, + Some(InternalEvent::OpenExternalEditor(Some(path))) + if path == "src/main.rs" + )); + } }