Use functional option pattern
This commit is contained in:
parent
bfa943e55b
commit
6c7b45d7b8
7
main.go
7
main.go
|
@ -45,7 +45,12 @@ func completer(b *prompt.Buffer) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
pt := prompt.NewPrompt(executor, completer, 8)
|
pt := prompt.NewPrompt(
|
||||||
|
executor,
|
||||||
|
completer,
|
||||||
|
prompt.MaxCompletionsOption(8),
|
||||||
|
prompt.PrefixOption("> "),
|
||||||
|
)
|
||||||
defer fmt.Println("\nGoodbye!")
|
defer fmt.Println("\nGoodbye!")
|
||||||
fmt.Print("Hello! This is a example appication using prompt-toolkit.\n")
|
fmt.Print("Hello! This is a example appication using prompt-toolkit.\n")
|
||||||
pt.Run()
|
pt.Run()
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -1,6 +0,0 @@
|
||||||
package prompt
|
|
||||||
|
|
||||||
type WinSize struct {
|
|
||||||
Row uint16
|
|
||||||
Col uint16
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
}
|
|
@ -11,7 +11,7 @@ type Executor func(*Buffer) string
|
||||||
type Completer func(*Buffer) []string
|
type Completer func(*Buffer) []string
|
||||||
|
|
||||||
type Prompt struct {
|
type Prompt struct {
|
||||||
in *VT100Parser
|
in ConsoleParser
|
||||||
buf *Buffer
|
buf *Buffer
|
||||||
renderer *Render
|
renderer *Render
|
||||||
title string
|
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)
|
sigCh := make(chan os.Signal, 1)
|
||||||
signal.Notify(
|
signal.Notify(
|
||||||
sigCh,
|
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,9 +3,9 @@ package prompt
|
||||||
type Render struct {
|
type Render struct {
|
||||||
Prefix string
|
Prefix string
|
||||||
Title string
|
Title string
|
||||||
out *VT100Writer
|
out ConsoleWriter
|
||||||
row uint16
|
row uint16
|
||||||
col uint16 // sigwinchで送られてくる列数を常に見ながら、prefixのlengthとbufferのcursor positionを比べて、completionの表示位置をずらす
|
col uint16
|
||||||
maxCompletions uint16
|
maxCompletions uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue