diff --git a/caret.go b/caret.go index 86782ed..00d1917 100644 --- a/caret.go +++ b/caret.go @@ -6,14 +6,18 @@ func (c *Caret) Pos() int { return c.pos } +func (c *Caret) setPos_nolock(p int) { + c.pos = p +} + func (c *Caret) SetPos(p int) { c.mutex.Lock() defer c.mutex.Unlock() - c.pos = p + c.setPos_nolock(p) } func (c *Caret) Move(diff int) { c.mutex.Lock() defer c.mutex.Unlock() - c.pos = c.pos + diff + c.setPos_nolock(c.pos + diff) } diff --git a/interface.go b/interface.go index 9bb4f68..f8661f7 100644 --- a/interface.go +++ b/interface.go @@ -157,6 +157,7 @@ type Screen interface { Print(PrintArgs) int Resume() SetCell(int, int, rune, termbox.Attribute, termbox.Attribute) + SetCursor(int, int) Size() (int, int) SendEvent(termbox.Event) Suspend() diff --git a/layout.go b/layout.go index 77257de..cea0f52 100644 --- a/layout.go +++ b/layout.go @@ -111,6 +111,10 @@ func (u UserPrompt) Draw(state *Peco) { fg := u.styles.Query.fg bg := u.styles.Query.bg + + // Used to notify termbox where our cursor is + var posX int + switch ql { case 0: u.screen.Print(PrintArgs{ @@ -120,6 +124,7 @@ func (u UserPrompt) Draw(state *Peco) { Bg: bg, Fill: true, }) + posX = u.promptLen + 1 u.screen.Print(PrintArgs{ X: u.promptLen + 1, Y: location, @@ -145,8 +150,9 @@ func (u UserPrompt) Draw(state *Peco) { Msg: qs, Fill: false, }) + posX = u.promptLen + 1 + int(runewidth.StringWidth(qs)) u.screen.Print(PrintArgs{ - X: u.promptLen + 1 + int(runewidth.StringWidth(qs)), + X: posX, Y: location, Fg: fg | termbox.AttrReverse, Bg: bg | termbox.AttrReverse, @@ -154,6 +160,7 @@ func (u UserPrompt) Draw(state *Peco) { Fill: false, }) default: + posX = c.Pos() // the caret is in the middle of the string prev := int(0) var i int @@ -179,6 +186,8 @@ func (u UserPrompt) Draw(state *Peco) { }) } + u.screen.SetCursor(posX, location) + width, _ := u.screen.Size() loc := state.Location() diff --git a/peco_test.go b/peco_test.go index 78758cb..81bdb23 100644 --- a/peco_test.go +++ b/peco_test.go @@ -101,6 +101,9 @@ func NewDummyScreen() *dummyScreen { } } +func (d dummyScreen) SetCursor(_, _ int) { +} + func (d dummyScreen) Init() error { return nil } diff --git a/screen.go b/screen.go index f6dd71e..fe56857 100644 --- a/screen.go +++ b/screen.go @@ -34,6 +34,10 @@ func (t *Termbox) Close() error { return nil } +func (t *Termbox) SetCursor(x, y int) { + termbox.SetCursor(x, y) +} + // 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