Skip to content

Commit ce9fbe5

Browse files
committed
Toggle only added/deleted lines in patch building view
This improves the experience when selecting a hunk generously with the mouse, by dragging over it including some context lines above and below. Previously we would consider the "moving end" of the selection range for whether things need to be added or removed, but this doesn't make sense if it's a context line. Now we consider the first actual change line that is included in the range.
1 parent ef1a141 commit ce9fbe5

File tree

3 files changed

+30
-18
lines changed

3 files changed

+30
-18
lines changed

pkg/commands/patch/patch_builder.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,6 @@ func (p *PatchBuilder) RemoveFile(filename string) error {
124124
return nil
125125
}
126126

127-
func getIndicesForRange(first, last int) []int {
128-
indices := []int{}
129-
for i := first; i <= last; i++ {
130-
indices = append(indices, i)
131-
}
132-
return indices
133-
}
134-
135127
func (p *PatchBuilder) getFileInfo(filename string) (*fileInfo, error) {
136128
info, ok := p.fileInfoMap[filename]
137129
if ok {
@@ -152,24 +144,24 @@ func (p *PatchBuilder) getFileInfo(filename string) (*fileInfo, error) {
152144
return info, nil
153145
}
154146

155-
func (p *PatchBuilder) AddFileLineRange(filename string, firstLineIdx, lastLineIdx int) error {
147+
func (p *PatchBuilder) AddFileLineRange(filename string, lineIndices []int) error {
156148
info, err := p.getFileInfo(filename)
157149
if err != nil {
158150
return err
159151
}
160152
info.mode = PART
161-
info.includedLineIndices = lo.Union(info.includedLineIndices, getIndicesForRange(firstLineIdx, lastLineIdx))
153+
info.includedLineIndices = lo.Union(info.includedLineIndices, lineIndices)
162154

163155
return nil
164156
}
165157

166-
func (p *PatchBuilder) RemoveFileLineRange(filename string, firstLineIdx, lastLineIdx int) error {
158+
func (p *PatchBuilder) RemoveFileLineRange(filename string, lineIndices []int) error {
167159
info, err := p.getFileInfo(filename)
168160
if err != nil {
169161
return err
170162
}
171163
info.mode = PART
172-
info.includedLineIndices, _ = lo.Difference(info.includedLineIndices, getIndicesForRange(firstLineIdx, lastLineIdx))
164+
info.includedLineIndices, _ = lo.Difference(info.includedLineIndices, lineIndices)
173165
if len(info.includedLineIndices) == 0 {
174166
p.removeFile(info)
175167
}

pkg/gui/controllers/patch_building_controller.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,27 +126,33 @@ func (self *PatchBuildingController) toggleSelection() error {
126126
self.context().GetMutex().Lock()
127127
defer self.context().GetMutex().Unlock()
128128

129-
toggleFunc := self.c.Git().Patch.PatchBuilder.AddFileLineRange
130129
filename := self.c.Contexts().CommitFiles.GetSelectedPath()
131130
if filename == "" {
132131
return nil
133132
}
134133

135134
state := self.context().GetState()
136135

136+
// Get added/deleted lines in the selected patch range
137+
lineIndicesToToggle := state.ChangeLinesInSelectedPatchRange()
138+
if len(lineIndicesToToggle) == 0 {
139+
// Only context lines or header lines selected, so nothing to do
140+
return nil
141+
}
142+
137143
includedLineIndices, err := self.c.Git().Patch.PatchBuilder.GetFileIncLineIndices(filename)
138144
if err != nil {
139145
return err
140146
}
141-
currentLineIsStaged := lo.Contains(includedLineIndices, state.GetSelectedPatchLineIdx())
142-
if currentLineIsStaged {
147+
148+
toggleFunc := self.c.Git().Patch.PatchBuilder.AddFileLineRange
149+
firstSelectedChangeLineIsStaged := lo.Contains(includedLineIndices, lineIndicesToToggle[0])
150+
if firstSelectedChangeLineIsStaged {
143151
toggleFunc = self.c.Git().Patch.PatchBuilder.RemoveFileLineRange
144152
}
145153

146154
// add range of lines to those set for the file
147-
firstLineIdx, lastLineIdx := state.SelectedPatchRange()
148-
149-
if err := toggleFunc(filename, firstLineIdx, lastLineIdx); err != nil {
155+
if err := toggleFunc(filename, lineIndicesToToggle); err != nil {
150156
// might actually want to return an error here
151157
self.c.Log.Error(err)
152158
}

pkg/gui/patch_exploring/state.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,20 @@ func (s *State) SelectedPatchRange() (int, int) {
282282
return s.patchLineIndices[start], s.patchLineIndices[end]
283283
}
284284

285+
// Returns the line indices of the selected patch range that are changes (i.e. additions or deletions)
286+
func (s *State) ChangeLinesInSelectedPatchRange() []int {
287+
viewStart, viewEnd := s.SelectedViewRange()
288+
patchStart, patchEnd := s.patchLineIndices[viewStart], s.patchLineIndices[viewEnd]
289+
lines := s.patch.Lines()
290+
indices := []int{}
291+
for i := patchStart; i <= patchEnd; i++ {
292+
if lines[i].IsChange() {
293+
indices = append(indices, i)
294+
}
295+
}
296+
return indices
297+
}
298+
285299
func (s *State) CurrentLineNumber() int {
286300
return s.patch.LineNumberOfLine(s.patchLineIndices[s.selectedLineIdx])
287301
}

0 commit comments

Comments
 (0)