diff --git a/buffer.go b/buffer.go index c470001..101dcfa 100644 --- a/buffer.go +++ b/buffer.go @@ -115,23 +115,13 @@ func (mb *MemoryBuffer) LineAt(n int) (Line, error) { return mb.lines[n], nil } -// Source implements pipline.Source, and is the buffer for the input -type Source struct { - pipeline.OutputChannel - MemoryBuffer - - in io.Reader - enableSep bool - ready chan struct{} - setupOnce sync.Once -} - // Creates a new Source. Does not start processing the input until you // call Setup() func NewSource(in io.Reader, enableSep bool) *Source { return &Source{ in: in, // Note that this may be closed, so do not rely on it enableSep: enableSep, + done: make(chan struct{}), ready: make(chan struct{}), setupOnce: sync.Once{}, OutputChannel: pipeline.OutputChannel(make(chan interface{})), @@ -212,6 +202,9 @@ func (s *Source) Setup(state *Peco) { // XXX Just in case scanner.Scan() did not return a single line... // Note: this will be a no-op if notify.Do has been called before notify.Do(notifycb) + // And also, close the done channel so we can tell the consumers + // we have finished reading everything + close(s.done) if pdebug.Enabled { pdebug.Printf("Read all %d lines from source", readCount) @@ -244,3 +237,9 @@ func (s *Source) Start(ctx context.Context) { func (s *Source) Ready() <-chan struct{} { return s.ready } + +// Done returns the "read all lines" channel. It will be closed as soon as +// the all input has been read +func (s *Source) Done() <-chan struct{} { + return s.done +} diff --git a/interface.go b/interface.go index bfac9b7..ad6e65e 100644 --- a/interface.go +++ b/interface.go @@ -409,6 +409,18 @@ type FilterSet struct { current int } +// Source implements pipline.Source, and is the buffer for the input +type Source struct { + pipeline.OutputChannel + MemoryBuffer + + in io.Reader + enableSep bool + done chan struct{} + ready chan struct{} + setupOnce sync.Once +} + type State interface { Keymap() *Keymap Query() Query diff --git a/peco.go b/peco.go index 6cbfa7b..70d1b04 100644 --- a/peco.go +++ b/peco.go @@ -232,6 +232,7 @@ func (p *Peco) Setup() (err error) { } p.source = src p.ResetCurrentLineBuffer() + return nil } @@ -286,6 +287,19 @@ func (p *Peco) Run(ctx context.Context) (err error) { } close(p.readyCh) + if p.Options.OptSelect1 { + go func() { + <-p.source.Done() + if b := p.CurrentLineBuffer(); b.Size() == 1 { + if l, err := b.LineAt(0); err == nil { + p.resultCh = make(chan Line) + p.Exit(nil) + p.resultCh <- l + close(p.resultCh) + } + } + }() + } <-ctx.Done() return p.Err()