+func searchDown(r *regexp.Regexp, v *View, start, end Loc) bool {
+ if start.Y >= v.Buf.NumLines {
+ start.Y = v.Buf.NumLines - 1
+ }
+ if start.Y < 0 {
+ start.Y = 0
+ }
+ for i := start.Y; i <= end.Y; i++ {
+ var l []byte
+ var charPos int
+ if i == start.Y {
+ runes := []rune(string(v.Buf.lines[i].data))
+ if start.X >= len(runes) {
+ start.X = len(runes) - 1
+ }
+ if start.X < 0 {
+ start.X = 0
+ }
+ l = []byte(string(runes[start.X:]))
+ charPos = start.X
+
+ if strings.Contains(r.String(), "^") && start.X != 0 {
+ continue
+ }
+ } else {
+ l = v.Buf.lines[i].data
+ }
+
+ match := r.FindIndex(l)
+
+ if match != nil {
+ v.Cursor.SetSelectionStart(Loc{charPos + runePos(match[0], string(l)), i})
+ v.Cursor.SetSelectionEnd(Loc{charPos + runePos(match[1], string(l)), i})
+ v.Cursor.OrigSelection[0] = v.Cursor.CurSelection[0]
+ v.Cursor.OrigSelection[1] = v.Cursor.CurSelection[1]
+ v.Cursor.Loc = v.Cursor.CurSelection[1]
+
+ return true
+ }
+ }
+ return false
+}
+
+func searchUp(r *regexp.Regexp, v *View, start, end Loc) bool {
+ if start.Y >= v.Buf.NumLines {
+ start.Y = v.Buf.NumLines - 1
+ }
+ if start.Y < 0 {
+ start.Y = 0
+ }
+ for i := start.Y; i >= end.Y; i-- {
+ var l []byte
+ if i == start.Y {
+ runes := []rune(string(v.Buf.lines[i].data))
+ if start.X >= len(runes) {
+ start.X = len(runes) - 1
+ }
+ if start.X < 0 {
+ start.X = 0
+ }
+ l = []byte(string(runes[:start.X]))
+
+ if strings.Contains(r.String(), "$") && start.X != Count(string(l)) {
+ continue
+ }
+ } else {
+ l = v.Buf.lines[i].data
+ }
+
+ match := r.FindIndex(l)
+
+ if match != nil {
+ v.Cursor.SetSelectionStart(Loc{runePos(match[0], string(l)), i})
+ v.Cursor.SetSelectionEnd(Loc{runePos(match[1], string(l)), i})
+ v.Cursor.OrigSelection[0] = v.Cursor.CurSelection[0]
+ v.Cursor.OrigSelection[1] = v.Cursor.CurSelection[1]
+ v.Cursor.Loc = v.Cursor.CurSelection[1]
+
+ return true
+ }
+ }
+ return false
+}
+