mirror of
https://github.com/peco/peco.git
synced 2026-09-10 07:16:29 -04:00
Use pdebug instead of trace
This commit is contained in:
parent
39eb717c6e
commit
c12cd97d29
92
action.go
92
action.go
|
|
@ -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
|
||||
|
|
|
|||
31
buffer.go
31
buffer.go
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
13
debug_off.go
13
debug_off.go
|
|
@ -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{}) {}
|
||||
63
debug_on.go
63
debug_on.go
|
|
@ -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()
|
||||
}
|
||||
74
filter.go
74
filter.go
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
input.go
1
input.go
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
15
keymap.go
15
keymap.go
|
|
@ -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)
|
||||
|
|
|
|||
45
layout.go
45
layout.go
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
page.go
1
page.go
|
|
@ -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
64
peco.go
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
33
screen.go
33
screen.go
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue