11package buffer
22
33import (
4+ "fmt"
45 "regexp"
56 "unicode/utf8"
67
@@ -32,9 +33,25 @@ func NewRegexpGroup(s string) (RegexpGroup, error) {
3233 return rgrp , err
3334}
3435
36+ func regexpGroup (re any ) (RegexpGroup , error ) {
37+ switch re := re .(type ) {
38+ case RegexpGroup :
39+ return re , nil
40+ case string :
41+ return NewRegexpGroup (re )
42+ default :
43+ return RegexpGroup {}, fmt .Errorf (`cannot convert "%v" (of type %[1]T) to type RegexpGroup` , re )
44+ }
45+ }
46+
3547type bytesFind func (* regexp.Regexp , []byte ) []int
3648
37- func (b * Buffer ) findDownFunc (rgrp RegexpGroup , start , end Loc , find bytesFind ) []Loc {
49+ func (b * Buffer ) findDownFunc (re any , start , end Loc , find bytesFind ) ([]Loc , error ) {
50+ rgrp , err := regexpGroup (re )
51+ if err != nil {
52+ return nil , err
53+ }
54+
3855 lastcn := util .CharacterCount (b .LineBytes (b .LinesNum () - 1 ))
3956 if start .Y > b .LinesNum ()- 1 {
4057 start .X = lastcn - 1
@@ -95,30 +112,35 @@ func (b *Buffer) findDownFunc(rgrp RegexpGroup, start, end Loc, find bytesFind)
95112 } else { // start or end of unused submatch
96113 return LocVoid ()
97114 }
98- })
115+ }), nil
99116 }
100117 }
101- return nil
118+ return nil , nil
102119}
103120
104- type bufferFind func (* Buffer , RegexpGroup , Loc , Loc ) []Loc
121+ type bufferFind func (* Buffer , any , Loc , Loc ) ( []Loc , error )
105122
106123// FindDown returns a slice containing the start and end positions
107- // of the first match of `rgrp ` between `start` and `end`, or nil
124+ // of the first match of `re ` between `start` and `end`, or nil
108125// if no match exists.
109- func (b * Buffer ) FindDown (rgrp RegexpGroup , start , end Loc ) []Loc {
110- return b .findDownFunc (rgrp , start , end , (* regexp .Regexp ).FindIndex )
126+ func (b * Buffer ) FindDown (re any , start , end Loc ) ( []Loc , error ) {
127+ return b .findDownFunc (re , start , end , (* regexp .Regexp ).FindIndex )
111128}
112129
113130// FindDownSubmatch returns a slice containing the start and end positions
114- // of the first match of `rgrp ` between `start` and `end` plus those
131+ // of the first match of `re ` between `start` and `end` plus those
115132// of all submatches (capturing groups), or nil if no match exists.
116133// The start and end positions of an unused submatch are void.
117- func (b * Buffer ) FindDownSubmatch (rgrp RegexpGroup , start , end Loc ) []Loc {
118- return b .findDownFunc (rgrp , start , end , (* regexp .Regexp ).FindSubmatchIndex )
134+ func (b * Buffer ) FindDownSubmatch (re any , start , end Loc ) ( []Loc , error ) {
135+ return b .findDownFunc (re , start , end , (* regexp .Regexp ).FindSubmatchIndex )
119136}
120137
121- func (b * Buffer ) findUpFunc (rgrp RegexpGroup , start , end Loc , find bytesFind ) []Loc {
138+ func (b * Buffer ) findUpFunc (re any , start , end Loc , find bytesFind ) ([]Loc , error ) {
139+ rgrp , err := regexpGroup (re )
140+ if err != nil {
141+ return nil , err
142+ }
143+
122144 lastcn := util .CharacterCount (b .LineBytes (b .LinesNum () - 1 ))
123145 if start .Y > b .LinesNum ()- 1 {
124146 start .X = lastcn - 1
@@ -139,24 +161,24 @@ func (b *Buffer) findUpFunc(rgrp RegexpGroup, start, end Loc, find bytesFind) []
139161 from := Loc {0 , i }.Clamp (start , end )
140162 to := Loc {charCount , i }.Clamp (start , end )
141163
142- b .findAllFuncFunc (rgrp , from , to , func (b * Buffer , rgrp RegexpGroup , start , end Loc ) []Loc {
164+ b .findAllFuncFunc (rgrp , from , to , func (b * Buffer , re any , start , end Loc ) ( []Loc , error ) {
143165 return b .findDownFunc (rgrp , start , end , find )
144166 }, func (match []Loc ) {
145167 locs = match
146168 })
147169
148170 if locs != nil {
149- return locs
171+ return locs , nil
150172 }
151173 }
152- return nil
174+ return nil , nil
153175}
154176
155177// FindUp returns a slice containing the start and end positions
156- // of the last match of `rgrp ` between `start` and `end`, or nil
178+ // of the last match of `re ` between `start` and `end`, or nil
157179// if no match exists.
158- func (b * Buffer ) FindUp (rgrp RegexpGroup , start , end Loc ) []Loc {
159- return b .findUpFunc (rgrp , start , end , func (re * regexp.Regexp , l []byte ) []int {
180+ func (b * Buffer ) FindUp (re any , start , end Loc ) ( []Loc , error ) {
181+ return b .findUpFunc (re , start , end , func (re * regexp.Regexp , l []byte ) []int {
160182 allMatches := re .FindAllIndex (l , - 1 )
161183 if allMatches != nil {
162184 return allMatches [len (allMatches )- 1 ]
@@ -167,12 +189,12 @@ func (b *Buffer) FindUp(rgrp RegexpGroup, start, end Loc) []Loc {
167189}
168190
169191// FindUpSubmatch returns a slice containing the start and end positions
170- // of the last match of `rgrp ` between `start` and `end` plus those
192+ // of the last match of `re ` between `start` and `end` plus those
171193// of all submatches (capturing groups), or nil if no match exists.
172194// The start and end positions of an unused submatch are void.
173- func (b * Buffer ) FindUpSubmatch (rgrp RegexpGroup , start , end Loc ) []Loc {
174- return b .findUpFunc (rgrp , start , end , func (re * regexp.Regexp , l []byte ) []int {
175- allMatches := re .FindAllSubmatchIndex (l , - 1 )
195+ func (b * Buffer ) FindUpSubmatch (re any , start , end Loc ) ( []Loc , error ) {
196+ return b .findUpFunc (re , start , end , func (r * regexp.Regexp , l []byte ) []int {
197+ allMatches := r .FindAllSubmatchIndex (l , - 1 )
176198 if allMatches != nil {
177199 return allMatches [len (allMatches )- 1 ]
178200 } else {
@@ -181,11 +203,15 @@ func (b *Buffer) FindUpSubmatch(rgrp RegexpGroup, start, end Loc) []Loc {
181203 })
182204}
183205
184- func (b * Buffer ) findAllFuncFunc (r RegexpGroup , start , end Loc , find bufferFind , f func ([]Loc )) int {
206+ func (b * Buffer ) findAllFuncFunc (re any , start , end Loc , find bufferFind , f func ([]Loc )) (int , error ) {
207+ rgrp , err := regexpGroup (re )
208+ if err != nil {
209+ return - 1 , err
210+ }
185211 n := 0
186212 loc := start
187213 for {
188- match := find (b , r , loc , end )
214+ match , _ := find (b , rgrp , loc , end )
189215 if match == nil {
190216 break
191217 }
@@ -199,55 +225,45 @@ func (b *Buffer) findAllFuncFunc(r RegexpGroup, start, end Loc, find bufferFind,
199225 break
200226 }
201227 }
202- return n
228+ return n , nil
203229}
204230
205231// FindAllFunc calls the function `f` once for each match between `start`
206- // and `end` of the regexp given by `s `. The argument of `f` is the slice
232+ // and `end` of the regexp given by `re `. The argument of `f` is the slice
207233// containing the start and end positions of the match. FindAllFunc returns
208234// the number of matches plus any error that occured when compiling the regexp.
209- func (b * Buffer ) FindAllFunc (s string , start , end Loc , f func ([]Loc )) (int , error ) {
210- rgrp , err := NewRegexpGroup (s )
211- if err == nil {
212- return b .findAllFuncFunc (rgrp , start , end , (* Buffer ).FindDown , f ), nil
213- } else {
214- return - 1 , err
215- }
235+ func (b * Buffer ) FindAllFunc (re any , start , end Loc , f func ([]Loc )) (int , error ) {
236+ return b .findAllFuncFunc (re , start , end , (* Buffer ).FindDown , f )
216237}
217238
218239// FindAll returns a slice containing the start and end positions of all
219- // matches between `start` and `end` of the regexp given by `s `, plus any
240+ // matches between `start` and `end` of the regexp given by `re `, plus any
220241// error that occured when compiling the regexp. If no match is found, the
221242// slice returned is nil.
222- func (b * Buffer ) FindAll (s string , start , end Loc ) ([][]Loc , error ) {
243+ func (b * Buffer ) FindAll (re any , start , end Loc ) ([][]Loc , error ) {
223244 var matches [][]Loc
224- _ , err := b .FindAllFunc (s , start , end , func (match []Loc ) {
245+ _ , err := b .FindAllFunc (re , start , end , func (match []Loc ) {
225246 matches = append (matches , match )
226247 })
227248 return matches , err
228249}
229250
230251// FindAllSubmatchFunc calls the function `f` once for each match between
231- // `start` and `end` of the regexp given by `s `. The argument of `f` is the
252+ // `start` and `end` of the regexp given by `re `. The argument of `f` is the
232253// slice containing the start and end positions of the match and all submatches
233254// (capturing groups). FindAllSubmatch Func returns the number of matches plus
234255// any error that occured when compiling the regexp.
235- func (b * Buffer ) FindAllSubmatchFunc (s string , start , end Loc , f func ([]Loc )) (int , error ) {
236- rgrp , err := NewRegexpGroup (s )
237- if err == nil {
238- return b .findAllFuncFunc (rgrp , start , end , (* Buffer ).FindDownSubmatch , f ), nil
239- } else {
240- return - 1 , err
241- }
256+ func (b * Buffer ) FindAllSubmatchFunc (re any , start , end Loc , f func ([]Loc )) (int , error ) {
257+ return b .findAllFuncFunc (re , start , end , (* Buffer ).FindDownSubmatch , f )
242258}
243259
244260// FindAllSubmatch returns a slice containing the start and end positions of
245261// all matches and all submatches (capturing groups) between `start` and `end`
246- // of the regexp given by `s `, plus any error that occured when compiling
262+ // of the regexp given by `re `, plus any error that occured when compiling
247263// the regexp. If no match is found, the slice returned is nil.
248- func (b * Buffer ) FindAllSubmatch (s string , start , end Loc ) ([][]Loc , error ) {
264+ func (b * Buffer ) FindAllSubmatch (re any , start , end Loc ) ([][]Loc , error ) {
249265 var matches [][]Loc
250- _ , err := b .FindAllSubmatchFunc (s , start , end , func (match []Loc ) {
266+ _ , err := b .FindAllSubmatchFunc (re , start , end , func (match []Loc ) {
251267 matches = append (matches , match )
252268 })
253269 return matches , err
@@ -290,14 +306,14 @@ func (b *Buffer) FindNext(s string, start, end, from Loc, down bool, useRegex bo
290306
291307 var match []Loc
292308 if down {
293- match = b .FindDown (rgrp , from , end )
309+ match , _ = b .FindDown (rgrp , from , end )
294310 if match == nil {
295- match = b .FindDown (rgrp , start , end )
311+ match , _ = b .FindDown (rgrp , start , end )
296312 }
297313 } else {
298- match = b .FindUp (rgrp , from , start )
314+ match , _ = b .FindUp (rgrp , from , start )
299315 if match == nil {
300- match = b .FindUp (rgrp , end , start )
316+ match , _ = b .FindUp (rgrp , end , start )
301317 }
302318 }
303319 if match != nil {
@@ -307,33 +323,33 @@ func (b *Buffer) FindNext(s string, start, end, from Loc, down bool, useRegex bo
307323 }
308324}
309325
310- func (b * Buffer ) replaceAllFuncFunc (s string , start , end Loc , find bufferFind , repl func (match []Loc ) []byte ) (int , Loc , error ) {
311- rgrp , err := NewRegexpGroup (s )
312- if err != nil {
313- return - 1 , LocVoid (), err
314- }
315-
326+ func (b * Buffer ) replaceAllFuncFunc (re any , start , end Loc , find bufferFind , repl func (match []Loc ) []byte ) (int , Loc , error ) {
316327 charsEnd := util .CharacterCount (b .LineBytes (end .Y ))
317328 var deltas []Delta
318329
319- n := b .findAllFuncFunc (rgrp , start , end , find , func (match []Loc ) {
330+ n , err := b .findAllFuncFunc (re , start , end , find , func (match []Loc ) {
320331 deltas = append (deltas , Delta {repl (match ), match [0 ], match [1 ]})
321332 })
333+
334+ if err != nil {
335+ return - 1 , LocVoid (), err
336+ }
337+
322338 b .MultipleReplace (deltas )
323339
324340 deltaX := util .CharacterCount (b .LineBytes (end .Y )) - charsEnd
325341 return n , Loc {end .X + deltaX , end .Y }, nil
326342}
327343
328- // ReplaceAll replaces all matches of the regexp `s ` in the given area. The
344+ // ReplaceAll replaces all matches of the regexp `re ` in the given area. The
329345// new text is obtained from `template` by replacing each variable with the
330346// corresponding submatch as in `Regexp.Expand`. The function returns the
331347// number of replacements made, the new end position and any error that
332348// occured during regexp compilation
333- func (b * Buffer ) ReplaceAll (s string , start , end Loc , template []byte ) (int , Loc , error ) {
349+ func (b * Buffer ) ReplaceAll (re any , start , end Loc , template []byte ) (int , Loc , error ) {
334350 var replace []byte
335351
336- find := func (b * Buffer , r RegexpGroup , start , end Loc ) []Loc {
352+ find := func (b * Buffer , r any , start , end Loc ) ( []Loc , error ) {
337353 return b .findDownFunc (r , start , end , func (re * regexp.Regexp , l []byte ) []int {
338354 match := re .FindSubmatchIndex (l )
339355 if match == nil {
@@ -344,34 +360,34 @@ func (b *Buffer) ReplaceAll(s string, start, end Loc, template []byte) (int, Loc
344360 })
345361 }
346362
347- return b .replaceAllFuncFunc (s , start , end , find , func (match []Loc ) []byte {
363+ return b .replaceAllFuncFunc (re , start , end , find , func (match []Loc ) []byte {
348364 return replace
349365 })
350366}
351367
352- // ReplaceAllLiteral replaces all matches of the regexp `s ` with `repl` in
368+ // ReplaceAllLiteral replaces all matches of the regexp `re ` with `repl` in
353369// the given area. The function returns the number of replacements made, the
354370// new end position and any error that occured during regexp compilation
355- func (b * Buffer ) ReplaceAllLiteral (s string , start , end Loc , repl []byte ) (int , Loc , error ) {
356- return b .ReplaceAllFunc (s , start , end , func ([]Loc ) []byte {
371+ func (b * Buffer ) ReplaceAllLiteral (re any , start , end Loc , repl []byte ) (int , Loc , error ) {
372+ return b .ReplaceAllFunc (re , start , end , func ([]Loc ) []byte {
357373 return repl
358374 })
359375}
360376
361- // ReplaceAllFunc replaces all matches of the regexp `s ` with `repl(match)`
377+ // ReplaceAllFunc replaces all matches of the regexp `re ` with `repl(match)`
362378// in the given area, where `match` is the slice containing start and end
363379// positions of the match. The function returns the number of replacements
364380// made, the new end position and any error that occured during regexp
365381// compilation
366- func (b * Buffer ) ReplaceAllFunc (s string , start , end Loc , repl func (match []Loc ) []byte ) (int , Loc , error ) {
367- return b .replaceAllFuncFunc (s , start , end , (* Buffer ).FindDown , repl )
382+ func (b * Buffer ) ReplaceAllFunc (re any , start , end Loc , repl func (match []Loc ) []byte ) (int , Loc , error ) {
383+ return b .replaceAllFuncFunc (re , start , end , (* Buffer ).FindDown , repl )
368384}
369385
370- // ReplaceAllSubmatchFunc replaces all matches of the regexp `s ` with
386+ // ReplaceAllSubmatchFunc replaces all matches of the regexp `re ` with
371387// `repl(match)` in the given area, where `match` is the slice containing
372388// start and end positions of the match and all submatches. The function
373389// returns the number of replacements made, the new end position and any
374390// error that occured during regexp compilation
375- func (b * Buffer ) ReplaceAllSubmatchFunc (s string , start , end Loc , repl func (match []Loc ) []byte ) (int , Loc , error ) {
376- return b .replaceAllFuncFunc (s , start , end , (* Buffer ).FindDownSubmatch , repl )
391+ func (b * Buffer ) ReplaceAllSubmatchFunc (re any , start , end Loc , repl func (match []Loc ) []byte ) (int , Loc , error ) {
392+ return b .replaceAllFuncFunc (re , start , end , (* Buffer ).FindDownSubmatch , repl )
377393}
0 commit comments