diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bdad9ba8f..d0bcc71ba3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,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)) +* auto return to the tree view after staging the last hunk from the status diff view [[@WaterWhisperer](https://github.com/WaterWhisperer)] ([#2748](https://github.com/gitui-org/gitui/issues/2748)) ### Fixes * crash when opening submodule ([#2895](https://github.com/gitui-org/gitui/issues/2895)) diff --git a/src/components/utils/statustree.rs b/src/components/utils/statustree.rs index 6147e57ead..bf5ba9c95a 100644 --- a/src/components/utils/statustree.rs +++ b/src/components/utils/statustree.rs @@ -64,7 +64,7 @@ impl StatusTree { self.update_visibility(None, 0, true); self.available_selections = self.setup_available_selections(); - //NOTE: now that visibility is set we can make sure selection is visible + // NOTE: now that visibility is set we can make sure selection is visible if let Some(idx) = self.selection { self.selection = Some(self.find_visible_idx(idx)); } diff --git a/src/tabs/status.rs b/src/tabs/status.rs index 135cf18e4e..255a9b32fe 100644 --- a/src/tabs/status.rs +++ b/src/tabs/status.rs @@ -456,13 +456,27 @@ impl Status { } fn update_status(&mut self) -> Result<()> { + let diff_before_update = self.diff.current(); + let stage_status = self.git_status_stage.last()?; self.index.set_items(&stage_status.items)?; let workdir_status = self.git_status_workdir.last()?; self.index_wd.set_items(&workdir_status.items)?; - self.update_diff()?; + if Self::should_exit_diff_focus_after_status_update( + self.git_action_executed, + self.is_focus_on_diff(), + &diff_before_update, + self.selected_path().as_ref(), + ) { + self.switch_focus(match self.diff_target { + DiffTarget::Stage => Focus::Stage, + DiffTarget::WorkingDir => Focus::WorkDir, + })?; + } else { + self.update_diff()?; + } if self.git_action_executed { self.git_action_executed = false; @@ -482,6 +496,18 @@ impl Status { Ok(()) } + fn should_exit_diff_focus_after_status_update( + git_action_executed: bool, + is_focus_on_diff: bool, + diff_before_update: &(String, bool), + selected_path_after_update: Option<&(String, bool)>, + ) -> bool { + git_action_executed + && is_focus_on_diff + && !diff_before_update.0.is_empty() + && selected_path_after_update != Some(diff_before_update) + } + /// pub fn update_diff(&mut self) -> Result<()> { if let Some((path, is_stage)) = self.selected_path() {