diff --git a/prompt/prompt.go b/prompt/prompt.go index 0b9c3a2..3e985b6 100644 --- a/prompt/prompt.go +++ b/prompt/prompt.go @@ -17,6 +17,7 @@ type Prompt struct { title string executor Executor completer Completer + chosen int } func (p *Prompt) Run() { @@ -41,14 +42,25 @@ func (p *Prompt) Run() { res := p.executor(p.buf) p.renderer.BreakLine(p.buf, res) p.buf = NewBuffer() + p.chosen = -1 } else if ac.Key == ControlC || ac.Key == ControlD { return + } else if ac.Key == BackTab || ac.Key == Up { + p.chosen -= 1 + } else if ac.Key == Tab || ac.Key == ControlI || ac.Key == Down { + p.chosen += 1 } else { InputHandler(ac, p.buf) + p.chosen = -1 } completions := p.completer(p.buf) - p.renderer.Render(p.buf, completions) + 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) case w := <-winSizeCh: p.renderer.UpdateWinSize(w) case e := <-exitCh: @@ -130,5 +142,6 @@ func NewPrompt(executor Executor, completer Completer, maxCompletions uint8) *Pr buf: NewBuffer(), executor: executor, completer: completer, + chosen: -1, } } diff --git a/prompt/render.go b/prompt/render.go index 84518b3..9631f23 100644 --- a/prompt/render.go +++ b/prompt/render.go @@ -6,7 +6,6 @@ type Render struct { out *VT100Writer row uint16 col uint16 // sigwinchで送られてくる列数を常に見ながら、prefixのlengthとbufferのcursor positionを比べて、completionの表示位置をずらす - chosen uint8 // the index number of a chosen completion maxCompletions uint8 } @@ -40,7 +39,7 @@ func (r *Render) UpdateWinSize(ws *WinSize) { return } -func (r *Render) RenderCompletion(words []string) { +func (r *Render) RenderCompletion(words []string, chosen int) { if len(words) == 0 { return } @@ -51,7 +50,7 @@ func (r *Render) RenderCompletion(words []string) { r.out.SetColor("white", "teal") for i := 0; i < l; i++ { r.out.CursorDown(1) - if i == int(r.chosen) { + if i == chosen { r.out.SetColor("white", "turquoise") } else { r.out.SetColor("black", "cyan") @@ -76,11 +75,11 @@ func (r *Render) Erase(buffer *Buffer) { return } -func (r *Render) Render(buffer *Buffer, completions []string) { +func (r *Render) Render(buffer *Buffer, completions []string, chosen int) { line := buffer.Document().CurrentLine() r.out.WriteStr(line) r.out.CursorBackward(len(line) - buffer.CursorPosition) - r.RenderCompletion(completions) + r.RenderCompletion(completions, chosen) r.out.Flush() }