Some work
This commit is contained in:
177
wdgt_cli.go
177
wdgt_cli.go
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user