diff --git a/main.go b/main.go index 82a9444..79d8b43 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,7 @@ import ( ) func executor(b *prompt.Buffer) string { - r := "\n>>> Your input: '" + b.Text() + "' <<<\n" + r := "Your input: " + b.Text() return r } @@ -20,8 +20,8 @@ func completer(b *prompt.Buffer) []string { } func main() { - pt := prompt.NewPrompt(executor, completer) + pt := prompt.NewPrompt(executor, completer, 8) defer fmt.Println("\nGoodbye!") - fmt.Print("Hello! This is a example appication using prompt-toolkit.\n\n") + fmt.Print("Hello! This is a example appication using prompt-toolkit.\n") pt.Run() } diff --git a/prompt/completions.go b/prompt/completions.go index 0c4f39f..049e6d5 100644 --- a/prompt/completions.go +++ b/prompt/completions.go @@ -2,7 +2,7 @@ package prompt type Completion struct { // The new string that will be inserted into document. - text string + text string // Position relative to the cursor position where the new text will start. startPosition int } @@ -13,7 +13,7 @@ func (c *Completion) NewCompletionFromPosition(position int) *Completion { } return &Completion{ - text: c.text[position - c.startPosition:], + text: c.text[position-c.startPosition:], } } diff --git a/prompt/document_test.go b/prompt/document_test.go index 635a610..92ec82f 100644 --- a/prompt/document_test.go +++ b/prompt/document_test.go @@ -31,10 +31,10 @@ func TestDocument_TextBeforeCursor(t *testing.T) { } func TestDocument_TextAfterCursor(t *testing.T) { - pattern := []struct{ + pattern := []struct { document *Document expected string - } { + }{ { document: &Document{ Text: "line 1\nline 2\nline 3\nline 4\n", @@ -60,10 +60,10 @@ func TestDocument_TextAfterCursor(t *testing.T) { } func TestDocument_GetWordBeforeCursor(t *testing.T) { - pattern := []struct{ + pattern := []struct { document *Document expected string - } { + }{ { document: &Document{ Text: "apple bana", @@ -89,10 +89,10 @@ func TestDocument_GetWordBeforeCursor(t *testing.T) { } func TestDocument_FindStartOfPreviousWord(t *testing.T) { - pattern := []struct{ + pattern := []struct { document *Document expected int - } { + }{ { document: &Document{ Text: "apple bana", diff --git a/prompt/prompt.go b/prompt/prompt.go index 41c9af9..0b9c3a2 100644 --- a/prompt/prompt.go +++ b/prompt/prompt.go @@ -1,9 +1,9 @@ package prompt import ( - "syscall" "os" "os/signal" + "syscall" "time" ) @@ -23,7 +23,6 @@ func (p *Prompt) Run() { p.setUp() defer p.tearDown() - bufCh := make(chan []byte, 128) go readBuffer(bufCh) @@ -33,7 +32,7 @@ func (p *Prompt) Run() { for { select { - case b := <- bufCh: + case b := <-bufCh: p.renderer.Erase(p.buf) ac := p.in.GetASCIICode(b) if ac == nil { @@ -42,7 +41,7 @@ func (p *Prompt) Run() { res := p.executor(p.buf) p.renderer.BreakLine(p.buf, res) p.buf = NewBuffer() - } else if ac.Key == ControlC { + } else if ac.Key == ControlC || ac.Key == ControlD { return } else { InputHandler(ac, p.buf) @@ -50,9 +49,9 @@ func (p *Prompt) Run() { completions := p.completer(p.buf) p.renderer.Render(p.buf, completions) - case w := <- winSizeCh: + case w := <-winSizeCh: p.renderer.UpdateWinSize(w) - case e := <- exitCh: + case e := <-exitCh: if e { return } @@ -119,16 +118,17 @@ func handleSignals(in *VT100Parser, exitCh chan bool, winSizeCh chan *WinSize) { } } -func NewPrompt(executor Executor, completer Completer) *Prompt { +func NewPrompt(executor Executor, completer Completer, maxCompletions uint8) *Prompt { return &Prompt{ in: NewVT100Parser(), renderer: &Render{ - Prefix: ">>> ", - out: NewVT100Writer(), + Prefix: ">>> ", + out: NewVT100Writer(), + maxCompletions: maxCompletions, }, - title: "Hello! this is prompt toolkit", - buf: NewBuffer(), - executor: executor, + title: "Hello! this is prompt toolkit", + buf: NewBuffer(), + executor: executor, completer: completer, } } diff --git a/prompt/render.go b/prompt/render.go index 996f780..f33f7ed 100644 --- a/prompt/render.go +++ b/prompt/render.go @@ -1,20 +1,21 @@ package prompt - type Render struct { - Prefix string - Title string - out *VT100Writer - row uint16 - col uint16 // sigwinchで送られてくる列数を常に見ながら、prefixのlengthとbufferのcursor positionを比べて、completionの表示位置をずらす - chosen uint8 // the index number of a chosen completion + Prefix string + Title string + out *VT100Writer + row uint16 + col uint16 // sigwinchで送られてくる列数を常に見ながら、prefixのlengthとbufferのcursor positionを比べて、completionの表示位置をずらす + chosen uint8 // the index number of a chosen completion + maxCompletions uint8 } func (r *Render) Setup() { if r.Title != "" { r.out.SetTitle(r.Title) - r.out.Flush() } + r.out.WriteStr(r.Prefix) + r.out.Flush() } func (r *Render) TearDown() { @@ -63,8 +64,11 @@ func (r *Render) RenderCompletion(words []string) { } func (r *Render) Erase(buffer *Buffer) { + r.out.CursorBackward(len(r.Prefix)) r.out.CursorBackward(buffer.CursorPosition) r.out.EraseDown() + r.out.WriteStr(r.Prefix) + r.out.Flush() return } @@ -78,7 +82,10 @@ func (r *Render) Render(buffer *Buffer, completions []string) { func (r *Render) BreakLine(buffer *Buffer, result string) { r.out.WriteStr(buffer.Document().Text) + r.out.WriteStr("\n") r.out.WriteStr(result) + r.out.WriteStr("\n") + r.out.WriteStr(r.Prefix) } func formatCompletions(words []string) ([]string, int) { diff --git a/prompt/render_test.go b/prompt/render_test.go index c581c70..6831378 100644 --- a/prompt/render_test.go +++ b/prompt/render_test.go @@ -1,12 +1,12 @@ package prompt import ( - "testing" "reflect" + "testing" ) func TestFormatCompletion(t *testing.T) { - in := []string { + in := []string{ "select", "from", "insert",