readline/example/readline-demo/readline-demo.go

169 lines
3.5 KiB
Go
Raw Normal View History

2015-09-20 18:14:29 +03:00
package main
import (
2015-11-20 15:56:42 +03:00
"fmt"
2015-09-20 18:14:29 +03:00
"io"
"io/ioutil"
2015-09-20 18:14:29 +03:00
"log"
"strconv"
2015-09-25 17:56:00 +03:00
"strings"
2015-09-20 18:14:29 +03:00
"time"
2022-12-12 16:55:00 +03:00
"git.internal/re/readline"
2015-09-20 18:14:29 +03:00
)
2015-09-21 17:27:40 +03:00
func usage(w io.Writer) {
2015-11-20 16:32:53 +03:00
io.WriteString(w, "commands:\n")
io.WriteString(w, completer.Tree(" "))
2015-09-21 17:27:40 +03:00
}
// Function constructor - constructs new function for listing given directory
func listFiles(path string) func(string) []string {
return func(line string) []string {
names := make([]string, 0)
files, _ := ioutil.ReadDir(path)
for _, f := range files {
names = append(names, f.Name())
}
return names
}
}
2015-09-25 19:31:09 +03:00
var completer = readline.NewPrefixCompleter(
2015-10-02 05:37:21 +03:00
readline.PcItem("mode",
readline.PcItem("vi"),
readline.PcItem("emacs"),
),
2015-09-30 09:16:46 +03:00
readline.PcItem("login"),
2015-09-25 19:31:09 +03:00
readline.PcItem("say",
readline.PcItemDynamic(listFiles("./"),
readline.PcItem("with",
readline.PcItem("following"),
readline.PcItem("items"),
),
),
2015-09-25 19:31:09 +03:00
readline.PcItem("hello"),
readline.PcItem("bye"),
),
2015-09-27 13:54:26 +03:00
readline.PcItem("setprompt"),
2015-11-20 15:56:42 +03:00
readline.PcItem("setpassword"),
2015-09-25 19:31:09 +03:00
readline.PcItem("bye"),
readline.PcItem("help"),
readline.PcItem("go",
2015-11-14 05:21:55 +03:00
readline.PcItem("build", readline.PcItem("-o"), readline.PcItem("-v")),
readline.PcItem("install",
readline.PcItem("-v"),
readline.PcItem("-vv"),
readline.PcItem("-vvv"),
),
2015-09-25 19:31:09 +03:00
readline.PcItem("test"),
),
readline.PcItem("sleep"),
2015-09-25 19:31:09 +03:00
)
2015-09-25 17:56:00 +03:00
func filterInput(r rune) (rune, bool) {
switch r {
// block CtrlZ feature
case readline.CharCtrlZ:
return r, false
}
return r, true
}
2015-09-20 18:14:29 +03:00
func main() {
2015-11-20 16:00:05 +03:00
l, err := readline.NewEx(&readline.Config{
Prompt: "\033[31m»\033[0m ",
HistoryFile: "/tmp/readline.tmp",
AutoComplete: completer,
2016-03-25 12:08:13 +03:00
InterruptPrompt: "^C",
EOFPrompt: "exit",
HistorySearchFold: true,
FuncFilterInputRune: filterInput,
2015-11-20 16:00:05 +03:00
})
2015-09-20 18:14:29 +03:00
if err != nil {
panic(err)
}
2015-09-21 08:30:10 +03:00
defer l.Close()
l.CaptureExitSignal()
2015-09-20 18:14:29 +03:00
2015-11-20 15:56:42 +03:00
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.Refresh()
return nil, 0, false
})
2015-09-20 18:14:29 +03:00
log.SetOutput(l.Stderr())
for {
line, err := l.Readline()
2016-03-25 12:08:13 +03:00
if err == readline.ErrInterrupt {
if len(line) == 0 {
break
} else {
continue
}
} else if err == io.EOF {
2015-09-20 18:14:29 +03:00
break
}
2016-03-25 12:08:13 +03:00
2015-10-02 05:37:21 +03:00
line = strings.TrimSpace(line)
2015-09-25 19:31:09 +03:00
switch {
2015-10-02 05:37:21 +03:00
case strings.HasPrefix(line, "mode "):
switch line[5:] {
case "vi":
l.SetVimMode(true)
case "emacs":
l.SetVimMode(false)
default:
println("invalid mode:", line[5:])
}
case line == "mode":
if l.IsVimMode() {
println("current mode: vim")
} else {
println("current mode: emacs")
}
2015-09-30 09:16:46 +03:00
case line == "login":
pswd, err := l.ReadPassword("please enter your password: ")
if err != nil {
break
}
println("you enter:", strconv.Quote(string(pswd)))
2015-09-25 19:31:09 +03:00
case line == "help":
2015-09-21 17:27:40 +03:00
usage(l.Stderr())
2015-11-20 15:56:42 +03:00
case line == "setpassword":
pswd, err := l.ReadPasswordWithConfig(setPasswordCfg)
if err == nil {
println("you set:", strconv.Quote(string(pswd)))
}
2015-09-27 13:54:26 +03:00
case strings.HasPrefix(line, "setprompt"):
if len(line) <= 10 {
2015-09-27 13:54:26 +03:00
log.Println("setprompt <prompt>")
break
}
l.SetPrompt(line[10:])
2015-09-25 19:31:09 +03:00
case strings.HasPrefix(line, "say"):
line := strings.TrimSpace(line[3:])
if len(line) == 0 {
log.Println("say what?")
break
}
2015-09-20 18:14:29 +03:00
go func() {
for range time.Tick(time.Second) {
2015-09-25 19:31:09 +03:00
log.Println(line)
2015-09-20 18:14:29 +03:00
}
}()
2015-09-25 19:31:09 +03:00
case line == "bye":
2015-09-20 18:14:29 +03:00
goto exit
case line == "sleep":
log.Println("sleep 4 second")
time.Sleep(4 * time.Second)
2015-09-25 19:31:09 +03:00
case line == "":
2015-09-20 18:14:29 +03:00
default:
log.Println("you said:", strconv.Quote(line))
}
}
exit:
}