Use functional option pattern

This commit is contained in:
c-bata 2017-07-16 17:20:58 +09:00
parent bfa943e55b
commit 6c7b45d7b8
6 changed files with 132 additions and 27 deletions

View File

@ -45,7 +45,12 @@ func completer(b *prompt.Buffer) []string {
}
func main() {
pt := prompt.NewPrompt(executor, completer, 8)
pt := prompt.NewPrompt(
executor,
completer,
prompt.MaxCompletionsOption(8),
prompt.PrefixOption("> "),
)
defer fmt.Println("\nGoodbye!")
fmt.Print("Hello! This is a example appication using prompt-toolkit.\n")
pt.Run()

View File

@ -0,0 +1,62 @@
package prompt
type WinSize struct {
Row uint16
Col uint16
}
type ConsoleParser interface {
// Setup
Setup() error
// TearDown
TearDown() error
// GetSCIICode returns ASCIICode correspond to input byte codes.
GetASCIICode(b []byte) *ASCIICode
// GetWinSize returns winsize struct which is the response of ioctl(2).
GetWinSize() *WinSize
}
type ConsoleWriter interface {
/* Write */
Write(data []byte)
WriteStr(data string)
WriteRaw(data []byte)
Flush() error
/* Erasing */
EraseScreen()
EraseUp()
EraseDown()
EraseStartOfLine()
EraseEndOfLine()
EraseLine()
/* Cursor */
ShowCursor()
HideCursor()
CursorGoTo(row, col int)
CursorUp(n int)
CursorDown(n int)
CursorForward(n int)
CursorBackward(n int)
AskForCPR()
SaveCursor()
UnSaveCursor()
/* Scrolling */
ScrollDown()
ScrollUp()
/* Title */
SetTitle(title string)
ClearTitle()
/* colors */
SetColor(fg, bg string) (ok bool)
}

View File

@ -1,6 +0,0 @@
package prompt
type WinSize struct {
Row uint16
Col uint16
}

60
prompt/option.go Normal file
View File

@ -0,0 +1,60 @@
package prompt
type option func(prompt *Prompt) error
func ParserOption(x ConsoleParser) option {
return func(p *Prompt) error {
p.in = x
return nil
}
}
func WriterOption(x ConsoleWriter) option {
return func(p *Prompt) error {
p.renderer.out = x
return nil
}
}
func TitleOption(x string) option {
return func(p *Prompt) error {
p.title = x
return nil
}
}
func PrefixOption(x string) option {
return func(p *Prompt) error {
p.renderer.Prefix = x
return nil
}
}
func MaxCompletionsOption(x uint16) option {
return func(p *Prompt) error {
p.renderer.maxCompletions = x
return nil
}
}
func NewPrompt(executor Executor, completer Completer, opts ...option) *Prompt {
pt := &Prompt{
in: NewVT100Parser(),
renderer: &Render{
Prefix: ">>> ",
out: NewVT100Writer(),
},
title: "Hello! this is prompt toolkit",
buf: NewBuffer(),
executor: executor,
completer: completer,
chosen: -1,
}
for _, opt := range opts {
if err := opt(pt); err != nil {
panic(err)
}
}
return pt
}

View File

@ -11,7 +11,7 @@ type Executor func(*Buffer) string
type Completer func(*Buffer) []string
type Prompt struct {
in *VT100Parser
in ConsoleParser
buf *Buffer
renderer *Render
title string
@ -110,7 +110,7 @@ func readBuffer(bufCh chan []byte) {
}
}
func handleSignals(in *VT100Parser, exitCh chan bool, winSizeCh chan *WinSize) {
func handleSignals(in ConsoleParser, exitCh chan bool, winSizeCh chan *WinSize) {
sigCh := make(chan os.Signal, 1)
signal.Notify(
sigCh,
@ -146,19 +146,3 @@ func handleSignals(in *VT100Parser, exitCh chan bool, winSizeCh chan *WinSize) {
}
}
}
func NewPrompt(executor Executor, completer Completer, maxCompletions uint16) *Prompt {
return &Prompt{
in: NewVT100Parser(),
renderer: &Render{
Prefix: ">>> ",
out: NewVT100Writer(),
maxCompletions: maxCompletions,
},
title: "Hello! this is prompt toolkit",
buf: NewBuffer(),
executor: executor,
completer: completer,
chosen: -1,
}
}

View File

@ -3,9 +3,9 @@ package prompt
type Render struct {
Prefix string
Title string
out *VT100Writer
out ConsoleWriter
row uint16
col uint16 // sigwinchで送られてくる列数を常に見ながら、prefixのlengthとbufferのcursor positionを比べて、completionの表示位置をずらす
col uint16
maxCompletions uint16
}