Skip to content

Commit c0ba33e

Browse files
committed
match beginning and end of line correctly
1 parent 8cdf68b commit c0ba33e

1 file changed

Lines changed: 54 additions & 40 deletions

File tree

internal/buffer/search.go

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
943
func (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

Comments
 (0)