Separate signalHandler and InputProcessor from Prompt
This commit is contained in:
parent
42db104fe7
commit
9df5194c95
27
input_processor.go
Normal file
27
input_processor.go
Normal file
@ -0,0 +1,27 @@
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
type InputProcessor struct {
|
||||
in ConsoleParser
|
||||
}
|
||||
|
||||
func (ip *InputProcessor) Run(ctx context.Context, bufCh chan []byte) {
|
||||
log.Printf("[INFO] Start running input processor")
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
log.Print("[INFO] Stop input processor")
|
||||
return
|
||||
default:
|
||||
if b, err := ip.in.Read(); err == nil && !(len(b) == 1 && b[0] == 0) {
|
||||
bufCh <- b
|
||||
}
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
}
|
37
prompt.go
37
prompt.go
@ -22,6 +22,7 @@ type Completer func(Document) []Suggest
|
||||
// Prompt is core struct of go-prompt.
|
||||
type Prompt struct {
|
||||
in ConsoleParser
|
||||
inputProcessor *InputProcessor
|
||||
buf *Buffer
|
||||
renderer *Render
|
||||
executor Executor
|
||||
@ -57,11 +58,11 @@ func (p *Prompt) Run() {
|
||||
p.renderer.Render(p.buf, p.completion)
|
||||
|
||||
bufchan := make(chan []byte, 128)
|
||||
go p.readBuffer(p.ctx, bufchan)
|
||||
go p.inputProcessor.Run(p.ctx, bufchan)
|
||||
|
||||
exitCh := make(chan int)
|
||||
winchan := make(chan *WinSize)
|
||||
go p.handleSignals(p.ctx, p.cancel, winchan)
|
||||
winchan := make(chan struct{})
|
||||
go handleSignals(p.ctx, p.cancel, winchan)
|
||||
|
||||
for {
|
||||
select {
|
||||
@ -87,14 +88,15 @@ func (p *Prompt) Run() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
p.ctx = ctx
|
||||
p.cancel = cancel
|
||||
go p.readBuffer(p.ctx, bufchan)
|
||||
go p.handleSignals(p.ctx, p.cancel, winchan)
|
||||
go p.inputProcessor.Run(p.ctx, bufchan)
|
||||
go handleSignals(p.ctx, p.cancel, winchan)
|
||||
} else {
|
||||
p.completion.Update(*p.buf.Document())
|
||||
p.renderer.Render(p.buf, p.completion)
|
||||
}
|
||||
case w := <-winchan:
|
||||
p.renderer.UpdateWinSize(w)
|
||||
case <-winchan:
|
||||
ws := p.in.GetWinSize()
|
||||
p.renderer.UpdateWinSize(ws)
|
||||
p.renderer.Render(p.buf, p.completion)
|
||||
case code := <-exitCh:
|
||||
p.renderer.BreakLine(p.buf)
|
||||
@ -236,7 +238,7 @@ func (p *Prompt) Input() string {
|
||||
|
||||
p.renderer.Render(p.buf, p.completion)
|
||||
bufchan := make(chan []byte, 128)
|
||||
go p.readBuffer(p.ctx, bufchan)
|
||||
go p.inputProcessor.Run(p.ctx, bufchan)
|
||||
|
||||
for {
|
||||
select {
|
||||
@ -257,26 +259,13 @@ func (p *Prompt) Input() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prompt) readBuffer(ctx context.Context, bufCh chan []byte) {
|
||||
log.Printf("[INFO] readBuffer start")
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
log.Print("[INFO] stop readBuffer")
|
||||
return
|
||||
default:
|
||||
if b, err := p.in.Read(); err == nil && !(len(b) == 1 && b[0] == 0) {
|
||||
bufCh <- b
|
||||
}
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prompt) setUp() {
|
||||
p.in.Setup()
|
||||
p.renderer.Setup()
|
||||
p.renderer.UpdateWinSize(p.in.GetWinSize())
|
||||
p.inputProcessor = &InputProcessor{
|
||||
in: p.in,
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
p.ctx = ctx
|
||||
|
@ -10,8 +10,7 @@ import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func (p *Prompt) handleSignals(ctx context.Context, cancel context.CancelFunc, winSizeCh chan *WinSize) {
|
||||
in := p.in
|
||||
func handleSignals(ctx context.Context, cancel context.CancelFunc, sigwinchan chan struct{}) {
|
||||
sigchan := make(chan os.Signal, 1)
|
||||
signal.Notify(
|
||||
sigchan,
|
||||
@ -42,7 +41,7 @@ func (p *Prompt) handleSignals(ctx context.Context, cancel context.CancelFunc, w
|
||||
|
||||
case syscall.SIGWINCH:
|
||||
log.Println("[SIGNAL] Catch SIGWINCH")
|
||||
winSizeCh <- in.GetWinSize()
|
||||
sigwinchan <- struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,12 @@ package prompt
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func (p *Prompt) handleSignals(tx context.Context, cancel context.CancelFunc, winSizeCh chan *WinSize) {
|
||||
func handleSignals(ctx context.Context, cancel context.CancelFunc, winsizechan chan struct{}) {
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(
|
||||
sigCh,
|
||||
@ -29,7 +28,7 @@ func (p *Prompt) handleSignals(tx context.Context, cancel context.CancelFunc, wi
|
||||
cancel()
|
||||
|
||||
case syscall.SIGTERM: // kill -SIGTERM XXXX
|
||||
log.Println("[SIGNAL] Catch SIGTERM")
|
||||
cancel()
|
||||
|
||||
case syscall.SIGQUIT: // kill -SIGQUIT XXXX
|
||||
cancel()
|
||||
|
Loading…
Reference in New Issue
Block a user