Some work

This commit is contained in:
2025-10-09 12:24:00 -05:00
parent 28a9824542
commit 79a212e601
3 changed files with 247 additions and 48 deletions

View File

@@ -23,7 +23,6 @@ package widgets
import (
"fmt"
"sort"
"strings"
wh "git.bullercodeworks.com/brian/tcell-widgets/helpers"
@@ -53,13 +52,12 @@ type Cli struct {
history []string
historyPosition int
commands []string
commandMap map[string]cliCommand
commandGuessMap map[string]func(args ...string) string
commands []*CliCommand
keyMap KeyMap
}
// TODO: Fix Command/SubCommand finding
var _ Widget = (*Cli)(nil)
func NewCli(id string, s tcell.Style) *Cli {
@@ -146,20 +144,22 @@ func (w *Cli) Draw(screen tcell.Screen) {
}
x, y := w.x+1, w.y+1+w.h-3
for i := 0; i < w.h-2; i++ {
if len(w.log) > (i + w.logPosition) {
idx := len(w.log) - (i + w.logPosition) - 1
if idx < 0 {
if !w.minimized {
for i := 0; i < w.h-2; i++ {
if len(w.log) > (i + w.logPosition) {
idx := len(w.log) - (i + w.logPosition) - 1
if idx < 0 {
y--
wh.DrawText(x, y, wh.PadR("", w.w-2), dStyle, screen)
continue
}
line := w.log[idx]
if len(line) > w.w-2 {
line = line[:w.w-2]
}
wh.DrawText(x, y, wh.PadR(line, w.w-2), dStyle, screen)
y--
wh.DrawText(x, y, wh.PadR("", w.w-2), dStyle, screen)
continue
}
line := w.log[idx]
if len(line) > w.w-2 {
line = line[:w.w-2]
}
wh.DrawText(x, y, wh.PadR(line, w.w-2), dStyle, screen)
y--
}
}
y = w.y + w.h - 1
@@ -258,26 +258,29 @@ func (w *Cli) initKeyMap() {
tcell.KeyTab: func(ev *tcell.EventKey) bool {
// Auto-complete
guess := w.findBestGuess()
if guess != "" {
w.value = guess
if guess != nil {
wrk := strings.Split(w.value, " ")
wrk = append(wrk[:len(wrk)-1], guess.cmd)
w.value = strings.Join(wrk, " ")
w.cursor = len(w.value)
return true
}
return false
},
tcell.KeyEnter: func(ev *tcell.EventKey) 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()
}
args := strings.Split(w.value, " ")
w.historyPosition = -1
w.value = ""
w.cursor = 0
v := w.value
if len(args) > 0 {
v = args[0]
}
if wrk := w.GetCommandFor(v); wrk != nil {
w.history = append(w.history, w.value)
return wrk.Run(args...)
}
w.history = append(w.history, fmt.Sprintf("%s: command not found", w.value))
return true
},
tcell.KeyPgUp: func(ev *tcell.EventKey) bool {
@@ -309,33 +312,56 @@ func (w *Cli) SetValue(val string) {
w.cursor = len(val)
}
func (w *Cli) AddComamnd(cmd string, do cliCommand) {
w.commands = append(w.commands, cmd)
sort.Strings(w.commands)
w.commandMap[cmd] = do
func (w *Cli) GetCommandFor(txt string) *CliCommand {
for i := range w.commands {
if w.commands[i].cmd == txt {
return w.commands[i]
}
}
return nil
}
func (w *Cli) HasCommand(cmd *CliCommand) bool {
for i := range w.commands {
if w.commands[i].cmd == cmd.cmd {
return true
}
}
return false
}
func (w *Cli) AddCommand(cmd *CliCommand) {
if !w.HasCommand(cmd) {
w.commands = append(w.commands, cmd)
}
}
func (w *Cli) RemoveCommand(cmd string) {
var idx int
for idx = range w.commands {
if w.commands[idx] == cmd {
if w.commands[idx].cmd == cmd {
break
}
}
w.commands = append(w.commands[:idx], w.commands[idx+1:]...)
delete(w.commandMap, cmd)
}
func (w *Cli) findBestGuess() string {
func (w *Cli) findBestGuess() *CliCommand {
if w.value == "" {
return ""
return nil
}
args := strings.Split(w.value, " ")
if len(args) > 1 {
if wrk := w.GetCommandFor(args[0]); wrk != nil {
return wrk.findBestGuess(args[1:]...)
}
}
for _, v := range w.commands {
if strings.HasPrefix(v, w.value) {
if strings.HasPrefix(v.cmd, w.value) {
return v
}
}
return ""
return nil
}
func (w *Cli) Log(txt string, args ...any) {
@@ -352,10 +378,71 @@ func (w *Cli) Clear() {
func (w *Cli) SetMinimized(m bool) { w.minimized = m }
func (w *Cli) IsMinimized() bool { return w.minimized }
type cliCommand func(args ...string) bool
// TODO
func (c *cliCommand) findBestGuess(args ...string) string {
_ = args
return ""
type CliCommand struct {
cmd string
do func(args ...string) bool
subCommands []*CliCommand
}
func NewCliCommand(nm string, do func(args ...string) bool, subs ...*CliCommand) *CliCommand {
c := CliCommand{
cmd: nm,
do: do,
}
for i := range subs {
c.AddCommand(subs[i])
}
return &c
}
func (c *CliCommand) Run(args ...string) bool {
if len(c.subCommands) > 0 {
wrk := c.findBestGuess(args...)
if wrk != nil {
return wrk.Run(args...)
}
}
if c.do != nil {
return c.do(args...)
}
return false
}
func (c *CliCommand) AddCommand(cc *CliCommand) error {
if c.HasCommand(cc.cmd) {
return fmt.Errorf("command already exists: %s", cc.cmd)
}
c.subCommands = append(c.subCommands, cc)
return nil
}
func (c *CliCommand) HasCommand(cmd string) bool {
for i := range c.subCommands {
if c.subCommands[i].cmd == cmd {
return true
}
}
return false
}
func (c *CliCommand) GetCommandFor(cmd string) *CliCommand {
for i := range c.subCommands {
if c.subCommands[i].cmd == cmd {
return c.subCommands[i]
}
}
return nil
}
func (c *CliCommand) findBestGuess(args ...string) *CliCommand {
if len(args) == 0 {
return nil
}
// Find the best guess
for _, v := range c.subCommands {
if strings.HasPrefix(args[0], v.cmd) {
return v
}
}
return nil
}