Skip to content

Commit 039831a

Browse files
committed
Move to next stageable line after adding a line to a custom patch
While it's true that the behavior is a little different from the staging panel, where the staged lines are actually removed from the view and in many cases the selection stays more or less in the same place, it is still very useful to move to the next stageable thing in the custom patch building view too.
1 parent ce9fbe5 commit 039831a

File tree

5 files changed

+52
-20
lines changed

5 files changed

+52
-20
lines changed

pkg/commands/patch/patch.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,29 +115,41 @@ func (self *Patch) HunkContainingLine(idx int) int {
115115
return -1
116116
}
117117

118-
// Returns the patch line index of the next change (i.e. addition or deletion).
119-
func (self *Patch) GetNextChangeIdx(idx int) int {
118+
// Returns the patch line index of the next change (i.e. addition or deletion)
119+
// that matches the same "included" state, given the includedLines. If you don't
120+
// care about included states, pass nil for includedLines and false for included.
121+
func (self *Patch) GetNextChangeIdxOfSameIncludedState(idx int, includedLines []int, included bool) (int, bool) {
120122
idx = lo.Clamp(idx, 0, self.LineCount()-1)
121123

122124
lines := self.Lines()
123125

126+
isMatch := func(i int, line *PatchLine) bool {
127+
sameIncludedState := lo.Contains(includedLines, i) == included
128+
return line.IsChange() && sameIncludedState
129+
}
130+
124131
for i, line := range lines[idx:] {
125-
if line.isChange() {
126-
return i + idx
132+
if isMatch(i+idx, line) {
133+
return i + idx, true
127134
}
128135
}
129136

130137
// there are no changes from the cursor onwards so we'll instead
131138
// return the index of the last change
132139
for i := len(lines) - 1; i >= 0; i-- {
133140
line := lines[i]
134-
if line.isChange() {
135-
return i
141+
if isMatch(i, line) {
142+
return i, true
136143
}
137144
}
138145

139-
// should not be possible
140-
return 0
146+
return 0, false
147+
}
148+
149+
// Returns the patch line index of the next change (i.e. addition or deletion).
150+
func (self *Patch) GetNextChangeIdx(idx int) int {
151+
result, _ := self.GetNextChangeIdxOfSameIncludedState(idx, nil, false)
152+
return result
141153
}
142154

143155
// Returns the length of the patch in lines

pkg/gui/controllers/patch_building_controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ func (self *PatchBuildingController) toggleSelection() error {
161161
state.SetLineSelectMode()
162162
}
163163

164+
state.SelectNextStageableLineOfSameIncludedState(self.context().GetIncludedLineIndices(), firstSelectedChangeLineIsStaged)
165+
164166
return nil
165167
}
166168

pkg/gui/patch_exploring/state.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,3 +338,11 @@ func wrapPatchLines(diff string, view *gocui.View) ([]int, []int) {
338338
view.Wrap, view.Editable, strings.TrimSuffix(diff, "\n"), view.InnerWidth(), view.TabWidth)
339339
return viewLineIndices, patchLineIndices
340340
}
341+
342+
func (s *State) SelectNextStageableLineOfSameIncludedState(includedLines []int, included bool) {
343+
_, lastLineIdx := s.SelectedPatchRange()
344+
patchLineIdx, found := s.patch.GetNextChangeIdxOfSameIncludedState(lastLineIdx+1, includedLines, included)
345+
if found {
346+
s.SelectLine(s.viewLineIndices[patchLineIdx])
347+
}
348+
}

pkg/integration/tests/patch_building/move_to_index_partial.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ var MoveToIndexPartial = NewIntegrationTest(NewIntegrationTestArgs{
4848
Contains(`+third line2`),
4949
).
5050
PressPrimaryAction().
51-
SelectNextItem().
5251
PressPrimaryAction().
5352
Tap(func() {
5453
t.Views().Information().Content(Contains("Building patch"))

pkg/integration/tests/patch_building/specific_selection.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,20 @@ var SpecificSelection = NewIntegrationTest(NewIntegrationTestArgs{
6666
Contains(` 1f`),
6767
).
6868
PressPrimaryAction().
69-
// unlike in the staging panel, we don't remove lines from the patch building panel
70-
// upon 'adding' them. So the same lines will be selected
7169
SelectedLines(
72-
Contains(`@@ -1,6 +1,6 @@`),
73-
Contains(`-1a`),
74-
Contains(`+aa`),
75-
Contains(` 1b`),
76-
Contains(`-1c`),
77-
Contains(`+cc`),
78-
Contains(` 1d`),
79-
Contains(` 1e`),
80-
Contains(` 1f`),
70+
Contains(`@@ -17,9 +17,9 @@`),
71+
Contains(` 1q`),
72+
Contains(` 1r`),
73+
Contains(` 1s`),
74+
Contains(`-1t`),
75+
Contains(`-1u`),
76+
Contains(`-1v`),
77+
Contains(`+tt`),
78+
Contains(`+uu`),
79+
Contains(`+vv`),
80+
Contains(` 1w`),
81+
Contains(` 1x`),
82+
Contains(` 1y`),
8183
).
8284
Tap(func() {
8385
t.Views().Information().Content(Contains("Building patch"))
@@ -106,12 +108,21 @@ var SpecificSelection = NewIntegrationTest(NewIntegrationTestArgs{
106108
Contains("+2a"),
107109
).
108110
PressPrimaryAction().
111+
SelectedLines(
112+
Contains("+2b"),
113+
).
109114
NavigateToLine(Contains("+2c")).
110115
Press(keys.Universal.ToggleRangeSelect).
111116
NavigateToLine(Contains("+2e")).
112117
PressPrimaryAction().
118+
SelectedLines(
119+
Contains("+2f"),
120+
).
113121
NavigateToLine(Contains("+2g")).
114122
PressPrimaryAction().
123+
SelectedLines(
124+
Contains("+2h"),
125+
).
115126
Tap(func() {
116127
t.Views().Information().Content(Contains("Building patch"))
117128

0 commit comments

Comments
 (0)