Tweak timing for when to initialize the screen and other components

We should wait to initialize the screen until we have something
coming in from the source: otherwise multiple peograms chained via
pipes would compete for the same terminal resource, and things may
go southward.

But then there are components that rely on the screen being intialized,
so we let them wait as well.
This commit is contained in:
Daisuke Maki 2017-03-03 23:23:07 +09:00
parent 766fdd73c0
commit ab72a5521f
2 changed files with 24 additions and 20 deletions

39
peco.go
View file

@ -301,11 +301,6 @@ func (p *Peco) Run(ctx context.Context) (err error) {
if err := p.Setup(); err != nil {
return errors.Wrap(err, "failed to setup peco")
}
// screen.Init must be called within Run() because we
// want to make sure to call screen.Close() after getting
// out of Run()
p.screen.Init()
defer p.screen.Close()
var _cancelOnce sync.Once
var _cancel func()
@ -325,20 +320,11 @@ func (p *Peco) Run(ctx context.Context) (err error) {
// remember this cancel func so p.Exit works (XXX requires locking?)
p.cancelFunc = cancel
loopers := []interface {
Loop(ctx context.Context, cancel func()) error
}{
NewInput(p, p.Keymap(), p.screen.PollEvent(ctx)),
NewView(p),
NewFilter(p),
sig.New(sig.SigReceivedHandlerFunc(func(sig os.Signal) {
p.Exit(errors.New("received signal: " + sig.String()))
})),
}
sigH := sig.New(sig.SigReceivedHandlerFunc(func(sig os.Signal) {
p.Exit(errors.New("received signal: " + sig.String()))
}))
for _, l := range loopers {
go l.Loop(ctx, cancel)
}
go sigH.Loop(ctx, cancel)
// SetupSource is done AFTER other components are ready, otherwise
// we can't draw onto the screen while we are reading a really big
@ -350,6 +336,18 @@ func (p *Peco) Run(ctx context.Context) (err error) {
}
p.source = src
go func() {
<-p.source.Ready()
// screen.Init must be called within Run() because we
// want to make sure to call screen.Close() after getting
// out of Run()
p.screen.Init()
go NewInput(p, p.Keymap(), p.screen.PollEvent(ctx)).Loop(ctx, cancel)
go NewView(p).Loop(ctx, cancel)
go NewFilter(p).Loop(ctx, cancel)
}()
defer p.screen.Close()
if p.Query().Len() <= 0 {
// Re-set the source only if there are no queries
p.ResetCurrentLineBuffer()
@ -391,7 +389,10 @@ func (p *Peco) Run(ctx context.Context) (err error) {
}
if p.Query().Len() > 0 {
p.ExecQuery()
go func() {
<-p.source.Ready()
p.ExecQuery()
}()
}
// Alright, done everything we need to do automatically. We'll let

View file

@ -26,6 +26,10 @@ func NewTermbox() *Termbox {
}
func (t *Termbox) Close() error {
if pdebug.Enabled {
pdebug.Printf("Termbox: Close")
}
termbox.Interrupt()
termbox.Close()
return nil
}
@ -69,7 +73,6 @@ func (t *Termbox) PollEvent(ctx context.Context) chan termbox.Event {
if pdebug.Enabled {
pdebug.Printf("poll event suspended!")
}
termbox.Interrupt()
t.Close()
}
}