This commit is contained in:
2025-07-09 16:14:11 -05:00
parent 4763d1be26
commit 2e2aa50b82
13 changed files with 763 additions and 124 deletions

153
cli.go
View File

@@ -53,6 +53,8 @@ type Cli struct {
commands []string
commandMap map[string]cliCommand
commandGuessMap map[string]func(args ...string) string
keyMap KeyMap
}
func NewCli(id string, s tcell.Style) *Cli {
@@ -64,6 +66,7 @@ func NewCli(id string, s tcell.Style) *Cli {
func (w *Cli) Init(id string, s tcell.Style) {
w.id, w.style = id, s
w.visible = true
w.initKeyMap()
}
func (w *Cli) Id() string { return w.id }
@@ -84,80 +87,10 @@ func (w *Cli) HandleKey(ev *tcell.EventKey) bool {
w.value = w.value[:w.cursor] + w.value[w.cursor+1:]
}
}
if done := h.HandleKeys(*ev, map[tcell.Key]func() bool{
tcell.KeyEsc: func() bool {
w.SetActive(false)
return true
},
tcell.KeyUp: func() bool {
if w.historyPosition < len(w.history)-1 {
w.historyPosition++
w.value = w.history[w.historyPosition]
w.cursor = len(w.value)
return true
}
return false
},
tcell.KeyDown: func() bool {
if w.historyPosition > -1 {
w.historyPosition--
if w.historyPosition == -1 {
w.value = ""
} else {
w.value = w.history[w.historyPosition]
}
w.cursor = len(w.value)
return true
}
return false
},
tcell.KeyLeft: func() bool {
if w.cursor > 0 {
w.cursor--
return true
}
return false
},
tcell.KeyRight: func() bool {
if w.cursor < len(w.value) {
w.cursor++
return true
}
return false
},
tcell.KeyCtrlU: func() bool {
w.value = w.value[w.cursor:]
w.cursor = 0
return true
},
tcell.KeyTab: func() bool {
// Auto-complete
guess := w.findBestGuess()
if guess != "" {
w.value = guess
w.cursor = len(w.value)
return true
}
return false
},
tcell.KeyEnter: func() bool {
cmds := strings.Split(w.value, " ")
if v, ok := w.commandMap[cmds[0]]; ok {
w.history = append(w.history, w.value)
w.historyPosition = -1
w.value = ""
w.cursor = 0
if len(cmds) > 1 {
return v(cmds[1:]...)
} else {
return v()
}
}
return true
},
}); done {
return done
if ok := w.keyMap.Handle(ev); ok {
return true
}
var ch string
if h.KeyIsDisplayable(*ev) {
ch = string(ev.Rune())
@@ -237,6 +170,80 @@ func (w *Cli) SetSize(c Coord) { w.w, w.h = c.X, c.Y }
func (w *Cli) WantW() int { return w.w }
func (w *Cli) WantH() int { return w.h }
func (w *Cli) initKeyMap() {
w.keyMap = NewKeyMap(map[tcell.Key]func() bool{
tcell.KeyEsc: func() bool {
w.SetActive(false)
return true
},
tcell.KeyUp: func() bool {
if w.historyPosition < len(w.history)-1 {
w.historyPosition++
w.value = w.history[w.historyPosition]
w.cursor = len(w.value)
return true
}
return false
},
tcell.KeyDown: func() bool {
if w.historyPosition > -1 {
w.historyPosition--
if w.historyPosition == -1 {
w.value = ""
} else {
w.value = w.history[w.historyPosition]
}
w.cursor = len(w.value)
return true
}
return false
},
tcell.KeyLeft: func() bool {
if w.cursor > 0 {
w.cursor--
return true
}
return false
},
tcell.KeyRight: func() bool {
if w.cursor < len(w.value) {
w.cursor++
return true
}
return false
},
tcell.KeyCtrlU: func() bool {
w.value = w.value[w.cursor:]
w.cursor = 0
return true
},
tcell.KeyTab: func() bool {
// Auto-complete
guess := w.findBestGuess()
if guess != "" {
w.value = guess
w.cursor = len(w.value)
return true
}
return false
},
tcell.KeyEnter: func() bool {
cmds := strings.Split(w.value, " ")
if v, ok := w.commandMap[cmds[0]]; ok {
w.history = append(w.history, w.value)
w.historyPosition = -1
w.value = ""
w.cursor = 0
if len(cmds) > 1 {
return v(cmds[1:]...)
} else {
return v()
}
}
return true
},
})
}
func (w *Cli) SetTitle(ttl string) { w.title = ttl }
func (w *Cli) Title() string { return w.title }
func (w *Cli) SetValue(val string) {