package editor import ( "timshome.page/gilo/editor/highlight" "timshome.page/gilo/internal/gilo" "timshome.page/gilo/key" ) type search struct { cursor *gilo.Point offset *gilo.Point savedhlLine int savedhl []int direction int lastMatch int } func newSearch() *search { return &search{ cursor: gilo.DefaultPoint(), offset: gilo.DefaultPoint(), savedhlLine: -1, savedhl: []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 we highlighted a previous match, restore the original highlighting if e.search.savedhlLine != -1 && e.search.savedhl != nil { staleRow := e.doc.GetRow(e.search.savedhlLine) for i, val := range e.search.savedhl { staleRow.Hl[i] = val } e.search.savedhl = nil e.search.savedhlLine = -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() // Save the current highlighting of where the search result is e.search.savedhlLine = current e.search.savedhl = make([]int, row.RenderSize()) for i, val := range row.Hl { e.search.savedhl[i] = val } // Update highlighting of search result for x := matchIndex; x < matchIndex+len(query); x++ { row.Hl[x] = highlight.Match } break } }