diff --git a/action.go b/action.go index 81a863a..0f23866 100644 --- a/action.go +++ b/action.go @@ -317,7 +317,7 @@ func doDeleteBackwardWord(i *Input, _ termbox.Event) { return } - i.current = nil + i.SetCurrent(nil) i.DrawMatches(nil) } @@ -444,7 +444,7 @@ func doDeleteForwardWord(i *Input, _ termbox.Event) { return } - i.current = nil + i.SetCurrent(nil) i.DrawMatches(nil) } @@ -472,7 +472,7 @@ func doKillBeginningOfLine(i *Input, _ termbox.Event) { if i.ExecQuery() { return } - i.current = nil + i.SetCurrent(nil) i.DrawMatches(nil) } @@ -485,13 +485,13 @@ func doKillEndOfLine(i *Input, _ termbox.Event) { if i.ExecQuery() { return } - i.current = nil + i.SetCurrent(nil) i.DrawMatches(nil) } func doDeleteAll(i *Input, _ termbox.Event) { i.SetQuery(make([]rune, 0)) - i.current = nil + i.SetCurrent(nil) i.DrawMatches(nil) } @@ -511,7 +511,7 @@ func doDeleteForwardChar(i *Input, _ termbox.Event) { return } - i.current = nil + i.SetCurrent(nil) i.DrawMatches(nil) } @@ -539,7 +539,7 @@ func doDeleteBackwardChar(i *Input, ev termbox.Event) { return } - i.current = nil + i.SetCurrent(nil) i.DrawMatches(nil) } diff --git a/ctx.go b/ctx.go index c89f426..f546bd3 100644 --- a/ctx.go +++ b/ctx.go @@ -5,10 +5,13 @@ import ( "io" "os" "os/signal" + "runtime" "sync" "syscall" ) +const debug = false + var screen Screen = Termbox{} // CtxOptions is the interface that defines that options can be @@ -38,16 +41,10 @@ type PageInfo struct { } type CaretPosition struct { - pos int + pos int mutex *sync.Mutex } -func (p CaretPosition) Int() int { - p.mutex.Lock() - defer p.mutex.Unlock() - return int(p.pos) -} - func (p CaretPosition) CaretPos() int { p.mutex.Lock() defer p.mutex.Unlock() @@ -61,7 +58,9 @@ func (p *CaretPosition) SetCaretPos(where int) { } func (p *CaretPosition) MoveCaretPos(offset int) { - p.SetCaretPos(p.Int() + offset) + p.mutex.Lock() + defer p.mutex.Unlock() + p.pos = p.pos + offset } type FilterQuery struct { @@ -113,7 +112,7 @@ type Ctx struct { *MatcherSet enableSep bool result []Match - mutex *sync.Mutex + mutex sync.Locker currentLine int currentPage *PageInfo maxPage int @@ -132,6 +131,31 @@ type Ctx struct { wait *sync.WaitGroup } +func newMutex() sync.Locker { + if debug { + return &loggingMutex{&sync.Mutex{}} + } + return &sync.Mutex{} +} + +type loggingMutex struct { + *sync.Mutex +} + +func (m *loggingMutex) Lock() { + buf := make([]byte, 8092) + l := runtime.Stack(buf, false) + fmt.Printf("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]) + m.Mutex.Unlock() +} + func NewCtx(o CtxOptions) *Ctx { c := &Ctx{ Hub: NewHub(), @@ -139,7 +163,7 @@ func NewCtx(o CtxOptions) *Ctx { FilterQuery: &FilterQuery{[]rune{}, &sync.Mutex{}}, MatcherSet: nil, result: []Match{}, - mutex: &sync.Mutex{}, + mutex: newMutex(), currentPage: &PageInfo{0, 1, 0}, maxPage: 0, selection: NewSelection(), @@ -235,10 +259,14 @@ func (c *Ctx) IsRangeMode() bool { } func (c *Ctx) SelectionClear() { + c.mutex.Lock() + defer c.mutex.Unlock() c.selection.Clear() } func (c *Ctx) SelectionContains(n int) bool { + c.mutex.Lock() + defer c.mutex.Unlock() return c.selection.Has(n) } @@ -341,7 +369,7 @@ func (c *Ctx) NewView() *View { default: layout = NewDefaultLayout(c) } - return &View{c, layout} + return &View{c, &sync.Mutex{}, layout} } func (c *Ctx) NewFilter() *Filter { @@ -356,9 +384,9 @@ func (c *Ctx) NewInput() *Input { } func (c *Ctx) SetQuery(q []rune) { - c.FilterQuery.mutex.Lock() + c.mutex.Lock() c.FilterQuery.query = q - c.FilterQuery.mutex.Unlock() + c.mutex.Unlock() c.SetCaretPos(c.QueryLen()) } diff --git a/matchers.go b/matchers.go index 6476bcc..1404687 100644 --- a/matchers.go +++ b/matchers.go @@ -416,6 +416,7 @@ func (m *RegexpMatcher) Match(quit chan struct{}, q string, buffer []Match) []Ma if ms == nil { continue } + iter <- NewDidMatch(match.Buffer(), m.enableSep, ms) } iter <- nil diff --git a/view.go b/view.go index ba5b200..0052b54 100644 --- a/view.go +++ b/view.go @@ -1,10 +1,14 @@ package peco -import "time" +import ( + "sync" + "time" +) // View handles the drawing/updating the screen type View struct { *Ctx + mutex sync.Locker layout Layout } @@ -26,7 +30,7 @@ const ( // on the status message bar and an optional delay that tells // the view to clear that message type StatusMsgRequest struct { - message string + message string clearDelay time.Duration }