- internal/test/e2e/: FrameCapture, Harness, ElementAssertions, helpers - internal/editor/logic.go: Add done channel and Done() method for graceful shutdown - internal/editor/mock_setup.go: Mock filesystem for tests - internal/browser/: Browser layout and search logic - internal/io/: Worker pool for async tasks - Update architecture docs and spec
45 lines
1.2 KiB
Go
45 lines
1.2 KiB
Go
package browser
|
|
|
|
import "strings"
|
|
|
|
// HandleSearch filters entries by the given query string.
|
|
// It performs case-insensitive substring matching across all loaded pages.
|
|
// When query is empty, search results are cleared.
|
|
// When results are found, ScrollIndex is set to the first match.
|
|
func HandleSearch(s *BrowserState, query string) {
|
|
s.Query = query
|
|
|
|
// Empty query clears search results; leave ScrollIndex unchanged.
|
|
if query == "" {
|
|
s.SearchResults = nil
|
|
return
|
|
}
|
|
|
|
var results []int
|
|
queryLower := strings.ToLower(query)
|
|
|
|
// Iterate over all loaded pages in order (map iteration is non-deterministic).
|
|
totalPages := (s.TotalEntries + PageSize - 1) / PageSize
|
|
for pageIdx := 0; pageIdx < totalPages; pageIdx++ {
|
|
page, ok := s.Pages[pageIdx]
|
|
if !ok || !page.Loaded {
|
|
continue
|
|
}
|
|
// Compute the global start index for this page.
|
|
startIdx := pageIdx * PageSize
|
|
for i, entry := range page.Entries {
|
|
globalIdx := startIdx + i
|
|
if strings.Contains(strings.ToLower(entry.Name), queryLower) {
|
|
results = append(results, globalIdx)
|
|
}
|
|
}
|
|
}
|
|
|
|
s.SearchResults = results
|
|
|
|
// Jump to first result if any matches found.
|
|
if len(results) > 0 {
|
|
s.ScrollIndex = results[0]
|
|
}
|
|
}
|