Separate signalHandler and InputProcessor from Prompt

This commit is contained in:
c-bata 2018-06-24 04:50:59 +09:00
parent 42db104fe7
commit 9df5194c95
4 changed files with 44 additions and 30 deletions

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)
}
}

@ -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()