Use pdebug instead of trace

This commit is contained in:
Daisuke Maki 2016-06-17 10:34:14 +09:00
parent 39eb717c6e
commit c12cd97d29
14 changed files with 220 additions and 224 deletions

View file

@ -1,24 +1,20 @@
package peco
import (
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"unicode"
"golang.org/x/net/context"
"github.com/google/btree"
"github.com/lestrrat/go-pdebug"
"github.com/nsf/termbox-go"
"github.com/peco/peco/internal/keyseq"
"github.com/pkg/errors"
"golang.org/x/net/context"
)
// ErrUserCanceled is used to signal that the user deliberately
// canceled using peco
var ErrUserCanceled = errors.New("canceled")
// This is the global map of canonical action name to actions
var nameToActions map[string]Action
@ -168,7 +164,6 @@ func doAcceptChar(ctx context.Context, state *Peco, e termbox.Event) {
q.InsertAt(ch, c.Pos())
c.Move(1)
trace("query = '%s'", q.String())
h := state.Hub()
h.SendDrawPrompt() // Update prompt before running query
@ -177,8 +172,10 @@ func doAcceptChar(ctx context.Context, state *Peco, e termbox.Event) {
}
func doRotateFilter(ctx context.Context, state *Peco, e termbox.Event) {
trace("doRotateFitler: START")
defer trace("doRotateFitler: END")
if pdebug.Enabled {
g := pdebug.Marker("doRotateFilter")
defer g.End()
}
filters := state.Filters()
filters.Rotate()
@ -190,8 +187,10 @@ func doRotateFilter(ctx context.Context, state *Peco, e termbox.Event) {
}
func doBackToInitialFilter(ctx context.Context, state *Peco, e termbox.Event) {
trace("doBackToInitialFilter: START")
defer trace("doBackToInitialFilter: END")
if pdebug.Enabled {
g := pdebug.Marker("doBackToInitialFilter")
defer g.End()
}
filters := state.Filters()
filters.Reset()
@ -203,6 +202,11 @@ func doBackToInitialFilter(ctx context.Context, state *Peco, e termbox.Event) {
}
func doToggleSelection(ctx context.Context, state *Peco, _ termbox.Event) {
if pdebug.Enabled {
g := pdebug.Marker("doToggleSelection")
defer g.End()
}
l, err := state.CurrentLineBuffer().LineAt(state.Location().LineNumber())
if err != nil {
return
@ -217,8 +221,10 @@ func doToggleSelection(ctx context.Context, state *Peco, _ termbox.Event) {
}
func doToggleRangeMode(ctx context.Context, state *Peco, _ termbox.Event) {
trace("doToggleRangeMode: START")
defer trace("doToggleRangeMode: END")
if pdebug.Enabled {
g := pdebug.Marker("doToggleRangeMode")
defer g.End()
}
r := state.SelectionRangeStart()
if r.Valid() {
@ -255,8 +261,10 @@ func doSelectAll(ctx context.Context, state *Peco, _ termbox.Event) {
}
func doSelectVisible(ctx context.Context, state *Peco, _ termbox.Event) {
trace("doSelectVisible: START")
defer trace("doSelectVisible: END")
if pdebug.Enabled {
g := pdebug.Marker("doSelectVisible")
defer g.End()
}
b := state.CurrentLineBuffer()
selection := state.Selection()
@ -275,8 +283,10 @@ func doSelectVisible(ctx context.Context, state *Peco, _ termbox.Event) {
}
func doFinish(ctx context.Context, state *Peco, _ termbox.Event) {
trace("doFinish: START")
defer trace("doFinish: END")
if pdebug.Enabled {
g := pdebug.Marker("doFinish")
defer g.End()
}
selection := state.Selection()
// Must end with all the selected lines.
@ -306,12 +316,14 @@ func doCancel(ctx context.Context, state *Peco, e termbox.Event) {
}
// peco.Cancel -> end program, exit with failure
state.Exit(ErrUserCanceled)
state.Exit(errors.New("user canceled"))
}
func doSelectDown(ctx context.Context, state *Peco, e termbox.Event) {
trace("doSelectDown: START")
defer trace("doSelectDown: END")
if pdebug.Enabled {
g := pdebug.Marker("doSelectDown")
defer g.End()
}
state.Hub().SendPaging(ToLineBelow)
}
@ -348,8 +360,10 @@ func doToggleSelectionAndSelectNext(ctx context.Context, state *Peco, e termbox.
}
func doInvertSelection(ctx context.Context, state *Peco, _ termbox.Event) {
trace("doInvertSelection: START")
defer trace("doInvertSelection: END")
if pdebug.Enabled {
g := pdebug.Marker("doInvertSelection")
defer g.End()
}
selection := state.Selection()
selection.Reset()
@ -368,15 +382,17 @@ func doInvertSelection(ctx context.Context, state *Peco, _ termbox.Event) {
}
func doDeleteBackwardWord(ctx context.Context, state *Peco, _ termbox.Event) {
q := state.Query()
trace("START doDeleteBackwardWord")
defer trace("END doDeleteBackwardWord")
if pdebug.Enabled {
g := pdebug.Marker("doDeleteBackwardWord")
defer g.End()
}
c := state.Caret()
if c.Pos() == 0 {
return
}
q := state.Query()
pos := q.Len()
if l := q.Len(); l <= c.Pos() {
pos = l
@ -596,20 +612,26 @@ func doDeleteForwardChar(ctx context.Context, state *Peco, _ termbox.Event) {
}
func doDeleteBackwardChar(ctx context.Context, state *Peco, e termbox.Event) {
trace("doDeleteBackwardChar: START")
defer trace("doDeleteBackwardChar: END")
if pdebug.Enabled {
g := pdebug.Marker("doDeleteBackwardChar")
defer g.End()
}
q := state.Query()
c := state.Caret()
qlen := q.Len()
if qlen <= 0 {
trace("doDeleteBackwardChar: QueryLen <= 0, do nothing")
if pdebug.Enabled {
pdebug.Printf("doDeleteBackwardChar: QueryLen <= 0, do nothing")
}
return
}
pos := c.Pos()
if pos == 0 {
trace("doDeleteBackwardChar: Already at position 0")
if pdebug.Enabled {
pdebug.Printf("doDeleteBackwardChar: Already at position 0")
}
// No op
return
}
@ -652,12 +674,18 @@ func doKonamiCommand(ctx context.Context, state *Peco, e termbox.Event) {
}
func doToggleSingleKeyJump(ctx context.Context, state *Peco, e termbox.Event) {
trace("Toggling SingleKeyJump")
if pdebug.Enabled {
g := pdebug.Marker("doToggleSingleKeyJump")
defer g.End()
}
state.ToggleSingleKeyJumpMode()
}
func doSingleKeyJump(ctx context.Context, state *Peco, e termbox.Event) {
trace("Doing single key jump for %c", e.Ch)
if pdebug.Enabled {
g := pdebug.Marker("doSingleKeyJump %c", e.Ch)
defer g.End()
}
index, ok := state.SingleKeyJumpIndex(e.Ch)
if !ok {
// Couldn't find it? Do nothing

View file

@ -6,6 +6,7 @@ import (
"sync"
"time"
"github.com/lestrrat/go-pdebug"
"github.com/peco/peco/pipeline"
"github.com/pkg/errors"
"golang.org/x/net/context"
@ -74,27 +75,30 @@ func (mb *MemoryBuffer) Done() <-chan struct{} {
}
func (mb *MemoryBuffer) Accept(ctx context.Context, p pipeline.Producer) {
trace("START MemoryBuffer.Accept")
defer trace("END MemoryBuffer.Accept")
if pdebug.Enabled {
g := pdebug.Marker("MemoryBuffer.Accept")
defer g.End()
}
defer close(mb.done)
for {
select {
case <-ctx.Done():
trace("MemoryBuffer received context done")
if pdebug.Enabled {
pdebug.Printf("MemoryBuffer received context done")
}
return
case v := <-p.OutCh():
switch v.(type) {
case error:
if pipeline.IsEndMark(v.(error)) {
trace("MemoryBuffer received end mark (read %d lines)", mb.Size())
if pdebug.Enabled {
pdebug.Printf("MemoryBuffer received end mark (read %d lines)", mb.Size())
}
return
}
case Line:
trace("MemoryBuffer received new line")
mb.lines = append(mb.lines, v.(Line))
default:
trace("MemoryBuffer received something else %s", v)
}
}
}
@ -209,26 +213,27 @@ func (s *Source) Setup(state *Peco) {
// Note: this will be a no-op if notify.Do has been called before
notify.Do(notifycb)
trace("Read all %d lines from source", readCount)
if pdebug.Enabled {
pdebug.Printf("Read all %d lines from source", readCount)
}
})
}
// Start starts
func (s *Source) Start(ctx context.Context) {
trace("START Source.Start")
defer trace("END Source.Start")
if pdebug.Enabled {
g := pdebug.Marker("Source.Start")
defer g.End()
}
defer s.OutputChannel.SendEndMark("end of input")
s.done = make(chan struct{})
trace("Going to send %d lines", len(s.lines))
for _, l := range s.lines {
select {
case <-ctx.Done():
trace("Source received done")
return
case s.OutputChannel <- l:
trace("Source sent to output channel")
// no op
}
}

View file

@ -1,13 +0,0 @@
// +build !debug
package peco
import "sync"
const debug = true
func newMutex() sync.Locker {
return &sync.Mutex{}
}
func trace(f string, args ...interface{}) {}

View file

@ -1,63 +0,0 @@
// +build debug
package peco
import (
"log"
"os"
"runtime"
"strconv"
"sync"
)
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{}) {
if tracer == nil {
return
}
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{}}
}
type loggingMutex struct {
*sync.Mutex
}
func (m *loggingMutex) Lock() {
buf := make([]byte, 8092)
l := runtime.Stack(buf, false)
mutexTrace("LOCK %s\n", buf[:l])
m.Mutex.Lock()
}
func (m *loggingMutex) Unlock() {
buf := make([]byte, 8092)
l := runtime.Stack(buf, false)
mutexTrace("UNLOCK %s\n", buf[:l])
m.Mutex.Unlock()
}

View file

@ -8,12 +8,12 @@ import (
"sort"
"sync"
"golang.org/x/net/context"
"github.com/lestrrat/go-pdebug"
"github.com/peco/peco/hub"
"github.com/peco/peco/internal/util"
"github.com/peco/peco/pipeline"
"github.com/pkg/errors"
"golang.org/x/net/context"
)
func (fx *FilterSet) Reset() {
@ -34,7 +34,9 @@ func (fs *FilterSet) Rotate() {
if fs.current >= len(fs.filters) {
fs.current = 0
}
trace("FilterSet.Rotate: now filter in effect is %s", fs.filters[fs.current])
if pdebug.Enabled {
pdebug.Printf("FilterSet.Rotate: now filter in effect is %s", fs.filters[fs.current])
}
}
func (fs *FilterSet) SetCurrentByName(name string) error {
@ -69,10 +71,8 @@ func (f *Filter) Work(ctx context.Context, q hub.Payload) {
state := f.state
if query == "" {
trace("Filter.Work: Resetting activingLineBuffer")
state.ResetCurrentLineBuffer()
} else {
trace("Filter.Work: Creating new pipeline")
// Create a new pipeline
p := pipeline.New()
p.SetSource(state.Source())
@ -91,12 +91,12 @@ func (f *Filter) Work(ctx context.Context, q hub.Payload) {
}()
go func() {
defer trace("query finished running")
trace("waiting for query to finish")
if pdebug.Enabled {
pdebug.Printf("waiting for query to finish")
defer pdebug.Printf("Filter.Work: finished running query")
}
<-p.Done()
trace("p.Done returns")
state.Hub().SendStatusMsg("")
trace("SendStatusMsg returns")
}()
}
@ -123,11 +123,7 @@ func (f *Filter) Loop(ctx context.Context, cancel func()) error {
case <-ctx.Done():
return nil
case q := <-f.state.Hub().QueryCh():
workctx, _workcancel := context.WithCancel(ctx)
workcancel := func() {
trace("Filter.Work cancel called!")
_workcancel()
}
workctx, workcancel := context.WithCancel(ctx)
mutex.Lock()
previous()
@ -166,25 +162,29 @@ func (rf RegexpFilter) Clone() LineFilter {
}
func (rf *RegexpFilter) Accept(ctx context.Context, p pipeline.Producer) {
trace("START RegexpFilter.Accept")
defer trace("END RegexpFilter.Accept")
if pdebug.Enabled {
g := pdebug.Marker("RegexpFilter.Accept")
defer g.End()
}
defer rf.outCh.SendEndMark("end of RegexpFilter")
for {
select {
case <-ctx.Done():
trace("RegexpFilter received done")
if pdebug.Enabled {
pdebug.Printf("RegexpFilter received done")
}
return
case v := <-p.OutCh():
switch v.(type) {
case error:
if pipeline.IsEndMark(v.(error)) {
trace("RegexpFilter received end mark")
if pdebug.Enabled {
pdebug.Printf("RegexpFilter received end mark")
}
return
}
case Line:
trace("RegexpFilter received new line")
if l, err := rf.filter(v.(Line)); err == nil {
trace("RegexpFilter send line")
rf.outCh.Send(l)
}
}
@ -193,8 +193,6 @@ func (rf *RegexpFilter) Accept(ctx context.Context, p pipeline.Producer) {
}
func (rf *RegexpFilter) filter(l Line) (Line, error) {
trace("RegexpFilter.filter: START")
defer trace("RegexpFilter.filter: END")
regexps, err := rf.getQueryAsRegexps()
if err != nil {
return nil, errors.Wrap(err, "failed to compile queries as regular expression")
@ -302,7 +300,6 @@ func NewSmartCaseFilter() *RegexpFilter {
}
func NewExternalCmdFilter(name, cmd string, args []string, threshold int, enableSep bool) *ExternalCmdFilter {
trace("name = %s, cmd = %s, args = %#v", name, cmd, args)
if len(args) == 0 {
args = []string{"$QUERY"}
}
@ -340,27 +337,35 @@ func (ecf *ExternalCmdFilter) Verify() error {
}
func (ecf *ExternalCmdFilter) Accept(ctx context.Context, p pipeline.Producer) {
trace("START ExternalCmdFilter.Accept")
defer trace("END ExternalCmdFilter.Accept")
if pdebug.Enabled {
g := pdebug.Marker("ExternalCmdFilter.Accept")
defer g.End()
}
defer ecf.outCh.SendEndMark("end of ExternalCmdFilter")
buf := make([]Line, 0, ecf.thresholdBufsiz)
for {
select {
case <-ctx.Done():
trace("ExternalCmdFilter received done")
if pdebug.Enabled {
pdebug.Printf("ExternalCmdFilter received done")
}
return
case v := <-ecf.OutCh():
switch v.(type) {
case error:
if pipeline.IsEndMark(v.(error)) {
trace("ExternalCmdFilter received end mark")
if pdebug.Enabled {
pdebug.Printf("ExternalCmdFilter received end mark")
}
if len(buf) > 0 {
ecf.launchExternalCmd(ctx, buf)
}
}
case Line:
trace("ExternalCmdFilter received new line")
if pdebug.Enabled {
pdebug.Printf("ExternalCmdFilter received new line")
}
buf = append(buf, v.(Line))
if len(buf) < ecf.thresholdBufsiz {
continue
@ -387,11 +392,10 @@ func (ecf ExternalCmdFilter) String() string {
func (ecf *ExternalCmdFilter) launchExternalCmd(ctx context.Context, buf []Line) {
defer func() { recover() }() // ignore errors
trace("ExternalCmdFilter.launchExternalCmd: START")
defer trace("ExternalCmdFilter.launchExternalCmd: END")
trace("buf = %v", buf)
if pdebug.Enabled {
g := pdebug.Marker("ExternalCmdFilter.launchExternalCmd")
defer g.End()
}
args := append([]string(nil), ecf.args...)
for i, v := range args {
@ -412,7 +416,6 @@ func (ecf *ExternalCmdFilter) launchExternalCmd(ctx context.Context, buf []Line)
return
}
trace("cmd = %#v", cmd)
err = cmd.Start()
if err != nil {
return
@ -445,8 +448,6 @@ func (ecf *ExternalCmdFilter) launchExternalCmd(ctx context.Context, buf []Line)
}
}()
defer trace("Done waiting for cancel or line")
for {
select {
case <-ctx.Done():
@ -455,7 +456,6 @@ func (ecf *ExternalCmdFilter) launchExternalCmd(ctx context.Context, buf []Line)
if l == nil || !ok {
return
}
trace("Custom: l = %s", l.DisplayString())
ecf.outCh.Send(l)
}
}

View file

@ -54,7 +54,6 @@ func (i *Input) handleInputEvent(ctx context.Context, ev termbox.Event) error {
m.Lock()
i.mod = nil
m.Unlock()
// trace("Input.handleInputEvent: Firing delayed input event")
i.handleInputEvent(ctx, tmp)
})
m.Unlock()

View file

@ -157,7 +157,9 @@ type Screen interface {
}
// Termbox just hands out the processing to the termbox library
type Termbox struct{}
type Termbox struct {
mutex sync.Mutex
}
// View handles the drawing/updating the screen
type View struct {
@ -210,7 +212,7 @@ type StatusBar struct {
*AnchorSettings
clearTimer *time.Timer
styles *StyleSet
timerMutex sync.Locker
timerMutex sync.Mutex
}
// ListArea represents the area where the actual line buffer is

View file

@ -5,6 +5,7 @@ import (
"strings"
"time"
"github.com/lestrrat/go-pdebug"
"github.com/nsf/termbox-go"
"github.com/peco/peco/internal/keyseq"
"github.com/pkg/errors"
@ -47,18 +48,23 @@ func (km Keymap) LookupAction(ev termbox.Event) Action {
Ch: ev.Ch,
}
action, err := km.seq.AcceptKey(key)
trace("err = %s\n", err)
switch err {
case nil:
// Found an action!
trace("Keymap.Handler: Fetched action")
if pdebug.Enabled {
pdebug.Printf("Keymap.Handler: Fetched action")
}
return wrapClearSequence(action.(Action))
case keyseq.ErrInSequence:
trace("Keymap.Handler: Waiting for more commands...")
if pdebug.Enabled {
pdebug.Printf("Keymap.Handler: Waiting for more commands...")
}
return wrapRememberSequence(ActionFunc(doNothing))
default:
trace("Keymap.Handler: Defaulting to doAcceptChar")
if pdebug.Enabled {
pdebug.Printf("Keymap.Handler: Defaulting to doAcceptChar")
}
return wrapClearSequence(ActionFunc(doAcceptChar))
}
}
@ -160,7 +166,6 @@ func (km *Keymap) ApplyKeybinding() error {
for _, s := range keys {
a := kb[s]
trace("%s", s)
list, err := keyseq.ToKeyList(s)
if err != nil {
return errors.Wrapf(err, "urnknown key %s: %s", s, err)

View file

@ -2,11 +2,11 @@ package peco
import (
"fmt"
"reflect"
"strconv"
"time"
"unicode/utf8"
"github.com/lestrrat/go-pdebug"
"github.com/mattn/go-runewidth"
"github.com/nsf/termbox-go"
"github.com/pkg/errors"
@ -95,8 +95,10 @@ func NewUserPrompt(screen Screen, anchor VerticalAnchor, anchorOffset int, promp
// Draw draws the query prompt
func (u UserPrompt) Draw(state *Peco) {
trace("UserPrompt.Draw: START")
defer trace("UserPrompt.Draw: END")
if pdebug.Enabled {
g := pdebug.Marker("UserPrompt.Draw")
defer g.End()
}
location := u.AnchorPosition()
@ -209,7 +211,6 @@ func NewStatusBar(screen Screen, anchor VerticalAnchor, anchorOffset int, styles
AnchorSettings: NewAnchorSettings(screen, anchor, anchorOffset),
clearTimer: nil,
styles: styles,
timerMutex: newMutex(),
}
}
@ -319,8 +320,10 @@ func selectionContains(state *Peco, n int) bool {
// Draw displays the ListArea on the screen
func (l *ListArea) Draw(state *Peco, parent Layout, perPage int, runningQuery bool) {
trace("START ListArea.Draw perPage = %d, runningQuery = %t", perPage, runningQuery)
defer trace("END ListArea.Draw")
if pdebug.Enabled {
g := pdebug.Marker("ListArea.Draw pp = %d, q = %t", perPage, runningQuery)
defer g.End()
}
if perPage < 1 {
panic("perPage < 1 (was " + strconv.Itoa(perPage) + ")")
@ -376,7 +379,10 @@ func (l *ListArea) Draw(state *Peco, parent Layout, perPage int, runningQuery bo
// If our buffer is smaller than perPage, we may need to
// clear some lines
trace("ListArea.Draw: buffer size is %d, our view area is %d\n", bufsiz, perPage)
if pdebug.Enabled {
pdebug.Printf("ListArea.Draw: buffer size is %d, our view area is %d", bufsiz, perPage)
}
for n := bufsiz; n < perPage; n++ {
l.displayCache[n] = nil
if l.sortTopDown {
@ -385,7 +391,6 @@ func (l *ListArea) Draw(state *Peco, parent Layout, perPage int, runningQuery bo
y = start - n
}
trace("ListArea.Draw: clearing row %d", y)
l.screen.Print(PrintArgs{
Y: y,
Fg: l.styles.Basic.fg,
@ -541,7 +546,9 @@ func (l *ListArea) Draw(state *Peco, parent Layout, perPage int, runningQuery bo
}
}
l.SetDirty(false)
trace("ListArea.Draw: Written total of %d lines (%d cached)\n", written+cached, cached)
if pdebug.Enabled {
pdebug.Printf("ListArea.Draw: Written total of %d lines (%d cached)", written+cached, cached)
}
}
// NewDefaultLayout creates a new Layout in the default format (top-down)
@ -574,10 +581,12 @@ func (l *BasicLayout) PurgeDisplayCache() {
// CalculatePage calculates which page we're displaying
func (l *BasicLayout) CalculatePage(state *Peco, perPage int) error {
if pdebug.Enabled {
g := pdebug.Marker("BasicLayout.Calculate %d", perPage)
defer g.End()
}
buf := state.CurrentLineBuffer()
loc := state.Location()
trace("BasicLayout.CalculatePage buf = %s", reflect.TypeOf(buf).String())
defer trace("BasicLayout.CalculatePage: %#v", loc)
loc.SetPage((loc.LineNumber() / perPage) + 1)
loc.SetOffset((loc.Page() - 1) * perPage)
loc.SetPerPage(perPage)
@ -607,8 +616,10 @@ func (l *BasicLayout) DrawPrompt(state *Peco) {
// DrawScreen draws the entire screen
func (l *BasicLayout) DrawScreen(state *Peco, runningQuery bool) {
trace("DrawScreen: START")
defer trace("DrawScreen: END")
if pdebug.Enabled {
g := pdebug.Marker("BasicLayout.DrawScreen")
defer g.End()
}
perPage := l.linesPerPage()
@ -654,14 +665,18 @@ func verticalScroll(state *Peco, l *BasicLayout, p PagingRequest) bool {
lineBefore := loc.LineNumber()
lineno := lineBefore
defer func() { trace("currentLine changed from %d -> %d", lineBefore, state.Location().LineNumber()) }()
if pdebug.Enabled {
defer func() {
pdebug.Printf("currentLine changed from %d -> %d", lineBefore, state.Location().LineNumber())
}()
}
buf := state.CurrentLineBuffer()
lcur := buf.Size()
defer func() {
for _, lno := range []int{lineBefore, loc.LineNumber()} {
if oldLine, err := buf.LineAt(lno); err == nil {
trace("Setting line %d dirty", lno)
oldLine.SetDirty(true)
}
}

View file

@ -66,6 +66,5 @@ func (l Location) PageCrop() PageCrop {
// Crop returns a new Buffer whose contents are
// bound within the given range
func (pf PageCrop) Crop(in Buffer) Buffer {
trace("Cropping for page %d, %d entries per page", pf.currentPage, pf.perPage)
return NewFilteredBuffer(in, pf.currentPage, pf.perPage)
}

64
peco.go
View file

@ -8,6 +8,7 @@ import (
"golang.org/x/net/context"
"github.com/google/btree"
"github.com/lestrrat/go-pdebug"
"github.com/peco/peco/hub"
"github.com/peco/peco/internal/util"
"github.com/peco/peco/pipeline"
@ -42,7 +43,7 @@ func New() *Peco {
currentLineBuffer: NewMemoryBuffer(), // XXX revisit this
queryExecDelay: 50 * time.Millisecond,
readyCh: make(chan struct{}),
screen: Termbox{},
screen: &Termbox{},
selection: NewSelection(),
}
}
@ -177,9 +178,12 @@ func (p *Peco) Keymap() Keymap {
return p.keymap
}
func (p *Peco) Setup() error {
trace("START Peco.Setup")
defer trace("END Peco.Setup")
func (p *Peco) Setup() (err error) {
if pdebug.Enabled {
g := pdebug.Marker("Peco.Setup").BindError(&err)
defer g.End()
}
if err := p.config.Init(); err != nil {
return errors.Wrap(err, "failed to initialize config")
}
@ -212,9 +216,12 @@ func (p *Peco) Setup() error {
return nil
}
func (p *Peco) Run(ctx context.Context) error {
trace("START Peco.Run")
defer trace("END Peco.Run")
func (p *Peco) Run(ctx context.Context) (err error) {
if pdebug.Enabled {
g := pdebug.Marker("Peco.Run").BindError(&err)
defer g.End()
}
if err := p.Setup(); err != nil {
return errors.Wrap(err, "failed to setup peco")
}
@ -227,7 +234,9 @@ func (p *Peco) Run(ctx context.Context) error {
var _cancel func()
ctx, _cancel = context.WithCancel(ctx)
cancel := func() {
trace("cancel function called!")
if pdebug.Enabled {
pdebug.Printf("Peco.Run cancel called")
}
_cancel()
}
@ -253,7 +262,10 @@ func (p *Peco) Run(ctx context.Context) error {
go l.Loop(ctx, cancel)
}
trace("peco is now ready, go go go!")
if pdebug.Enabled {
pdebug.Printf("peco is now ready, go go go!")
}
close(p.readyCh)
<-ctx.Done()
@ -270,11 +282,13 @@ func parseCommandLine(opts *CLIOptions, args *[]string, argv []string) error {
return nil
}
func (p *Peco) SetupSource() (*Source, error) {
trace("START Peco.SetupSource")
defer trace("END Peco.SetupSource")
func (p *Peco) SetupSource() (s *Source, err error) {
if pdebug.Enabled {
g := pdebug.Marker("Peco.SetupSource").BindError(&err)
defer g.End()
}
var in *os.File
var err error
switch {
case len(p.args) > 1:
in, err = os.Open(p.args[1])
@ -289,8 +303,11 @@ func (p *Peco) SetupSource() (*Source, error) {
defer in.Close()
src := NewSource(in, p.enableSep)
// Block until we receive something from `in`
trace("Blocking until we read something in source...")
if pdebug.Enabled {
pdebug.Printf("Blocking until we read something in source...")
}
go src.Setup(p)
<-src.Ready()
@ -375,7 +392,10 @@ func (p *Peco) CurrentLineBuffer() Buffer {
}
func (p *Peco) SetCurrentLineBuffer(b Buffer) {
trace("Peco.SetCurrentLineBuffer %s", reflect.TypeOf(b).String())
if pdebug.Enabled {
g := pdebug.Marker("Peco.SetCurrentLineBuffer %s", reflect.TypeOf(b).String())
defer g.End()
}
p.currentLineBuffer = b
p.Hub().SendDraw(false)
}
@ -385,13 +405,17 @@ func (p *Peco) ResetCurrentLineBuffer() {
}
func (p *Peco) ExecQuery() bool {
trace("Peco.ExecQuery: START")
defer trace("Peco.ExecQuery: END")
if pdebug.Enabled {
g := pdebug.Marker("Peco.ExecQuery")
defer g.End()
}
select {
case <-p.Ready():
default:
trace("peco is not ready yet, ignoring.")
if pdebug.Enabled {
pdebug.Printf("peco is not ready yet, ignoring.")
}
return false
}
@ -399,7 +423,9 @@ func (p *Peco) ExecQuery() bool {
// the raw source buffer
q := p.Query()
if q.Len() <= 0 {
trace("empty query, reset buffer")
if pdebug.Enabled {
pdebug.Printf("empty query, reset buffer")
}
p.ResetCurrentLineBuffer()
return true
}

View file

@ -13,14 +13,13 @@ import (
type interceptorArgs []interface{}
type interceptor struct {
m sync.Locker
m sync.Mutex
events map[string][]interceptorArgs
}
func newInterceptor() *interceptor {
return &interceptor{
newMutex(),
make(map[string][]interceptorArgs),
events: make(map[string][]interceptorArgs),
}
}

View file

@ -8,12 +8,7 @@ import (
"github.com/pkg/errors"
)
// termbox always gives us some sort of warning when we run
// go run -race cmd/peco/peco.go
var termboxMutex = newMutex()
func (t Termbox) Init() error {
trace("initializing termbox")
func (t *Termbox) Init() error {
if err := termbox.Init(); err != nil {
return errors.Wrap(err, "failed to initialized termbox")
}
@ -21,7 +16,7 @@ func (t Termbox) Init() error {
return t.PostInit()
}
func (t Termbox) Close() error {
func (t *Termbox) Close() error {
termbox.Close()
return nil
}
@ -29,21 +24,21 @@ func (t Termbox) Close() error {
// SendEvent is used to allow programmers generate random
// events, but it's only useful for testing purposes.
// When interactiving with termbox-go, this method is a noop
func (t Termbox) SendEvent(_ termbox.Event) {
func (t *Termbox) SendEvent(_ termbox.Event) {
// no op
}
// Flush calls termbox.Flush
func (t Termbox) Flush() error {
termboxMutex.Lock()
defer termboxMutex.Unlock()
func (t *Termbox) Flush() error {
t.mutex.Lock()
defer t.mutex.Unlock()
return errors.Wrap(termbox.Flush(), "failed to flush termbox")
}
// PollEvent returns a channel that you can listen to for
// termbox's events. The actual polling is done in a
// separate gouroutine
func (t Termbox) PollEvent() chan termbox.Event {
func (t *Termbox) PollEvent() chan termbox.Event {
// XXX termbox.PollEvent() can get stuck on unexpected signal
// handling cases. We still would like to wait until the user
// (termbox) has some event for us to process, but we don't
@ -66,16 +61,16 @@ func (t Termbox) PollEvent() chan termbox.Event {
}
// SetCell writes to the terminal
func (t Termbox) SetCell(x, y int, ch rune, fg, bg termbox.Attribute) {
termboxMutex.Lock()
defer termboxMutex.Unlock()
func (t *Termbox) SetCell(x, y int, ch rune, fg, bg termbox.Attribute) {
t.mutex.Lock()
defer t.mutex.Unlock()
termbox.SetCell(x, y, ch, fg, bg)
}
// Size returns the dimensions of the current terminal
func (t Termbox) Size() (int, int) {
termboxMutex.Lock()
defer termboxMutex.Unlock()
func (t *Termbox) Size() (int, int) {
t.mutex.Lock()
defer t.mutex.Unlock()
return termbox.Size()
}
@ -89,7 +84,7 @@ type PrintArgs struct {
Fill bool
}
func (t Termbox) Print(args PrintArgs) int {
func (t *Termbox) Print(args PrintArgs) int {
return screenPrint(t, args)
}

View file

@ -113,7 +113,6 @@ func (v *View) movePage(p PagingRequest) {
v.mutex.Lock()
defer v.mutex.Unlock()
trace("Pageing request = %s", p)
if v.layout.MovePage(v.state, p) {
v.layout.DrawScreen(v.state, false)
}