@@ -6,6 +6,40 @@ import (
66 "github.com/zyedidia/micro/v2/internal/util"
77)
88
9+ func padRegexp (r * regexp.Regexp ) (* regexp.Regexp , * regexp.Regexp , * regexp.Regexp , * regexp.Regexp ) {
10+ rPadStart := regexp .MustCompile (".(?:" + r .String ()+ ")" )
11+ rPadEnd := regexp .MustCompile ("(?:" + r .String ()+ ")." )
12+ rPadBoth := regexp .MustCompile (".(?:" + r .String ()+ ")." )
13+ return r , rPadStart , rPadEnd , rPadBoth
14+ }
15+
16+ func findLineParams (b * Buffer , start , end Loc , i int , rPadded [4 ]* regexp.Regexp ) ([]byte , int , * regexp.Regexp ) {
17+ l := b .LineBytes (i )
18+ charpos := 0
19+ ri := 0 // rPadNone
20+
21+ if i == end .Y {
22+ nchars := util .CharacterCount (l )
23+ end .X = util .Clamp (end .X , 0 , nchars )
24+ if end .X < nchars {
25+ l = util .SliceStart (l , end .X + 1 )
26+ ri = 2 // rPadEnd
27+ }
28+ }
29+
30+ if i == start .Y {
31+ nchars := util .CharacterCount (l )
32+ start .X = util .Clamp (start .X , 0 , nchars )
33+ if start .X > 0 {
34+ charpos = start .X - 1
35+ l = util .SliceEnd (l , charpos )
36+ ri += 1 // rPadNone -> rPadStart, rPadEnd -> rPadBoth
37+ }
38+ }
39+
40+ return l , charpos , rPadded [ri ]
41+ }
42+
943func (b * Buffer ) findDown (r * regexp.Regexp , start , end Loc ) ([2 ]Loc , bool ) {
1044 lastcn := util .CharacterCount (b .LineBytes (b .LinesNum () - 1 ))
1145 if start .Y > b .LinesNum ()- 1 {
@@ -21,33 +55,23 @@ func (b *Buffer) findDown(r *regexp.Regexp, start, end Loc) ([2]Loc, bool) {
2155 start , end = end , start
2256 }
2357
24- for i := start .Y ; i <= end .Y ; i ++ {
25- l := b .LineBytes (i )
26- charpos := 0
58+ rPadNone , rPadStart , rPadEnd , rPadBoth := padRegexp (r )
59+ rPadded := [4 ]* regexp.Regexp {rPadNone , rPadStart , rPadEnd , rPadBoth }
2760
28- if i == start .Y && start .Y == end .Y {
29- nchars := util .CharacterCount (l )
30- start .X = util .Clamp (start .X , 0 , nchars )
31- end .X = util .Clamp (end .X , 0 , nchars )
32- l = util .SliceStart (l , end .X )
33- l = util .SliceEnd (l , start .X )
34- charpos = start .X
35- } else if i == start .Y {
36- nchars := util .CharacterCount (l )
37- start .X = util .Clamp (start .X , 0 , nchars )
38- l = util .SliceEnd (l , start .X )
39- charpos = start .X
40- } else if i == end .Y {
41- nchars := util .CharacterCount (l )
42- end .X = util .Clamp (end .X , 0 , nchars )
43- l = util .SliceStart (l , end .X )
44- }
61+ for i := start .Y ; i <= end .Y ; i ++ {
62+ l , charpos , r := findLineParams (b , start , end , i , rPadded )
4563
4664 match := r .FindIndex (l )
4765
4866 if match != nil {
4967 start := Loc {charpos + util .RunePos (l , match [0 ]), i }
68+ if r == rPadStart || r == rPadBoth {
69+ start = start .Move (1 , b )
70+ }
5071 end := Loc {charpos + util .RunePos (l , match [1 ]), i }
72+ if r == rPadEnd || r == rPadBoth {
73+ end = end .Move (- 1 , b )
74+ }
5175 return [2 ]Loc {start , end }, true
5276 }
5377 }
@@ -69,34 +93,24 @@ func (b *Buffer) findUp(r *regexp.Regexp, start, end Loc) ([2]Loc, bool) {
6993 start , end = end , start
7094 }
7195
72- for i := end .Y ; i >= start .Y ; i -- {
73- l := b .LineBytes (i )
74- charpos := 0
96+ rPadNone , rPadStart , rPadEnd , rPadBoth := padRegexp (r )
97+ rPadded := [4 ]* regexp.Regexp {rPadNone , rPadStart , rPadEnd , rPadBoth }
7598
76- if i == start .Y && start .Y == end .Y {
77- nchars := util .CharacterCount (l )
78- start .X = util .Clamp (start .X , 0 , nchars )
79- end .X = util .Clamp (end .X , 0 , nchars )
80- l = util .SliceStart (l , end .X )
81- l = util .SliceEnd (l , start .X )
82- charpos = start .X
83- } else if i == start .Y {
84- nchars := util .CharacterCount (l )
85- start .X = util .Clamp (start .X , 0 , nchars )
86- l = util .SliceEnd (l , start .X )
87- charpos = start .X
88- } else if i == end .Y {
89- nchars := util .CharacterCount (l )
90- end .X = util .Clamp (end .X , 0 , nchars )
91- l = util .SliceStart (l , end .X )
92- }
99+ for i := end .Y ; i >= start .Y ; i -- {
100+ l , charpos , r := findLineParams (b , start , end , i , rPadded )
93101
94102 allMatches := r .FindAllIndex (l , - 1 )
95103
96104 if allMatches != nil {
97105 match := allMatches [len (allMatches )- 1 ]
98106 start := Loc {charpos + util .RunePos (l , match [0 ]), i }
107+ if r == rPadStart || r == rPadBoth {
108+ start = start .Move (1 , b )
109+ }
99110 end := Loc {charpos + util .RunePos (l , match [1 ]), i }
111+ if r == rPadEnd || r == rPadBoth {
112+ end = end .Move (- 1 , b )
113+ }
100114 return [2 ]Loc {start , end }, true
101115 }
102116 }
0 commit comments