Update Prompt type form string to fmt.Stringer.

On branch master
 Your branch is up to date with 'origin/master'.

 Changes to be committed:
	modified:   example/readline-demo/readline-demo.go
	modified:   example/readline-im/readline-im.go
	modified:   example/readline-multiline/readline-multiline.go
	modified:   example/readline-pass-strength/readline-pass-strength.go
	modified:   example/readline-remote/readline-remote-server/server.go
	modified:   operation.go
	new file:   prompt.go
	modified:   readline.go
	modified:   runebuf.go
	modified:   std.go
This commit is contained in:
luopengift 2018-10-13 23:42:23 +08:00
parent 2972be24d4
commit ee7dbdffca
10 changed files with 53 additions and 32 deletions

View File

@ -72,7 +72,7 @@ func filterInput(r rune) (rune, bool) {
func main() {
l, err := readline.NewEx(&readline.Config{
Prompt: "\033[31m»\033[0m ",
Prompt: readline.StaticPrompt("\033[31m»\033[0m "),
HistoryFile: "/tmp/readline.tmp",
AutoComplete: completer,
InterruptPrompt: "^C",
@ -88,7 +88,7 @@ func main() {
setPasswordCfg := l.GenPasswordConfig()
setPasswordCfg.SetListener(func(line []rune, pos int, key rune) (newLine []rune, newPos int, ok bool) {
l.SetPrompt(fmt.Sprintf("Enter password(%v): ", len(line)))
l.SetPrompt(readline.StaticPrompt(fmt.Sprintf("Enter password(%v): ", len(line))))
l.Refresh()
return nil, 0, false
})
@ -124,7 +124,7 @@ func main() {
println("current mode: emacs")
}
case line == "login":
pswd, err := l.ReadPassword("please enter your password: ")
pswd, err := l.ReadPassword(readline.StaticPrompt("please enter your password: "))
if err != nil {
break
}
@ -141,7 +141,7 @@ func main() {
log.Println("setprompt <prompt>")
break
}
l.SetPrompt(line[10:])
l.SetPrompt(readline.StaticPrompt(line[10:]))
case strings.HasPrefix(line, "say"):
line := strings.TrimSpace(line[3:])
if len(line) == 0 {

View File

@ -18,7 +18,7 @@ func main() {
}
defer rl.Close()
rl.SetPrompt("username: ")
rl.SetPrompt(readline.StaticPrompt("username: "))
username, err := rl.Readline()
if err != nil {
return
@ -27,7 +27,7 @@ func main() {
log.SetOutput(rl.Stderr())
fmt.Fprintln(rl, "Hi,", username+"! My name is Dave.")
rl.SetPrompt(username + "> ")
rl.SetPrompt(readline.StaticPrompt(username + "> "))
done := make(chan struct{})
go func() {

View File

@ -8,7 +8,7 @@ import (
func main() {
rl, err := readline.NewEx(&readline.Config{
Prompt: "> ",
Prompt: readline.StaticPrompt("> "),
HistoryFile: "/tmp/readline-multiline",
DisableAutoSaveHistory: true,
})
@ -29,12 +29,12 @@ func main() {
}
cmds = append(cmds, line)
if !strings.HasSuffix(line, ";") {
rl.SetPrompt(">>> ")
rl.SetPrompt(readline.StaticPrompt(">>> "))
continue
}
cmd := strings.Join(cmds, " ")
cmds = cmds[:0]
rl.SetPrompt("> ")
rl.SetPrompt(readline.StaticPrompt("> "))
rl.SaveHistory(cmd)
println(cmd)
}

View File

@ -80,7 +80,7 @@ func createStrengthPrompt(password []rune) string {
}
func main() {
rl, err := readline.New("")
rl, err := readline.New(readline.StaticPrompt(""))
if err != nil {
return
}
@ -88,7 +88,7 @@ func main() {
setPasswordCfg := rl.GenPasswordConfig()
setPasswordCfg.SetListener(func(line []rune, pos int, key rune) (newLine []rune, newPos int, ok bool) {
rl.SetPrompt(createStrengthPrompt(line))
rl.SetPrompt(readline.StaticPrompt(createStrengthPrompt(line)))
rl.Refresh()
return nil, 0, false
})

View File

@ -8,7 +8,7 @@ import (
func main() {
cfg := &readline.Config{
Prompt: "readline-remote: ",
Prompt: readline.StaticPrompt("readline-remote: "),
}
handleFunc := func(rl *readline.Instance) {
for {

View File

@ -2,6 +2,7 @@ package readline
import (
"errors"
"fmt"
"io"
"sync"
)
@ -89,7 +90,7 @@ func NewOperation(t *Terminal, cfg *Config) *Operation {
return op
}
func (o *Operation) SetPrompt(s string) {
func (o *Operation) SetPrompt(s fmt.Stringer) {
o.buf.SetPrompt(s)
}
@ -398,7 +399,7 @@ func (o *Operation) Runes() ([]rune, error) {
}
}
func (o *Operation) PasswordEx(prompt string, l Listener) ([]byte, error) {
func (o *Operation) PasswordEx(prompt fmt.Stringer, l Listener) ([]byte, error) {
cfg := o.GenPasswordConfig()
cfg.Prompt = prompt
cfg.Listener = l
@ -417,7 +418,7 @@ func (o *Operation) PasswordWithConfig(cfg *Config) ([]byte, error) {
return o.Slice()
}
func (o *Operation) Password(prompt string) ([]byte, error) {
func (o *Operation) Password(prompt fmt.Stringer) ([]byte, error) {
return o.PasswordEx(prompt, nil)
}

11
prompt.go Normal file
View File

@ -0,0 +1,11 @@
package readline
type StaticPrompt string
func (s StaticPrompt) String() string {
return string(s)
}
func NewStaticPrompt(s string) StaticPrompt {
return StaticPrompt(s)
}

View File

@ -17,7 +17,10 @@
//
package readline
import "io"
import (
"fmt"
"io"
)
type Instance struct {
Config *Config
@ -27,7 +30,7 @@ type Instance struct {
type Config struct {
// prompt supports ANSI escape sequence, so we can color some characters even in windows
Prompt string
Prompt fmt.Stringer
// readline will persist historys to file where HistoryFile specified
HistoryFile string
@ -175,7 +178,11 @@ func NewEx(cfg *Config) (*Instance, error) {
}, nil
}
func New(prompt string) (*Instance, error) {
type Prompter interface {
String() string
}
func New(prompt fmt.Stringer) (*Instance, error) {
return NewEx(&Config{Prompt: prompt})
}
@ -183,7 +190,7 @@ func (i *Instance) ResetHistory() {
i.Operation.ResetHistory()
}
func (i *Instance) SetPrompt(s string) {
func (i *Instance) SetPrompt(s fmt.Stringer) {
i.Operation.SetPrompt(s)
}
@ -224,11 +231,11 @@ func (i *Instance) ReadPasswordWithConfig(cfg *Config) ([]byte, error) {
return i.Operation.PasswordWithConfig(cfg)
}
func (i *Instance) ReadPasswordEx(prompt string, l Listener) ([]byte, error) {
func (i *Instance) ReadPasswordEx(prompt fmt.Stringer, l Listener) ([]byte, error) {
return i.Operation.PasswordEx(prompt, l)
}
func (i *Instance) ReadPassword(prompt string) ([]byte, error) {
func (i *Instance) ReadPassword(prompt fmt.Stringer) ([]byte, error) {
return i.Operation.Password(prompt)
}

View File

@ -3,6 +3,7 @@ package readline
import (
"bufio"
"bytes"
"fmt"
"io"
"strconv"
"strings"
@ -17,7 +18,7 @@ type runeBufferBck struct {
type RuneBuffer struct {
buf []rune
idx int
prompt []rune
prompt fmt.Stringer
w io.Writer
hadClean bool
@ -61,7 +62,7 @@ func (r *RuneBuffer) Restore() {
})
}
func NewRuneBuffer(w io.Writer, prompt string, cfg *Config, width int) *RuneBuffer {
func NewRuneBuffer(w io.Writer, prompt fmt.Stringer, cfg *Config, width int) *RuneBuffer {
rb := &RuneBuffer{
w: w,
interactive: cfg.useInteractive(),
@ -99,7 +100,7 @@ func (r *RuneBuffer) PromptLen() int {
}
func (r *RuneBuffer) promptLen() int {
return runes.WidthAll(runes.ColorFilter(r.prompt))
return runes.WidthAll(runes.ColorFilter([]rune(r.prompt.String())))
}
func (r *RuneBuffer) RuneSlice(i int) []rune {
@ -478,7 +479,7 @@ func (r *RuneBuffer) print() {
func (r *RuneBuffer) output() []byte {
buf := bytes.NewBuffer(nil)
buf.WriteString(string(r.prompt))
buf.WriteString(r.prompt.String())
if r.cfg.EnableMask && len(r.buf) > 0 {
buf.Write([]byte(strings.Repeat(string(r.cfg.MaskRune), len(r.buf)-1)))
if r.buf[len(r.buf)-1] == '\n' {
@ -582,9 +583,9 @@ func (r *RuneBuffer) Set(buf []rune) {
r.SetWithIdx(len(buf), buf)
}
func (r *RuneBuffer) SetPrompt(prompt string) {
func (r *RuneBuffer) SetPrompt(prompt fmt.Stringer) {
r.Lock()
r.prompt = []rune(prompt)
r.prompt = prompt //[]rune(prompt)
r.Unlock()
}

5
std.go
View File

@ -1,6 +1,7 @@
package readline
import (
"fmt"
"io"
"os"
"sync"
@ -54,13 +55,13 @@ func AddHistory(content string) error {
return ins.SaveHistory(content)
}
func Password(prompt string) ([]byte, error) {
func Password(prompt fmt.Stringer) ([]byte, error) {
ins := getInstance()
return ins.ReadPassword(prompt)
}
// readline with global configs
func Line(prompt string) (string, error) {
func Line(prompt fmt.Stringer) (string, error) {
ins := getInstance()
ins.SetPrompt(prompt)
return ins.Readline()