From 2828fb94fb5b793f3f3b597c06576a6dc0a61ad3 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Wed, 13 Nov 2024 15:46:22 +0100 Subject: [PATCH] Rewrap patch when view width changes This makes it so that when the staging view is resized, we keep the same patch line selected (as opposed to the same view line, which may correspond to a different patch line after resizing). It doesn't seem like a terribly important feature for resizing the window, but it is essential when initially entering the staging view: we select the first line of the first hunk in this case, but we do that before layout runs. At layout time the view is then split into unstaged/staged changes, and if this split is horizontal, the view gets narrower and may be wrapped in a different way. With this commit we ensure that the first line of the first hunk is still selected after that. --- pkg/gui/context/patch_explorer_context.go | 23 +++++++++++++++++------ pkg/gui/context/simple_context.go | 8 ++++++++ pkg/gui/patch_exploring/state.go | 17 +++++++++++++++++ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/pkg/gui/context/patch_explorer_context.go b/pkg/gui/context/patch_explorer_context.go index ab0d3f472..eb79dce86 100644 --- a/pkg/gui/context/patch_explorer_context.go +++ b/pkg/gui/context/patch_explorer_context.go @@ -39,12 +39,13 @@ func NewPatchExplorerContext( mutex: &deadlock.Mutex{}, getIncludedLineIndices: getIncludedLineIndices, SimpleContext: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - View: view, - WindowName: windowName, - Key: key, - Kind: types.MAIN_CONTEXT, - Focusable: true, - HighlightOnFocus: true, + View: view, + WindowName: windowName, + Key: key, + Kind: types.MAIN_CONTEXT, + Focusable: true, + HighlightOnFocus: true, + NeedsRerenderOnWidthChange: types.NEEDS_RERENDER_ON_WIDTH_CHANGE_WHEN_WIDTH_CHANGES, })), SearchTrait: NewSearchTrait(c), } @@ -58,6 +59,8 @@ func NewPatchExplorerContext( }), ) + ctx.SetHandleRenderFunc(ctx.OnViewWidthChanged) + return ctx } @@ -140,3 +143,11 @@ func (self *PatchExplorerContext) GetMutex() *deadlock.Mutex { func (self *PatchExplorerContext) ModelSearchResults(searchStr string, caseSensitive bool) []gocui.SearchPosition { return nil } + +func (self *PatchExplorerContext) OnViewWidthChanged() { + if state := self.GetState(); state != nil { + state.OnViewWidthChanged(self.GetView()) + self.setContent() + self.RenderAndFocus() + } +} diff --git a/pkg/gui/context/simple_context.go b/pkg/gui/context/simple_context.go index d78db7190..579f975e6 100644 --- a/pkg/gui/context/simple_context.go +++ b/pkg/gui/context/simple_context.go @@ -7,6 +7,7 @@ import ( type SimpleContext struct { *BaseContext + handleRenderFunc func() } func NewSimpleContext(baseContext *BaseContext) *SimpleContext { @@ -54,6 +55,13 @@ func (self *SimpleContext) HandleFocusLost(opts types.OnFocusLostOpts) { } func (self *SimpleContext) HandleRender() { + if self.handleRenderFunc != nil { + self.handleRenderFunc() + } +} + +func (self *SimpleContext) SetHandleRenderFunc(f func()) { + self.handleRenderFunc = f } func (self *SimpleContext) HandleRenderToMain() { diff --git a/pkg/gui/patch_exploring/state.go b/pkg/gui/patch_exploring/state.go index 2711dd2c7..c10807c8c 100644 --- a/pkg/gui/patch_exploring/state.go +++ b/pkg/gui/patch_exploring/state.go @@ -90,6 +90,23 @@ func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *Stat } } +func (s *State) OnViewWidthChanged(view *gocui.View) { + if !view.Wrap { + return + } + + selectedPatchLineIdx := s.patchLineIndices[s.selectedLineIdx] + var rangeStartPatchLineIdx int + if s.selectMode == RANGE { + rangeStartPatchLineIdx = s.patchLineIndices[s.rangeStartLineIdx] + } + s.viewLineIndices, s.patchLineIndices = wrapPatchLines(s.diff, view) + s.selectedLineIdx = s.viewLineIndices[selectedPatchLineIdx] + if s.selectMode == RANGE { + s.rangeStartLineIdx = s.viewLineIndices[rangeStartPatchLineIdx] + } +} + func (s *State) GetSelectedPatchLineIdx() int { return s.patchLineIndices[s.selectedLineIdx] }