From e8a654ce0639e018473d7a43d95a7317e02baf82 Mon Sep 17 00:00:00 2001 From: c-bata Date: Sun, 16 Jul 2017 01:04:18 +0900 Subject: [PATCH] Consider terminal screen size --- main.go | 27 ++++++++++++++++++++++++++- prompt/prompt.go | 6 +++++- prompt/render.go | 23 +++++++++++++++++++---- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/main.go b/main.go index 79d8b43..f6ed561 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,32 @@ func completer(b *prompt.Buffer) []string { if w := b.Document().GetWordBeforeCursor(); w == "" { return []string{} } else { - return []string{"select", "from", "insert", "where"} + if []rune(w)[0] == []rune("s")[0] { + return []string{"select"} + } else if []rune(w)[0] == []rune("w")[0] { + return []string{"where"} + } else if []rune(w)[0] == []rune("d")[0] { + return []string{"drop", "delete"} + } else if []rune(w)[0] == []rune("f")[0] { + return []string{"from"} + } + } + return []string{ + "select", + "select", + "select", + "select", + "select", + "select", + "select", + "select", + "select", + "select", + "select", + "select", + "select", + "select", + "select", } } diff --git a/prompt/prompt.go b/prompt/prompt.go index b2e485b..490cf97 100644 --- a/prompt/prompt.go +++ b/prompt/prompt.go @@ -76,6 +76,9 @@ func (p *Prompt) Run() { p.renderer.Render(p.buf, completions, p.chosen) 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) case e := <-exitCh: if e { return @@ -89,6 +92,7 @@ func (p *Prompt) Run() { func (p *Prompt) setUp() { p.in.Setup() p.renderer.Setup() + p.renderer.UpdateWinSize(p.in.GetWinSize()) } func (p *Prompt) tearDown() { @@ -143,7 +147,7 @@ func handleSignals(in *VT100Parser, exitCh chan bool, winSizeCh chan *WinSize) { } } -func NewPrompt(executor Executor, completer Completer, maxCompletions uint8) *Prompt { +func NewPrompt(executor Executor, completer Completer, maxCompletions uint16) *Prompt { return &Prompt{ in: NewVT100Parser(), renderer: &Render{ diff --git a/prompt/render.go b/prompt/render.go index f9e808b..206fb7d 100644 --- a/prompt/render.go +++ b/prompt/render.go @@ -6,7 +6,7 @@ type Render struct { out *VT100Writer row uint16 col uint16 // sigwinchで送られてくる列数を常に見ながら、prefixのlengthとbufferのcursor positionを比べて、completionの表示位置をずらす - maxCompletions uint8 + maxCompletions uint16 } func (r *Render) Setup() { @@ -39,14 +39,26 @@ func (r *Render) UpdateWinSize(ws *WinSize) { return } -func (r *Render) RenderCompletion(words []string, chosen int) { - if len(words) == 0 { +func (r *Render) renderCompletion(buf *Buffer, words []string, chosen int) { + if l := len(words); l == 0 { return + } else if l > int(r.maxCompletions) - 2 || l >= int(r.row) - 2 { + if r.maxCompletions > r.row { + words = words[:int(r.row) - 2] + } else { + words = words[:int(r.maxCompletions) - 2] + } } + formatted, width := formatCompletions(words) l := len(formatted) r.prepareArea(l) + d := (len(r.Prefix) + len(buf.Document().TextBeforeCursor())) % int(r.col) + if d + width + 3 > int(r.col) { + r.out.CursorBackward(d + width + 3 - int(r.col)) + } + r.out.SetColor("white", "teal") for i := 0; i < l; i++ { r.out.CursorDown(1) @@ -60,6 +72,9 @@ func (r *Render) RenderCompletion(words []string, chosen int) { r.out.Write([]byte(" ")) r.out.CursorBackward(width + 3) } + if d + width + 3 > int(r.col) { + r.out.CursorForward(d + width + 3 - int(r.col)) + } r.out.CursorUp(l) r.out.SetColor("default", "default") @@ -79,7 +94,7 @@ 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, chosen) + r.renderCompletion(buffer, completions, chosen) if chosen != -1 { c := completions[chosen] r.out.CursorBackward(len([]rune(buffer.Document().GetWordBeforeCursor())))