Split into category packages; module github.com/ZacharyZhang-NY/MujicaUI
This commit is contained in:
1822 files changed
+24568
-21314
No files matched your search
@@ -0,0 +1,80 @@
|
||||
package code
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/egoist/mygo/ui"
|
||||
|
||||
"github.com/ZacharyZhang-NY/MujicaUI/core"
|
||||
"github.com/ZacharyZhang-NY/MujicaUI/input"
|
||||
)
|
||||
|
||||
// TerminalSearchState is a search through a terminal's scrollback and screen.
|
||||
type TerminalSearchState struct {
|
||||
Query string
|
||||
// Current is the chosen match, from 0.
|
||||
Current int
|
||||
query string
|
||||
version int
|
||||
ran bool
|
||||
}
|
||||
|
||||
// TerminalSearchOptions configure a TerminalSearch.
|
||||
type TerminalSearchOptions struct {
|
||||
Disabled bool
|
||||
}
|
||||
|
||||
// TerminalSearch finds Query in term and shows the current match.
|
||||
func TerminalSearch(c *ui.Context, term *TerminalState, s *TerminalSearchState, opts TerminalSearchOptions) core.ChoiceResult {
|
||||
if term == nil || s == nil {
|
||||
panic("mujica: TerminalSearch needs a terminal and a state")
|
||||
}
|
||||
term.init()
|
||||
fresh := terminalSearchRun(term, s)
|
||||
r := input.SearchInput(c, &s.Query, input.SearchInputOptions{Find: true, Matches: len(term.matches), Current: &s.Current,
|
||||
Disabled: opts.Disabled, Label: core.Msg(c, "terminal_search.label")})
|
||||
var res core.ChoiceResult
|
||||
res.Element = r.Element
|
||||
if r.Changed() {
|
||||
s.Current = 0
|
||||
terminalSearchRun(term, s)
|
||||
res = core.NewChoiceResult(res.Element, true)
|
||||
}
|
||||
if r.Moved() {
|
||||
res = core.NewChoiceResult(res.Element, true)
|
||||
}
|
||||
if res.Changed() || fresh {
|
||||
term.current = s.Current
|
||||
if s.Current < len(term.matches) {
|
||||
term.reveal(term.matches[s.Current].pos.Line)
|
||||
}
|
||||
slog.Debug("mujica: terminal_search move", "matches", len(term.matches), "current", s.Current)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// terminalSearchRun refinds matches; it reports a new query.
|
||||
func terminalSearchRun(term *TerminalState, s *TerminalSearchState) bool {
|
||||
if s.ran && s.query == s.Query && s.version == term.version {
|
||||
return false
|
||||
}
|
||||
fresh := !s.ran || s.query != s.Query
|
||||
s.ran, s.query, s.version = true, s.Query, term.version
|
||||
term.matches = term.matches[:0]
|
||||
q := []rune(strings.ToLower(s.Query))
|
||||
if len(q) > 0 {
|
||||
for i := range term.Lines() {
|
||||
line := []rune(strings.ToLower(term.LineText(i)))
|
||||
for col := 0; col+len(q) <= len(line); col++ {
|
||||
if string(line[col:col+len(q)]) == string(q) {
|
||||
term.matches = append(term.matches, terminalMatch{TerminalPos{i, col}, len(q)})
|
||||
col += len(q) - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
s.Current = max(0, min(s.Current, len(term.matches)-1))
|
||||
term.current = s.Current
|
||||
return fresh
|
||||
}
|
||||
Reference in new issue
Block a user