Open editor in diff view (#2904)

This commit is contained in:
WaterWhisperer 2026-04-11 02:38:29 +08:00 committed by GitHub
parent 7c538e3873
commit 8619c07f3f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 49 additions and 1 deletions

View file

@ -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))

View file

@ -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"
));
}
}