mirror of
https://github.com/peco/peco.git
synced 2026-09-10 07:16:29 -04:00
Tweaks to reader
This commit is contained in:
parent
105e067172
commit
580fc48264
2
ctx.go
2
ctx.go
|
|
@ -276,7 +276,7 @@ func (c *Ctx) DrawPrompt() {
|
|||
}
|
||||
|
||||
func (c *Ctx) NewBufferReader(r io.ReadCloser) *BufferReader {
|
||||
return &BufferReader{c, r, make(chan struct{})}
|
||||
return &BufferReader{c, r, make(chan struct{}, 1)}
|
||||
}
|
||||
|
||||
func (c *Ctx) NewView() *View {
|
||||
|
|
|
|||
19
debug_on.go
19
debug_on.go
|
|
@ -3,7 +3,6 @@
|
|||
package peco
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
|
|
@ -12,12 +11,19 @@ import (
|
|||
)
|
||||
|
||||
const debug = true
|
||||
|
||||
var tracer *log.Logger
|
||||
var mutexTracer *log.Logger
|
||||
|
||||
func init() {
|
||||
if v, err := strconv.ParseBool(os.Getenv("PECO_TRACE")); err == nil && v {
|
||||
tracer = log.New(os.Stderr, "peco: ", log.LstdFlags)
|
||||
tracer.Printf("==== INITIALIZED tracer ====")
|
||||
}
|
||||
if v, err := strconv.ParseBool(os.Getenv("PECO_LOCK_TRACE")); err == nil && v {
|
||||
mutexTracer = log.New(os.Stderr, "mutex: ", log.LstdFlags)
|
||||
mutexTracer.Printf("==== INITIALIZED mutext tracer ====")
|
||||
}
|
||||
}
|
||||
|
||||
func trace(f string, args ...interface{}) {
|
||||
|
|
@ -27,6 +33,13 @@ func trace(f string, args ...interface{}) {
|
|||
tracer.Printf(f, args...)
|
||||
}
|
||||
|
||||
func mutexTrace(f string, args ...interface{}) {
|
||||
if mutexTracer == nil {
|
||||
return
|
||||
}
|
||||
mutexTracer.Printf(f, args...)
|
||||
}
|
||||
|
||||
func newMutex() sync.Locker {
|
||||
return &loggingMutex{&sync.Mutex{}}
|
||||
}
|
||||
|
|
@ -38,13 +51,13 @@ type loggingMutex struct {
|
|||
func (m *loggingMutex) Lock() {
|
||||
buf := make([]byte, 8092)
|
||||
l := runtime.Stack(buf, false)
|
||||
fmt.Printf("LOCK %s\n", buf[:l])
|
||||
mutexTrace("LOCK %s\n", buf[:l])
|
||||
m.Mutex.Lock()
|
||||
}
|
||||
|
||||
func (m *loggingMutex) Unlock() {
|
||||
buf := make([]byte, 8092)
|
||||
l := runtime.Stack(buf, false)
|
||||
fmt.Printf("UNLOCK %s\n", buf[:l])
|
||||
mutexTrace("UNLOCK %s\n", buf[:l])
|
||||
m.Mutex.Unlock()
|
||||
}
|
||||
|
|
|
|||
47
reader.go
47
reader.go
|
|
@ -8,6 +8,8 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// BufferReader reads from either stdin or a file. In case of stdin,
|
||||
// it also handles possible infinite source.
|
||||
type BufferReader struct {
|
||||
*Ctx
|
||||
input io.ReadCloser
|
||||
|
|
@ -25,11 +27,13 @@ func (b *BufferReader) Loop() {
|
|||
defer b.ReleaseWaitGroup()
|
||||
defer func() { recover() }() // ignore errors
|
||||
defer func() { close(b.inputReadyCh) }() // Make sure to close notifier
|
||||
defer b.input.Close()
|
||||
|
||||
ch := make(chan string, 10)
|
||||
|
||||
// scanner.Scan() blocks until the next read or error. But we want to
|
||||
// exit immediately, so we move it out to its own goroutine
|
||||
// scanner.Scan() blocks until the next read or error. But we want our
|
||||
// main loop to be able to exit without blocking, so we move this out
|
||||
// to its own goroutine
|
||||
go func() {
|
||||
defer func() { recover() }()
|
||||
defer func() { close(ch) }()
|
||||
|
|
@ -43,8 +47,27 @@ func (b *BufferReader) Loop() {
|
|||
once := &sync.Once{}
|
||||
var refresh *time.Timer
|
||||
|
||||
loop := true
|
||||
for loop {
|
||||
doDelayedDraw := func() {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
trace("doDelayedDraw")
|
||||
|
||||
if refresh != nil {
|
||||
return
|
||||
}
|
||||
|
||||
refresh = time.AfterFunc(100*time.Millisecond, func() {
|
||||
if !b.ExecQuery() {
|
||||
b.SendDraw()
|
||||
}
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
refresh = nil
|
||||
})
|
||||
}
|
||||
|
||||
for loop := true; loop; {
|
||||
select {
|
||||
case <-b.LoopCh():
|
||||
loop = false
|
||||
|
|
@ -56,6 +79,7 @@ func (b *BufferReader) Loop() {
|
|||
|
||||
if line != "" {
|
||||
// Notify once that we have received something from the file/stdin
|
||||
// This is the cue to start initializing the terminal
|
||||
once.Do(func() { b.inputReadyCh <- struct{}{} })
|
||||
|
||||
// Make sure we lock access to b.lines
|
||||
|
|
@ -64,23 +88,10 @@ func (b *BufferReader) Loop() {
|
|||
m.Unlock()
|
||||
}
|
||||
|
||||
m.Lock()
|
||||
if refresh == nil {
|
||||
refresh = time.AfterFunc(100*time.Millisecond, func() {
|
||||
if !b.ExecQuery() {
|
||||
b.SendDraw()
|
||||
}
|
||||
m.Lock()
|
||||
refresh = nil
|
||||
m.Unlock()
|
||||
})
|
||||
}
|
||||
m.Unlock()
|
||||
doDelayedDraw()
|
||||
}
|
||||
}
|
||||
|
||||
b.input.Close()
|
||||
|
||||
// Out of the reader loop. If at this point we have no buffer,
|
||||
// that means we have no buffer, so we should quit.
|
||||
if b.GetRawLineBufferSize() == 0 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue