diff --git a/main.go b/main.go index a2095d6..0c506d8 100644 --- a/main.go +++ b/main.go @@ -12,11 +12,12 @@ func executor(b *prompt.Buffer) string { } func completer(b *prompt.Buffer) []string { - return []string{"foo", "bar", "baz"} + return []string{"select", "from", "insert", "where"} } func main() { - pt := prompt.NewPrompt(executor) + pt := prompt.NewPrompt(executor, completer) defer fmt.Println("\nGoodbye!") + fmt.Print("Hello! This is a example appication using prompt-toolkit.\n\n") pt.Run() } diff --git a/prompt/prompt.go b/prompt/prompt.go index 5da08bc..c0e3b7b 100644 --- a/prompt/prompt.go +++ b/prompt/prompt.go @@ -8,14 +8,16 @@ import ( ) type Executor func(*Buffer) string +type Completer func(*Buffer) []string type Prompt struct { - in *VT100Parser - out *VT100Writer - buf *Buffer - renderer *Render - title string - executor Executor + in *VT100Parser + out *VT100Writer + buf *Buffer + renderer *Render + title string + executor Executor + completer Completer } func (p *Prompt) Run() { @@ -54,7 +56,8 @@ func (p *Prompt) Run() { // Display completions if w := p.buf.Document().GetWordBeforeCursor(); w != "" { - p.renderer.RenderCompletion([]string{}) + completions := p.completer(p.buf) + p.renderer.RenderCompletion(completions) } completions := []string{"select", "insert", "update", "where"} @@ -133,7 +136,7 @@ func handleSignals(in *VT100Parser, exitCh chan bool, winSizeCh chan *WinSize) { } } -func NewPrompt(executor Executor) *Prompt { +func NewPrompt(executor Executor, completer Completer) *Prompt { out := NewVT100Writer() return &Prompt{ in: NewVT100Parser(), @@ -145,5 +148,6 @@ func NewPrompt(executor Executor) *Prompt { title: "Hello! this is prompt toolkit", buf: NewBuffer(), executor: executor, + completer: completer, } } diff --git a/prompt/render.go b/prompt/render.go index a04bf25..6a11921 100644 --- a/prompt/render.go +++ b/prompt/render.go @@ -24,42 +24,44 @@ func (r *Render) UpdateWinSize(ws *WinSize) { } func (r *Render) RenderCompletion(words []string) { - r.PrepareArea(4) - r.out.SetColor("white", "teal") + formatted, width := formatCompletions(words) + l := len(formatted) + r.PrepareArea(l) - r.out.CursorDown(1) - r.out.Write([]byte(" select ")) - r.out.SetColor("white", "darkGray") - r.out.Write([]byte(" ")) r.out.SetColor("white", "teal") - r.out.CursorBackward(len("select") + 3) + for i := 0; i < l; i++ { + r.out.CursorDown(1) + r.out.WriteStr(" " + formatted[i] + " ") + r.out.SetColor("white", "darkGray") + r.out.Write([]byte(" ")) + r.out.SetColor("white", "teal") + r.out.CursorBackward(width + 3) + } - r.out.CursorDown(1) - r.out.Write([]byte(" insert ")) - r.out.SetColor("white", "darkGray") - r.out.Write([]byte(" ")) - r.out.SetColor("white", "teal") - r.out.CursorBackward(len("insert") + 3) - - r.out.CursorDown(1) - r.out.Write([]byte(" update ")) - r.out.SetColor("white", "darkGray") - r.out.Write([]byte(" ")) - r.out.SetColor("white", "teal") - r.out.CursorBackward(len("update") + 3) - - r.out.CursorDown(1) - r.out.Write([]byte(" where ")) - r.out.SetColor("white", "darkGray") - r.out.Write([]byte(" ")) - r.out.SetColor("white", "teal") - r.out.CursorBackward(len("where ") + 3) - - r.out.CursorUp(4) + r.out.CursorUp(l) r.out.SetColor("default", "default") return } +func formatCompletions(words []string) ([]string, int) { + num := len(words) + width := 0 + + for i := 0; i < num; i++ { + if width < len([]rune(words[i])) { + width = len([]rune(words[i])) + } + } + + for i := 0; i < num; i++ { + spaces := width - len([]rune(words[i])) + for j := 0; j < spaces; j++ { + words[i] += " " + } + } + return words, width +} + func (r *Render) Render(buffer *Buffer, completions []string) { r.out.Flush() } diff --git a/prompt/render_test.go b/prompt/render_test.go new file mode 100644 index 0000000..c581c70 --- /dev/null +++ b/prompt/render_test.go @@ -0,0 +1,29 @@ +package prompt + +import ( + "testing" + "reflect" +) + +func TestFormatCompletion(t *testing.T) { + in := []string { + "select", + "from", + "insert", + "where", + } + ex := []string{ + "select", + "from ", + "insert", + "where ", + } + + ac, width := formatCompletions(in) + if !reflect.DeepEqual(ac, ex) { + t.Errorf("Should be %#v, but got %#v", ex, ac) + } + if width != 6 { + t.Errorf("Should be %#v, but got %#v", 4, width) + } +}