Skip to content

Commit a05320a

Browse files
committed
added FindNextSubmatch
1 parent 56c1f75 commit a05320a

1 file changed

Lines changed: 47 additions & 23 deletions

File tree

internal/buffer/search.go

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"github.com/zyedidia/micro/v2/internal/util"
77
)
88

9-
func (b *Buffer) findDown(r *regexp.Regexp, start, end Loc) ([2]Loc, bool) {
9+
func (b *Buffer) findDown(r *regexp.Regexp, start, end Loc) ([]Loc, bool) {
1010
lastcn := util.CharacterCount(b.LineBytes(b.LinesNum() - 1))
1111
if start.Y > b.LinesNum()-1 {
1212
start.X = lastcn - 1
@@ -43,18 +43,24 @@ func (b *Buffer) findDown(r *regexp.Regexp, start, end Loc) ([2]Loc, bool) {
4343
l = util.SliceStart(l, end.X)
4444
}
4545

46-
match := r.FindIndex(l)
46+
match := r.FindSubmatchIndex(l)
4747

4848
if match != nil {
49-
start := Loc{charpos + util.RunePos(l, match[0]), i}
50-
end := Loc{charpos + util.RunePos(l, match[1]), i}
51-
return [2]Loc{start, end}, true
49+
loc := make([]Loc, len(match))
50+
for j, x := range match {
51+
if x == -1 { // submatch doesn't occur in match
52+
loc[j] = Loc{-1, -1}
53+
} else {
54+
loc[j] = Loc{charpos + util.RunePos(l, x), i}
55+
}
56+
}
57+
return loc, true
5258
}
5359
}
54-
return [2]Loc{}, false
60+
return []Loc{}, false
5561
}
5662

57-
func (b *Buffer) findUp(r *regexp.Regexp, start, end Loc) ([2]Loc, bool) {
63+
func (b *Buffer) findUp(r *regexp.Regexp, start, end Loc) ([]Loc, bool) {
5864
lastcn := util.CharacterCount(b.LineBytes(b.LinesNum() - 1))
5965
if start.Y > b.LinesNum()-1 {
6066
start.X = lastcn - 1
@@ -91,46 +97,48 @@ func (b *Buffer) findUp(r *regexp.Regexp, start, end Loc) ([2]Loc, bool) {
9197
l = util.SliceStart(l, end.X)
9298
}
9399

94-
allMatches := r.FindAllIndex(l, -1)
100+
allMatches := r.FindAllSubmatchIndex(l, -1)
95101

96102
if allMatches != nil {
97103
match := allMatches[len(allMatches)-1]
98-
start := Loc{charpos + util.RunePos(l, match[0]), i}
99-
end := Loc{charpos + util.RunePos(l, match[1]), i}
100-
return [2]Loc{start, end}, true
104+
loc := make([]Loc, len(match))
105+
for j, x := range match {
106+
if x == -1 { // submatch doesn't occur in match
107+
loc[j] = Loc{-1, -1}
108+
} else {
109+
loc[j] = Loc{charpos + util.RunePos(l, x), i}
110+
}
111+
}
112+
return loc, true
101113
}
102114
}
103-
return [2]Loc{}, false
115+
return []Loc{}, false
104116
}
105117

106-
// FindNext finds the next occurrence of a given string in the buffer
107-
// It returns the start and end location of the match (if found) and
108-
// a boolean indicating if it was found
118+
// FindNextSubmatch finds the next occurrence of a given string in the
119+
// buffer. It returns the start and end location of the match and of
120+
// all submatches (if found) and a boolean indicating if it was found.
109121
// May also return an error if the search regex is invalid
110-
func (b *Buffer) FindNext(s string, start, end, from Loc, down bool, useRegex bool) ([2]Loc, bool, error) {
122+
func (b *Buffer) FindNextSubmatch(s string, start, end, from Loc, down bool) ([]Loc, bool, error) {
111123
if s == "" {
112-
return [2]Loc{}, false, nil
124+
return []Loc{}, false, nil
113125
}
114126

115127
var r *regexp.Regexp
116128
var err error
117129

118-
if !useRegex {
119-
s = regexp.QuoteMeta(s)
120-
}
121-
122130
if b.Settings["ignorecase"].(bool) {
123131
r, err = regexp.Compile("(?i)" + s)
124132
} else {
125133
r, err = regexp.Compile(s)
126134
}
127135

128136
if err != nil {
129-
return [2]Loc{}, false, err
137+
return []Loc{}, false, err
130138
}
131139

132140
var found bool
133-
var l [2]Loc
141+
var l []Loc
134142
if down {
135143
l, found = b.findDown(r, from, end)
136144
if !found {
@@ -145,6 +153,22 @@ func (b *Buffer) FindNext(s string, start, end, from Loc, down bool, useRegex bo
145153
return l, found, nil
146154
}
147155

156+
// FindNext finds the next occurrence of a given string in the buffer
157+
// It returns the start and end location of the match (if found) and
158+
// a boolean indicating if it was found
159+
// May also return an error if the search regex is invalid
160+
func (b *Buffer) FindNext(s string, start, end, from Loc, down bool, useRegex bool) ([2]Loc, bool, error) {
161+
if !useRegex {
162+
s = regexp.QuoteMeta(s)
163+
}
164+
l, found, err := b.FindNextSubmatch(s, start, end, from, down)
165+
if found {
166+
return [2]Loc{l[0], l[1]}, found, err
167+
} else {
168+
return [2]Loc{}, found, err
169+
}
170+
}
171+
148172
// ReplaceRegex replaces all occurrences of 'search' with 'replace' in the given area
149173
// and returns the number of replacements made and the number of runes
150174
// added or removed on the last line of the range

0 commit comments

Comments
 (0)