Skip to content

Commit 3549de8

Browse files
committed
fix: enhance to support reverse selection and maintain context order
modified: pkg/commands/patch/patch_test.go modified: pkg/commands/patch/transform.go
1 parent e1d8550 commit 3549de8

File tree

2 files changed

+118
-8
lines changed

2 files changed

+118
-8
lines changed

pkg/commands/patch/patch_test.go

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,11 +730,13 @@ index 1234567..abcdefg 100644
730730
scenarios := []struct {
731731
testName string
732732
selectedIndices []int
733+
reverse bool
733734
expected string
734735
}{
735736
{
736737
testName: "non-contiguous selection keeps change pairs together",
737738
selectedIndices: []int{6, 8},
739+
reverse: false,
738740
expected: `--- a/test.c
739741
+++ b/test.c
740742
@@ -1,6 +1,6 @@
@@ -745,6 +747,87 @@ index 1234567..abcdefg 100644
745747
746748
return 0;
747749
}
750+
`,
751+
},
752+
{
753+
testName: "select only deletions without additions",
754+
selectedIndices: []int{6, 7},
755+
reverse: false,
756+
expected: `--- a/test.c
757+
+++ b/test.c
758+
@@ -1,6 +1,4 @@
759+
int main() {
760+
- // init something
761+
- int i = 0;
762+
763+
return 0;
764+
}
765+
`,
766+
},
767+
{
768+
testName: "select only additions without deletions",
769+
selectedIndices: []int{8, 9},
770+
reverse: false,
771+
expected: `--- a/test.c
772+
+++ b/test.c
773+
@@ -1,6 +1,8 @@
774+
int main() {
775+
// init something
776+
int i = 0;
777+
+ // init variables
778+
+ int x = 0;
779+
780+
return 0;
781+
}
782+
`,
783+
},
784+
{
785+
testName: "select all lines in change block",
786+
selectedIndices: []int{6, 7, 8, 9},
787+
reverse: false,
788+
expected: `--- a/test.c
789+
+++ b/test.c
790+
@@ -1,6 +1,6 @@
791+
int main() {
792+
- // init something
793+
- int i = 0;
794+
+ // init variables
795+
+ int x = 0;
796+
797+
return 0;
798+
}
799+
`,
800+
},
801+
{
802+
testName: "select second deletion and second addition",
803+
selectedIndices: []int{7, 9},
804+
reverse: false,
805+
expected: `--- a/test.c
806+
+++ b/test.c
807+
@@ -1,6 +1,6 @@
808+
int main() {
809+
// init something
810+
- int i = 0;
811+
+ int x = 0;
812+
813+
return 0;
814+
}
815+
`,
816+
},
817+
{
818+
testName: "reverse mode - non-contiguous selection",
819+
selectedIndices: []int{6, 8},
820+
reverse: true,
821+
expected: `--- a/test.c
822+
+++ b/test.c
823+
@@ -1,6 +1,6 @@
824+
int main() {
825+
- // init something
826+
+ // init variables
827+
int x = 0;
828+
829+
return 0;
830+
}
748831
`,
749832
},
750833
}
@@ -753,7 +836,7 @@ index 1234567..abcdefg 100644
753836
t.Run(s.testName, func(t *testing.T) {
754837
result := Parse(changeBlockDiff).
755838
Transform(TransformOpts{
756-
Reverse: false,
839+
Reverse: s.reverse,
757840
FileNameOverride: "test.c",
758841
IncludedLineIndices: s.selectedIndices,
759842
}).

pkg/commands/patch/transform.go

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,38 +134,65 @@ func (self *patchTransformer) transformHunkLines(hunk *Hunk, firstLineIdx int) [
134134
}
135135
isLineSelected := lo.Contains(self.opts.IncludedLineIndices, lineIdx)
136136

137-
// Check for change block (multiple consecutive deletions)
137+
// Handle change block (multiple consecutive deletions followed by additions)
138138
if line.Kind == DELETION {
139139
deletionCount := 0
140140
for j := i; j < len(hunk.bodyLines) && hunk.bodyLines[j].Kind == DELETION; j++ {
141141
deletionCount++
142142
}
143143
if deletionCount > 1 {
144144
selectedDeletions := []*PatchLine{}
145-
pendingContext := []*PatchLine{}
145+
leadingContext := []*PatchLine{}
146+
trailingContext := []*PatchLine{}
147+
foundFirstSelectedDeletion := false
148+
146149
for j := 0; j < deletionCount; j++ {
147150
delLine := hunk.bodyLines[i+j]
148151
delLineIdx := i + j + firstLineIdx + 1
149152
if lo.Contains(self.opts.IncludedLineIndices, delLineIdx) {
153+
foundFirstSelectedDeletion = true
150154
selectedDeletions = append(selectedDeletions, delLine)
151-
} else if (delLine.Kind == DELETION && !self.opts.Reverse) || (delLine.Kind == ADDITION && self.opts.Reverse) {
152-
pendingContext = append(pendingContext, &PatchLine{Kind: CONTEXT, Content: " " + delLine.Content[1:]})
155+
} else if !self.opts.Reverse {
156+
ctx := &PatchLine{Kind: CONTEXT, Content: " " + delLine.Content[1:]}
157+
if foundFirstSelectedDeletion {
158+
trailingContext = append(trailingContext, ctx)
159+
} else {
160+
leadingContext = append(leadingContext, ctx)
161+
}
153162
}
154163
}
155-
newLines = append(newLines, selectedDeletions...)
156164

157165
// Process additions in the block
166+
selectedAdditions := []*PatchLine{}
167+
trailingAdditionContext := []*PatchLine{}
168+
foundFirstSelectedAddition := false
158169
addIdx := i + deletionCount
159170
for addIdx < len(hunk.bodyLines) && hunk.bodyLines[addIdx].Kind == ADDITION {
171+
addLine := hunk.bodyLines[addIdx]
160172
addLineIdx := addIdx + firstLineIdx + 1
161173
if lo.Contains(self.opts.IncludedLineIndices, addLineIdx) {
162-
newLines = append(newLines, hunk.bodyLines[addIdx])
174+
foundFirstSelectedAddition = true
175+
selectedAdditions = append(selectedAdditions, addLine)
176+
} else if self.opts.Reverse {
177+
ctx := &PatchLine{Kind: CONTEXT, Content: " " + addLine.Content[1:]}
178+
if foundFirstSelectedAddition {
179+
trailingAdditionContext = append(trailingAdditionContext, ctx)
180+
}
181+
// In reverse mode, unselected additions before any selected addition are dropped.
182+
// Unselected additions after a selected addition become context.
163183
} else {
164184
skippedNewlineMessageIndex = addLineIdx + 1
165185
}
166186
addIdx++
167187
}
168-
newLines = append(newLines, pendingContext...)
188+
189+
// Output order: leading context, deletions, additions, trailing context, trailing addition context
190+
newLines = append(newLines, leadingContext...)
191+
newLines = append(newLines, selectedDeletions...)
192+
newLines = append(newLines, selectedAdditions...)
193+
newLines = append(newLines, trailingContext...)
194+
newLines = append(newLines, trailingAdditionContext...)
195+
169196
i = addIdx - 1
170197
continue
171198
}

0 commit comments

Comments
 (0)