From dd47ef73547d23a158237538ec657dcd0f801a63 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sat, 12 Jul 2025 17:25:27 +0200 Subject: [PATCH 1/2] Make prepareConversionArrays a little more concurrency safe I have seen cases where during a rebase (two nonModelItems) all entries in viewIndicesByModelIndex beyond the second nonModelItem were off by 4 rather than 2 as I would expect. The only explanation I have for this is that the function was called concurrently. Improve this by working on a local variable and only assign to self at the end; this is not a real fix for the concurrency issue of course, but it makes it much less likely to be a problem in practice. --- pkg/gui/context/list_renderer.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pkg/gui/context/list_renderer.go b/pkg/gui/context/list_renderer.go index 9bde5fb4b..e863045e0 100644 --- a/pkg/gui/context/list_renderer.go +++ b/pkg/gui/context/list_renderer.go @@ -99,17 +99,19 @@ func (self *ListRenderer) renderLines(startIdx int, endIdx int) string { func (self *ListRenderer) prepareConversionArrays(nonModelItems []*NonModelItem) { self.numNonModelItems = len(nonModelItems) - self.viewIndicesByModelIndex = lo.Range(self.list.Len() + 1) - self.modelIndicesByViewIndex = lo.Range(self.list.Len() + 1) + viewIndicesByModelIndex := lo.Range(self.list.Len() + 1) + modelIndicesByViewIndex := lo.Range(self.list.Len() + 1) offset := 0 for _, item := range nonModelItems { for i := item.Index; i <= self.list.Len(); i++ { - self.viewIndicesByModelIndex[i]++ + viewIndicesByModelIndex[i]++ } - self.modelIndicesByViewIndex = slices.Insert( - self.modelIndicesByViewIndex, item.Index+offset, self.modelIndicesByViewIndex[item.Index+offset]) + modelIndicesByViewIndex = slices.Insert( + modelIndicesByViewIndex, item.Index+offset, modelIndicesByViewIndex[item.Index+offset]) offset++ } + self.viewIndicesByModelIndex = viewIndicesByModelIndex + self.modelIndicesByViewIndex = modelIndicesByViewIndex } func (self *ListRenderer) insertNonModelItems( From 2b41a27d92fc7e50d14895fe8ab228f6a255ae49 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sat, 12 Jul 2025 16:19:46 +0200 Subject: [PATCH 2/2] Fix search results being off by two lines during rebase or in divergence view We forgot to convert the model indices to view indices in searchModelCommits. This needs to be done for search results to be highlighted correctly in the "divergence from upstream" view, which adds "--- Remote/Local ---" entries, and during a rebase, where we have "--- Pending rebase todos ---" and "--- Commits ---" which offset view indices from model indices. --- pkg/gui/context/local_commits_context.go | 8 +++++--- pkg/gui/context/sub_commits_context.go | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/gui/context/local_commits_context.go b/pkg/gui/context/local_commits_context.go index c43d041d3..c11770986 100644 --- a/pkg/gui/context/local_commits_context.go +++ b/pkg/gui/context/local_commits_context.go @@ -223,7 +223,7 @@ func (self *LocalCommitsContext) RefForAdjustingLineNumberInDiff() string { } func (self *LocalCommitsContext) ModelSearchResults(searchStr string, caseSensitive bool) []gocui.SearchPosition { - return searchModelCommits(caseSensitive, self.GetCommits(), self.ColumnPositions(), searchStr) + return searchModelCommits(caseSensitive, self.GetCommits(), self.ColumnPositions(), self.ModelIndexToViewIndex, searchStr) } func (self *LocalCommitsViewModel) SetLimitCommits(value bool) { @@ -266,7 +266,9 @@ func shouldShowGraph(c *ContextCommon) bool { return false } -func searchModelCommits(caseSensitive bool, commits []*models.Commit, columnPositions []int, searchStr string) []gocui.SearchPosition { +func searchModelCommits(caseSensitive bool, commits []*models.Commit, columnPositions []int, + modelToViewIndex func(int) int, searchStr string, +) []gocui.SearchPosition { if columnPositions == nil { // This should never happen. We are being called at a time where our // entire view content is scrolled out of view, so that we didn't draw @@ -283,7 +285,7 @@ func searchModelCommits(caseSensitive bool, commits []*models.Commit, columnPosi // searching for a commit hash that is longer than the truncated hash // that we render. So we just set the XStart and XEnd values to the // start and end of the commit hash column, which is the second one. - result := gocui.SearchPosition{XStart: columnPositions[1], XEnd: columnPositions[2] - 1, Y: idx} + result := gocui.SearchPosition{XStart: columnPositions[1], XEnd: columnPositions[2] - 1, Y: modelToViewIndex(idx)} return result, strings.Contains(normalize(commit.Hash()), searchStr) || strings.Contains(normalize(commit.Name), searchStr) || strings.Contains(normalize(commit.ExtraInfo), searchStr) // allow searching for tags diff --git a/pkg/gui/context/sub_commits_context.go b/pkg/gui/context/sub_commits_context.go index ac28aca2e..e489511a0 100644 --- a/pkg/gui/context/sub_commits_context.go +++ b/pkg/gui/context/sub_commits_context.go @@ -225,7 +225,7 @@ func (self *SubCommitsContext) RefForAdjustingLineNumberInDiff() string { } func (self *SubCommitsContext) ModelSearchResults(searchStr string, caseSensitive bool) []gocui.SearchPosition { - return searchModelCommits(caseSensitive, self.GetCommits(), self.ColumnPositions(), searchStr) + return searchModelCommits(caseSensitive, self.GetCommits(), self.ColumnPositions(), self.ModelIndexToViewIndex, searchStr) } func (self *SubCommitsContext) IndexForGotoBottom() int {