gilo/editor/search.go
Timothy J Warren fe1c54317e
Some checks failed
timw4mail/gilo/pipeline/head There was a failure building this commit
Fix CI build?
2021-04-12 12:52:20 -04:00

113 lines
2.2 KiB
Go

package editor
import (
"timshome.page/gilo/editor/highlight"
gilo2 "timshome.page/gilo/internal/gilo"
"timshome.page/gilo/key"
)
type search struct {
cursor *gilo2.Point
offset *gilo2.Point
hlLine int
hl []int
direction int
lastMatch int
}
func newSearch() *search {
return &search{
cursor: gilo2.DefaultPoint(),
offset: gilo2.DefaultPoint(),
hlLine: -1,
hl: []int{},
lastMatch: -1,
direction: 1,
}
}
func (e *editor) find() {
e.search.cursor.X = e.cursor.X
e.search.cursor.Y = e.cursor.Y
e.search.offset.X = e.offset.X
e.search.offset.Y = e.offset.Y
query := e.prompt("Search: %s (Use ESC/Arrows/Enter)", e.findCallback)
if query == "" {
e.cursor.X = e.search.cursor.X
e.cursor.Y = e.search.cursor.Y
e.offset.X = e.search.offset.X
e.offset.Y = e.search.offset.Y
return
}
}
func (e *editor) findCallback(query string, ch string) {
if e.search.hlLine != -1 && e.search.hl != nil {
staleRow := e.doc.GetRow(e.search.hlLine)
for i, val := range e.search.hl {
staleRow.Hl[i] = val
}
e.search.hl = nil
e.search.hlLine = -1
}
if ch == string(key.Enter) || ch == string(key.Esc) {
e.search.lastMatch = -1
e.search.direction = 1
return
} else if ch == keyRight || ch == keyDown {
e.search.direction = 1
} else if ch == keyLeft || ch == keyUp {
e.search.direction = -1
} else {
e.search.lastMatch = -1
e.search.direction = 1
}
if e.search.lastMatch == -1 {
e.search.direction = 1
}
if len(query) == 0 {
return
}
current := e.search.lastMatch
for i := 0; i < e.doc.RowCount(); i++ {
current += e.search.direction
if current == -1 {
current = e.doc.RowCount() - 1
} else if current == e.doc.RowCount() {
current = 0
}
row := e.doc.GetRow(current)
matchIndex := row.Search(query)
if matchIndex == -1 {
continue
}
e.search.lastMatch = current
e.cursor.Y = current
e.cursor.X = row.RenderXtoCursorX(matchIndex)
e.offset.Y = e.doc.RowCount()
// Update highlighting of search result
e.search.hlLine = current
e.search.hl = make([]int, row.RenderSize())
for i, val := range row.Hl {
e.search.hl[i] = val
}
for x := matchIndex; x < matchIndex+len(query); x++ {
row.Hl[x] = highlight.Match
}
break
}
}