Add interrupts to simple Menu

This commit is contained in:
qowevisa 2024-10-22 21:10:37 +03:00
parent 37b00556e7
commit ddaf609d0c

View File

@ -3,6 +3,7 @@ package simple
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"log"
"os" "os"
"strings" "strings"
) )
@ -95,6 +96,11 @@ type Menu struct {
// //
counterForIDs uint counterForIDs uint
cmdTree *commandTree cmdTree *commandTree
//
interrupt chan func(m *Menu)
resumeSignal chan struct{}
inputChan chan string
errorChan chan error
} }
func CreateMenu(options ...SimpleMenuOption) *Menu { func CreateMenu(options ...SimpleMenuOption) *Menu {
@ -112,6 +118,10 @@ func CreateMenu(options ...SimpleMenuOption) *Menu {
lineCounter: 0, lineCounter: 0,
counterForIDs: 1, counterForIDs: 1,
cmdTree: createCommandTree(), cmdTree: createCommandTree(),
interrupt: make(chan func(m *Menu)),
resumeSignal: make(chan struct{}),
inputChan: make(chan string),
errorChan: make(chan error),
} }
} }
@ -236,21 +246,62 @@ func (m *Menu) printMenu() {
} }
} }
func (m *Menu) readInput() {
stdinReader := bufio.NewReader(os.Stdin)
for {
msg, err := stdinReader.ReadString('\n')
if err != nil {
// fmt.Printf("Error: ReadString: %v\n", err)
m.errorChan <- err
return
}
m.lineCounter++
m.inputChan <- msg
}
}
func (m *Menu) GetInput(prompt string) string {
nlCount := strings.Count(prompt, "\n")
m.lineCounter += uint(nlCount)
stdinReader := bufio.NewReader(os.Stdin)
rawMsg, err := stdinReader.ReadString('\n')
if err != nil {
// fmt.Printf("Error: ReadString: %v\n", err)
m.errorChan <- err
return ""
}
m.lineCounter++
msg := strings.TrimRight(rawMsg, "\n")
return msg
}
func (m *Menu) iteration() { func (m *Menu) iteration() {
m.Log.Flush() m.Log.Flush()
m.printMenu() m.printMenu()
stdinReader := bufio.NewReader(os.Stdin)
msg, err := stdinReader.ReadString('\n') // for {
if err != nil { select {
fmt.Printf("Error: ReadString: %v\n", err) case msg := <-m.inputChan:
return msg = strings.TrimRight(msg, "\n")
m.handleInput(msg)
case err := <-m.errorChan:
m.Log.Logf("err: %v", err)
case f := <-m.interrupt:
if m.usingEscapeCodes {
m.clearLines()
}
log.Printf("Interrupt")
f(m)
} }
m.lineCounter++ // }
msg = strings.TrimRight(msg, "\n") }
m.handleInput(msg)
func (m *Menu) SendInterrupt(f func(m *Menu)) {
m.interrupt <- f
} }
func (m *Menu) Start() { func (m *Menu) Start() {
go m.readInput()
for { for {
m.iteration() m.iteration()
} }