@@ -194,64 +194,50 @@ func (b *Buffer) ReplaceRegex(start, end Loc, search *regexp.Regexp, replace []b
194194
195195 charsEnd := util .CharacterCount (b .LineBytes (end .Y ))
196196 found := 0
197+ var charCount int
197198 var deltas []Delta
198199
199- // This replacement function works in general, but it creates a separate
200- // modification for each match. We only use it for the first and last lines,
201- // which may use padded regexps
202- replaceFirstLast := func (start , end Loc ) []Delta {
203- matches := b .findAll (search , start , end )
204- for j := len (matches ) - 1 ; j >= 0 ; j -- {
205- // if we counted upwards, the different deltas would interfere
206- match := matches [j ]
207- var newText []byte
208- if captureGroups {
209- newText = search .ReplaceAll (b .Substr (match [0 ], match [1 ]), replace )
210- } else {
211- newText = replace
200+ for i := start .Y ; i <= end .Y ; i ++ {
201+ l := b .LineBytes (i )
202+ charCount = util .CharacterCount (l )
203+ if i == start .Y || i == end .Y {
204+ // This replacement code works in general, but it creates a separate
205+ // modification for each match. We only use it for the first and last
206+ // lines, which may use padded regexps
207+
208+ from := Loc {0 , i }.Clamp (start , end )
209+ to := Loc {charCount , i }.Clamp (start , end )
210+ matches := b .findAll (search , from , to )
211+ found += len (matches )
212+
213+ for j := len (matches ) - 1 ; j >= 0 ; j -- {
214+ // if we counted upwards, the different deltas would interfere
215+ match := matches [j ]
216+ var newText []byte
217+ if captureGroups {
218+ newText = search .ReplaceAll (b .Substr (match [0 ], match [1 ]), replace )
219+ } else {
220+ newText = replace
221+ }
222+ deltas = append (deltas , Delta {newText , match [0 ], match [1 ]})
212223 }
213- deltas = append (deltas , Delta {newText , match [0 ], match [1 ]})
214- }
215- found += len (matches )
216- return deltas
217- }
218-
219- replaceMiddle := func (in []byte ) []byte {
220- found ++
221- var result []byte
222- if captureGroups {
223- match := search .FindSubmatchIndex (in )
224- result = search .Expand (result , replace , in , match )
225224 } else {
226- result = replace
225+ newLine := search .ReplaceAllFunc (l , func (in []byte ) []byte {
226+ found ++
227+ var result []byte
228+ if captureGroups {
229+ match := search .FindSubmatchIndex (in )
230+ result = search .Expand (result , replace , in , match )
231+ } else {
232+ result = replace
233+ }
234+ return result
235+ })
236+ deltas = append (deltas , Delta {newLine , Loc {0 , i }, Loc {charCount , i }})
227237 }
228- return result
229- }
230-
231- // first line (if different from last line)
232- if start .Y < end .Y {
233- n := util .CharacterCount (b .LineBytes (start .Y ))
234- startEnd := Loc {n , start .Y }
235- deltas = replaceFirstLast (start , startEnd )
236- }
237-
238- // middle lines
239- for i := start .Y + 1 ; i < end .Y ; i ++ {
240- l := b .LineBytes (i )
241- n := util .CharacterCount (l )
242- newLine := search .ReplaceAllFunc (l , replaceMiddle )
243- deltas = append (deltas , Delta {newLine , Loc {0 , i }, Loc {n , i }})
244- }
245-
246- // last line
247- endStart := Loc {0 , end .Y }
248- if start .Y == end .Y {
249- endStart = start
250238 }
251- deltas = replaceFirstLast (endStart , end )
252239
253240 b .MultipleReplace (deltas )
254241
255- deltaEndX := util .CharacterCount (b .LineBytes (end .Y )) - charsEnd
256- return found , deltaEndX
242+ return found , charCount - charsEnd
257243}
0 commit comments