feat: implement pagination

This commit is contained in:
Nao YONASHIRO 2018-02-12 17:40:47 +09:00
parent 95fb1dd6f4
commit 63302a5036
3 changed files with 52 additions and 12 deletions

View File

@ -28,6 +28,8 @@ type CompletionManager struct {
tmp []Suggest
max uint16
completer Completer
verticalScroll int
}
// GetSelectedSuggestion returns the selected item.
@ -50,6 +52,7 @@ func (c *CompletionManager) GetSuggestions() []Suggest {
// Reset to select nothing.
func (c *CompletionManager) Reset() {
c.selected = -1
c.verticalScroll = 0
c.Update(*NewDocument())
return
}
@ -62,6 +65,9 @@ func (c *CompletionManager) Update(in Document) {
// Previous to select the previous suggestion item.
func (c *CompletionManager) Previous() {
if c.verticalScroll == c.selected && c.selected > 0 {
c.verticalScroll--
}
c.selected--
c.update()
return
@ -69,6 +75,9 @@ func (c *CompletionManager) Previous() {
// Next to select the next suggestion item.
func (c *CompletionManager) Next() {
if c.verticalScroll+int(c.max)-1 == c.selected {
c.verticalScroll++
}
c.selected++
c.update()
return
@ -84,10 +93,12 @@ func (c *CompletionManager) update() {
if len(c.tmp) < max {
max = len(c.tmp)
}
if c.selected >= max {
if c.selected >= len(c.tmp) {
c.Reset()
} else if c.selected < -1 {
c.selected = max - 1
c.selected = len(c.tmp) - 1
c.verticalScroll = len(c.tmp) - max
}
}
@ -160,5 +171,7 @@ func NewCompletionManager(completer Completer, max uint16) *CompletionManager {
selected: -1,
max: max,
completer: completer,
verticalScroll: 0,
}
}

View File

@ -194,6 +194,8 @@ func New(executor Executor, completer Completer, opts ...Option) *Prompt {
descriptionBGColor: Turquoise,
selectedDescriptionTextColor: White,
selectedDescriptionBGColor: Cyan,
scrollbarThumbColor: DarkGray,
scrollbarBGColor: Cyan,
},
buf: NewBuffer(),
executor: executor,

View File

@ -1,5 +1,9 @@
package prompt
import (
"math"
)
// Render to render prompt information from state of Buffer.
type Render struct {
out ConsoleWriter
@ -22,6 +26,8 @@ type Render struct {
descriptionBGColor Color
selectedDescriptionTextColor Color
selectedDescriptionBGColor Color
scrollbarThumbColor Color
scrollbarBGColor Color
}
// Setup to initialize console output.
@ -72,24 +78,34 @@ func (r *Render) renderWindowTooSmall() {
}
func (r *Render) renderCompletion(buf *Buffer, completions *CompletionManager) {
max := completions.max
if max > r.row {
max = r.row
windowHeight := len(completions.tmp)
if windowHeight > int(completions.max) {
windowHeight = int(completions.max)
}
contentHeight := len(completions.tmp)
fractionVisible := float64(windowHeight) / float64(contentHeight)
fractionAbove := float64(completions.verticalScroll) / float64(contentHeight)
scrollbarHeight := int(math.Min(float64(windowHeight), math.Max(1, float64(windowHeight)*fractionVisible)))
scrollbarTop := int(float64(windowHeight) * fractionAbove)
isScrollThumb := func(row int) bool {
return scrollbarTop <= row && row <= scrollbarTop+scrollbarHeight
}
suggestions := completions.GetSuggestions()
if l := len(completions.GetSuggestions()); l == 0 {
return
} else if l > int(max) {
suggestions = suggestions[:max]
}
formatted, width := formatSuggestions(
suggestions,
int(r.col)-len(r.prefix),
int(r.col)-len(r.prefix)-1,
)
formatted = formatted[completions.verticalScroll : completions.verticalScroll+windowHeight]
l := len(formatted)
r.prepareArea(l)
r.prepareArea(windowHeight)
d := (len(r.prefix) + len(buf.Document().TextBeforeCursor())) % int(r.col)
if d == 0 { // the cursor is on right end.
@ -98,23 +114,32 @@ func (r *Render) renderCompletion(buf *Buffer, completions *CompletionManager) {
r.out.CursorBackward(d + width - int(r.col))
}
selected := completions.selected - completions.verticalScroll
r.out.SetColor(White, Cyan, false)
for i := 0; i < l; i++ {
r.out.CursorDown(1)
if i == completions.selected {
if i == selected {
r.out.SetColor(r.selectedSuggestionTextColor, r.selectedSuggestionBGColor, true)
} else {
r.out.SetColor(r.suggestionTextColor, r.suggestionBGColor, false)
}
r.out.WriteStr(formatted[i].Text)
if i == completions.selected {
if i == selected {
r.out.SetColor(r.selectedDescriptionTextColor, r.selectedDescriptionBGColor, false)
} else {
r.out.SetColor(r.descriptionTextColor, r.descriptionBGColor, false)
}
r.out.WriteStr(formatted[i].Description)
r.out.CursorBackward(width)
if isScrollThumb(i) {
r.out.SetColor(DefaultColor, r.scrollbarThumbColor, false)
} else {
r.out.SetColor(DefaultColor, r.scrollbarBGColor, false)
}
r.out.WriteStr(" ")
r.out.CursorBackward(width + 1)
}
if d == 0 { // the cursor is on right end.
// DON'T CURSOR DOWN HERE. Because the line doesn't erase properly.