Fix bug when specified max completions

This commit is contained in:
c-bata 2017-07-18 00:52:55 +09:00
parent 7b8f4e8e91
commit 6dcb8dfe6e
3 changed files with 43 additions and 36 deletions

View File

@ -118,7 +118,7 @@ func OptionSelectedSuggestionBGColor(x Color) option {
func OptionMaxCompletions(x uint16) option {
return func(p *Prompt) error {
p.renderer.maxCompletions = x
p.maxCompletions = x
return nil
}
}
@ -141,12 +141,12 @@ func NewPrompt(executor Executor, completer Completer, opts ...option) *Prompt {
suggestionBGColor: Cyan,
selectedSuggestionTextColor: Black,
selectedSuggestionBGColor: Turquoise,
maxCompletions: 10,
},
buf: NewBuffer(),
executor: executor,
completer: completer,
chosen: -1,
maxCompletions: 6,
selected: -1,
}
for _, opt := range opts {

View File

@ -11,12 +11,13 @@ type Executor func(*Buffer) string
type Completer func(*Buffer) []string
type Prompt struct {
in ConsoleParser
buf *Buffer
renderer *Render
executor Executor
completer Completer
chosen int // -1 means nothing one is chosen.
in ConsoleParser
buf *Buffer
renderer *Render
executor Executor
completer Completer
maxCompletions uint16
selected int // -1 means nothing one is selected.
}
func (p *Prompt) Run() {
@ -36,19 +37,19 @@ func (p *Prompt) Run() {
p.renderer.Erase(p.buf)
ac := p.in.GetASCIICode(b)
if ac == nil {
if p.chosen != -1 {
c := p.completer(p.buf)[p.chosen]
if p.selected != -1 {
c := p.completer(p.buf)[p.selected]
w := p.buf.Document().GetWordBeforeCursor()
if w != "" {
p.buf.DeleteBeforeCursor(len([]rune(w)))
}
p.buf.InsertText(c, false, true)
}
p.chosen = -1
p.selected = -1
p.buf.InsertText(string(b), false, true)
} else if ac.Key == ControlJ || ac.Key == Enter {
if p.chosen != -1 {
c := p.completer(p.buf)[p.chosen]
if p.selected != -1 {
c := p.completer(p.buf)[p.selected]
w := p.buf.Document().GetWordBeforeCursor()
if w != "" {
p.buf.DeleteBeforeCursor(len([]rune(w)))
@ -58,30 +59,26 @@ func (p *Prompt) Run() {
res := p.executor(p.buf)
p.renderer.BreakLine(p.buf, res)
p.buf = NewBuffer()
p.chosen = -1
p.selected = -1
} else if ac.Key == ControlC || ac.Key == ControlD {
return
} else if ac.Key == BackTab || ac.Key == Up {
p.chosen -= 1
p.selected -= 1
} else if ac.Key == Tab || ac.Key == ControlI || ac.Key == Down {
p.chosen += 1
p.selected += 1
} else {
InputHandler(ac, p.buf)
p.chosen = -1
p.selected = -1
}
completions := p.completer(p.buf)
if p.chosen >= len(completions) {
p.chosen = -1
} else if p.chosen < -1 {
p.chosen = len(completions) - 1
}
p.renderer.Render(p.buf, completions, p.chosen)
p.updateSelectedCompletion(completions)
p.renderer.Render(p.buf, completions, p.maxCompletions, p.selected)
case w := <-winSizeCh:
p.renderer.UpdateWinSize(w)
p.renderer.Erase(p.buf)
completions := p.completer(p.buf)
p.renderer.Render(p.buf, completions, p.chosen)
p.renderer.Render(p.buf, completions, p.maxCompletions, p.selected)
case e := <-exitCh:
if e {
return
@ -92,6 +89,18 @@ func (p *Prompt) Run() {
}
}
func (p *Prompt) updateSelectedCompletion(completions []string) {
max := int(p.maxCompletions)
if len(completions) < max {
max = len(completions)
}
if p.selected >= max {
p.selected = -1
} else if p.selected < -1 {
p.selected = max - 1
}
}
func (p *Prompt) setUp() {
p.in.Setup()
p.renderer.Setup()

View File

@ -8,7 +8,6 @@ type Render struct {
title string
row uint16
col uint16
maxCompletions uint16
// colors
prefixTextColor Color
prefixBGColor Color
@ -60,15 +59,14 @@ func (r *Render) UpdateWinSize(ws *WinSize) {
return
}
func (r *Render) renderCompletion(buf *Buffer, words []string, chosen int) {
max := int(r.maxCompletions)
if r.maxCompletions > r.row {
max = int(r.row)
func (r *Render) renderCompletion(buf *Buffer, words []string, max uint16, selected int) {
if max > r.row {
max = r.row
}
if l := len(words); l == 0 {
return
} else if l > max {
} else if l > int(max) {
words = words[:max]
}
@ -89,7 +87,7 @@ func (r *Render) renderCompletion(buf *Buffer, words []string, chosen int) {
r.out.SetColor(White, Cyan)
for i := 0; i < l; i++ {
r.out.CursorDown(1)
if i == chosen {
if i == selected {
r.out.SetColor(r.selectedSuggestionTextColor, r.selectedSuggestionBGColor)
} else {
r.out.SetColor(r.suggestionTextColor, r.suggestionBGColor)
@ -114,15 +112,15 @@ func (r *Render) Erase(buffer *Buffer) {
return
}
func (r *Render) Render(buffer *Buffer, completions []string, chosen int) {
func (r *Render) Render(buffer *Buffer, completions []string, maxCompletions uint16, selected int) {
line := buffer.Document().CurrentLine()
r.out.SetColor(r.inputTextColor, r.inputBGColor)
r.out.WriteStr(line)
r.out.SetColor(DefaultColor, DefaultColor)
r.out.CursorBackward(len(line) - buffer.CursorPosition)
r.renderCompletion(buffer, completions, chosen)
if chosen != -1 {
c := completions[chosen]
r.renderCompletion(buffer, completions, maxCompletions, selected)
if selected != -1 {
c := completions[selected]
r.out.CursorBackward(len([]rune(buffer.Document().GetWordBeforeCursor())))
r.out.SetColor(r.previewSuggestionTextColor, r.previewSuggestionBGColor)
r.out.WriteStr(c)