func (a *App) internalRun() error { if a.commandTitle == "" { a.commandTitle = ">" } var historyFile string usr, err := user.Current() // Only load history if we can get the user if err == nil { historyFile = filepath.Join(usr.HomeDir, ".command_history") } l, err := readline.NewEx(&readline.Config{ Prompt: a.commandTitle, HistoryFile: historyFile, AutoComplete: readline.NewPrefixCompleter(a.completeOptions...), }) if err != nil { return err } a.line = l log.SetOutput(l.Stderr()) for { l, e := a.line.Readline() if e != nil { return e } if !a.parseCommand(l) { break // exit main loop } } return nil }
func main() { rl, err := readline.NewEx(&readline.Config{ Prompt: "> ", HistoryFile: "/tmp/readline-multiline", DisableAutoSaveHistory: true, }) if err != nil { panic(err) } defer rl.Close() var cmds []string for { line, err := rl.Readline() if err != nil { break } line = strings.TrimSpace(line) if len(line) == 0 { continue } cmds = append(cmds, line) if !strings.Contains(line, ";") { rl.SetPrompt(">>> ") continue } cmd := strings.Join(cmds, " ") cmds = cmds[:0] rl.SetPrompt("> ") rl.SaveHistory(cmd) println(cmd) } }
func main() { l, err := readline.NewEx(&readline.Config{ Prompt: "\033[31m»\033[0m ", HistoryFile: "/tmp/readline.tmp", }) if err != nil { panic(err) } defer l.Close() log.SetOutput(l.Stderr()) for { line, err := l.Readline() if err != nil { break } switch line { case "help": usage(l.Stderr()) case "sayhello": go func() { for _ = range time.Tick(time.Second) { log.Println("hello") } }() case "bye": goto exit case "": default: log.Println("you said:", strconv.Quote(line)) } } exit: }
// runInteractive runs the SQL client interactively, presenting // a prompt to the user for each statement. func runInteractive(conn *sqlConn, config *readline.Config) (exitErr error) { c := cliState{conn: conn} state := cliStart for { if state == cliStop { break } switch state { case cliStart: // The readline initialization is not placed in // the doStart() method because of the defer. c.ins, c.exitErr = readline.NewEx(config) if c.exitErr != nil { return c.exitErr } defer func() { _ = c.ins.Close() }() state = c.doStart(cliQuerySyntax) case cliQuerySyntax: state = c.doQuerySyntax(cliStartLine) case cliStartLine: state = c.doStartLine(cliReadLine) case cliContinueLine: state = c.doContinueLine(cliReadLine) case cliReadLine: state = c.doReadLine(cliDecidePath) case cliDecidePath: state = c.doDecidePath() case cliProcessFirstLine: state = c.doProcessFirstLine(cliReadLine, cliHandleCliCmd) case cliHandleCliCmd: state = c.doHandleCliCmd(cliReadLine, cliPrepareStatementLine) case cliPrepareStatementLine: state = c.doPrepareStatementLine( cliStartLine, cliContinueLine, cliCheckStatement, cliRunStatement, ) case cliCheckStatement: state = c.doCheckStatement(cliStartLine, cliContinueLine, cliRunStatement) case cliRunStatement: state = c.doRunStatement(cliQuerySyntax) default: panic(fmt.Sprintf("unknown state: %d", state)) } } return c.exitErr }
func (app *App) Interactive() { rl, err := readline.NewEx(&readline.Config{ Prompt: color.BlueString("say » "), HistoryFile: app.Config.HistoryFile, }) if err != nil { log.Fatal(err) } defer rl.Close() app.Log.SetOutput(rl.Stderr()) log.SetOutput(rl.Stderr()) color.Output = ansicolor.NewAnsiColorWriter(rl.Stderr()) pings := make(map[string]time.Time) // Subscribe to all replies and print them to stdout app.Client.Subscribe("", "self", func(msg sarif.Message) { text := msg.Text if text == "" { text = msg.Action + " from " + msg.Source } if msg.IsAction("err") { text = color.RedString(text) } if sent, ok := pings[msg.CorrId]; ok { text += color.YellowString("[%.1fms]", time.Since(sent).Seconds()*1e3) } log.Println(color.GreenString(" « ") + strings.Replace(text, "\n", "\n ", -1)) }) // Interactive mode sends all lines from stdin. for { line, err := rl.Readline() if err != nil { if err == io.EOF { return } log.Fatal(err) } if len(line) == 0 { continue } // Publish natural message msg := sarif.Message{ Id: sarif.GenerateId(), Action: "natural/handle", Text: line, } if *profile { pings[msg.Id] = time.Now() } app.Client.Publish(msg) } }
// GetInput input terminal func GetInput(addr string) (string, error) { prpt := fmt.Sprintf("(%s) > ", addr) rl, err := readline.NewEx(&readline.Config{Prompt: prpt, HistoryFile: "/tmp/mem_cli_history.tmp"}) defer rl.Close() if err != nil { return "", err } line, _ := rl.Readline() return line, nil }
func main() { //Initialize Config GetConfig() CheckState() Clear() Msg(HeaderMsg, "discord-cli - version: %s\n\n", Version) //NewSession Session = DiscordState.NewSession(Config.Username, Config.Password) //Please don't abuse err := Session.Start() if err != nil { log.Println("Session Failed") log.Fatalln(err) } //Attach New Window InitWindow() //Attach Even Handlers State.Session.DiscordGo.AddHandler(newMessage) //Setup Readline rl, err := readline.NewEx(&readline.Config{ Prompt: "> ", UniqueEditLine: true, }) defer rl.Close() log.SetOutput(rl.Stderr()) // let "log" write to l.Stderr instead of os.Stderr //Start Listening for { line, _ := rl.Readline() //QUIT if line == ":q" { break } //Parse Commands line = ParseForCommands(line) line = ParseForMentions(line) if line != "" { State.Session.DiscordGo.ChannelMessageSend(State.Channel.ID, line) } } return }
func main() { rl, err := readline.NewEx(&readline.Config{ UniqueEditLine: true, }) if err != nil { panic(err) } defer rl.Close() rl.SetPrompt("username: "******"Hi,", username+"! My name is Dave.") rl.SetPrompt(username + "> ") done := make(chan struct{}) go func() { rand.Seed(time.Now().Unix()) loop: for { select { case <-time.After(time.Duration(rand.Intn(20)) * 100 * time.Millisecond): case <-done: break loop } log.Println("Dave:", "hello") } log.Println("Dave:", "bye") done <- struct{}{} }() for { ln := rl.Line() if ln.CanContinue() { continue } else if ln.CanBreak() { break } log.Println(username+":", ln.Line) } rl.Clean() done <- struct{}{} <-done }
func startLocal() { rl, err := readline.NewEx( &readline.Config{ Prompt: "> ", }, ) if err != nil { panic(err) } g := NewLocalGame(rl) g.play() }
func main() { l, err := readline.NewEx(&readline.Config{ Prompt: "\033[31m»\033[0m ", HistoryFile: "/tmp/readline.tmp", AutoComplete: completer, }) if err != nil { panic(err) } defer l.Close() log.SetOutput(l.Stderr()) for { line, err := l.Readline() if err != nil { break } switch { case line == "help": usage(l.Stderr()) case strings.HasPrefix(line, "setprompt"): prompt := line[10:] if prompt == "" { log.Println("setprompt <prompt>") break } l.SetPrompt(prompt) case strings.HasPrefix(line, "say"): line := strings.TrimSpace(line[3:]) if len(line) == 0 { log.Println("say what?") break } go func() { for _ = range time.Tick(time.Second) { log.Println(line) } }() case line == "bye": goto exit case line == "": default: log.Println("you said:", strconv.Quote(line)) } } exit: }
// NewShell creates a new shell with default settings. Uses standard output and default prompt ">>". func NewShell(completer *readline.PrefixCompleter) *Shell { shell := &Shell{ prompt: defaultPrompt, showPrompt: true, functions: make(map[string]CmdFunc), reader: &shellReader{ scanner: bufio.NewReader(os.Stdin), }, writer: os.Stdout, haltChan: make(chan struct{}), } rl, err := readline.NewEx(&readline.Config{Prompt: shell.prompt, AutoComplete: completer}) if err != nil { panic(err) } shell.rl = rl addDefaultFuncs(shell) return shell }
func (c *ConsoleCommand) modeInteractive(session *repl.Session, ui cli.Ui) int { // Configure input l, err := readline.NewEx(wrappedreadline.Override(&readline.Config{ Prompt: "> ", InterruptPrompt: "^C", EOFPrompt: "exit", HistorySearchFold: true, })) if err != nil { c.Ui.Error(fmt.Sprintf( "Error initializing console: %s", err)) return 1 } defer l.Close() for { // Read a line line, err := l.Readline() if err == readline.ErrInterrupt { if len(line) == 0 { break } else { continue } } else if err == io.EOF { break } out, err := session.Handle(line) if err == repl.ErrSessionExit { break } if err != nil { ui.Error(err.Error()) continue } ui.Output(out) } return 0 }
func main() { rl, err := readline.NewEx(&readline.Config{ Prompt: "> ", HistoryFile: "/tmp/flagly-shell.readline", }) if err != nil { println(err.Error()) os.Exit(1) } defer rl.Close() var p Program fset, err := flagly.Compile("", &p) if err != nil { println(err.Error()) os.Exit(1) } rl.Config.AutoComplete = &readline.SegmentComplete{fset.Completer()} for { line, err := rl.Readline() if err != nil { break } if line == "" { continue } command, err := shlex.Split(line) if err != nil { println("error: " + err.Error()) continue } if err := fset.Run(command); err != nil { println(err.Error()) } } }
func main() { l, err := readline.NewEx(&readline.Config{ Prompt: "\033[31m»\033[0m ", HistoryFile: "/tmp/readline.tmp", AutoComplete: completer, InterruptPrompt: "^C", EOFPrompt: "exit", HistorySearchFold: true, }) if err != nil { panic(err) } defer l.Close() 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 }) log.SetOutput(l.Stderr()) for { line, err := l.Readline() if err == readline.ErrInterrupt { if len(line) == 0 { break } else { continue } } else if err == io.EOF { break } line = strings.TrimSpace(line) switch { 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") } case line == "login": pswd, err := l.ReadPassword("please enter your password: "******"you enter:", strconv.Quote(string(pswd))) case line == "help": usage(l.Stderr()) case line == "setpassword": pswd, err := l.ReadPasswordWithConfig(setPasswordCfg) if err == nil { println("you set:", strconv.Quote(string(pswd))) } case strings.HasPrefix(line, "setprompt"): if len(line) <= 10 { log.Println("setprompt <prompt>") break } l.SetPrompt(line[10:]) case strings.HasPrefix(line, "say"): line := strings.TrimSpace(line[3:]) if len(line) == 0 { log.Println("say what?") break } go func() { for range time.Tick(time.Second) { log.Println(line) } }() case line == "bye": goto exit case line == "sleep": log.Println("sleep 4 second") time.Sleep(4 * time.Second) case line == "": default: log.Println("you said:", strconv.Quote(line)) } } exit: }
func main() { kingpin.Parse() var conn net.Conn var err error if *rawtls { conn, err = tls.Dial("tcp", *address, &tls.Config{ InsecureSkipVerify: true, }) if err != nil { fmt.Fprintf(os.Stderr, "Connect failed: %v\n", err) return } } else { conn, err = net.Dial("tcp", *address) if err != nil { fmt.Fprintf(os.Stderr, "Connect failed: %v\n", err) return } } c := client.New(conn) go func() { err := c.Serve() if err != nil { fmt.Fprintf(os.Stderr, "\nConnection lost: %v\n", err) os.Exit(-1) } }() _, _, err = c.Version(1024*1024, qp.Version) if err != nil { fmt.Fprintf(os.Stderr, "Version failed: %v\n", err) return } root, _, err := c.Attach(nil, *user, *service) if err != nil { fmt.Fprintf(os.Stderr, "Attach failed: %v\n", err) return } cwd := root confirmation, err = readline.New("") if err != nil { fmt.Fprintf(os.Stderr, "Could not make confirmation readline instance: %v\n", err) return } if len(*command) > 0 { args := "" for i := 1; i < len(*command); i++ { if i != 1 { args += " " } args += (*command)[i] } f, ok := cmds[(*command)[0]] if !ok { fmt.Fprintf(os.Stderr, "no such command: [%s]\n", *command) return } cwd, err = f(root, cwd, args) if err != nil { fmt.Fprintf(os.Stderr, "\ncommand %s failed: %v\n", *command, err) } return } completer := readline.NewPrefixCompleter() for k := range cmds { completer.Children = append(completer.Children, readline.PcItem(k)) } rl, err := readline.NewEx(&readline.Config{ Prompt: "9p> ", AutoComplete: completer, }) if err != nil { fmt.Fprintf(os.Stderr, "failed to create readline: %v\n", err) return } defer rl.Close() fmt.Fprintf(os.Stderr, "Welcome to the qptools 9P cli.\nPress tab to see available commands.\n") for { line, err := rl.Readline() if err != nil { // io.EOF break } idx := strings.Index(line, " ") var cmd, args string if idx != -1 { cmd = line[:idx] args = line[idx+1:] } else { cmd = line } f, ok := cmds[cmd] if !ok { fmt.Fprintf(os.Stderr, "no such command: [%s]\n", cmd) continue } cwd, err = f(root, cwd, args) if err != nil { fmt.Fprintf(os.Stderr, "\ncommand %s failed: %v\n", cmd, err) } } }
func main() { app := cli.NewApp() app.Name = "nats-repl" app.Usage = "REPL for NATS" app.Flags = []cli.Flag{ cli.StringFlag{ Name: "server, s", EnvVar: "NATS_DEFAULT_URL", Usage: "NATS `URL` to connect to", }, } app.Action = func(ctx *cli.Context) error { nc, err := nats.Connect(ctx.String("server")) if err != nil { logError(fmt.Sprintf("%v", err)) os.Exit(1) } logInfo(fmt.Sprintf("connected to %s", ctx.String("server"))) rl, err := readline.NewEx(&readline.Config{ Prompt: colorize("1;37", "nats> "), HistoryFile: "/tmp/nats-repl-history.tmp", InterruptPrompt: "^C", EOFPrompt: "exit", }) if err != nil { panic(err) } defer rl.Close() repl: for { line, err := rl.Readline() switch err { case readline.ErrInterrupt: if len(line) == 0 { break repl } else { continue repl } case io.EOF: break repl } args := strings.Fields(line) switch { case len(args) == 0: continue repl case args[0] == "pub": var subject string if len(args) >= 2 { subject = args[1] } else { logError("subject is required") continue repl } var data string if len(args) >= 3 { data = strings.Join(args[2:], " ") } else { data = "" } nc.Publish(subject, []byte(data)) case args[0] == "sub": sigch := make(chan os.Signal, 1) signal.Notify(sigch, os.Interrupt) var subject string if len(args) >= 2 { subject = args[1] } else { logError("subject is required") continue repl } subch := make(chan *nats.Msg, 64) sub, _ := nc.ChanSubscribe(subject, subch) sub: for { select { case msg := <-subch: fmt.Printf("[%s] %s\n", msg.Subject, string(msg.Data)) case <-sigch: fmt.Println() break sub } } close(sigch) close(subch) signal.Reset(os.Interrupt) sub.Unsubscribe() case args[0] == "req": var subject string if len(args) >= 2 { subject = args[1] } else { logError("subject is required") continue repl } var data string if len(args) >= 3 { data = strings.Join(args[2:], " ") } else { data = "" } msg, err := nc.Request(subject, []byte(data), 5000*time.Millisecond) if err != nil { logError(fmt.Sprintf("%v", err)) break } fmt.Println(string(msg.Data)) case args[0] == "help": logInfo("COMMANDS:") logInfo("pub <subject> [data]") logInfo("sub <subject>") logInfo("req <subject> [data]") case args[0] == "exit": break repl default: logError(fmt.Sprintf("unknown command: %s", args[0])) } } return nil } app.Run(os.Args) }
func main() { log.SetLevel(log.WarnLevel) log.SetOutput(os.Stderr) l, err := readline.NewEx(&readline.Config{ Prompt: "\033[31m»\033[0m ", HistoryFile: "/tmp/sjdb-readline.tmp", AutoComplete: completer, }) if err != nil { panic(err) } db, err := sjdb.New("metadata-db.dat") if err != nil { panic(err) } defer func() { if err := db.Close(); err != nil { panic(err) } l.Close() }() log.SetOutput(l.Stderr()) for { line, err := l.Readline() if err != nil { break } switch { case strings.HasPrefix(line, "set-log-level "): setLogLevel(strings.Trim(line[14:], " ")) case strings.HasPrefix(line, "insert "): insert(db, l, line[7:]) case strings.HasPrefix(line, "bulk-insert "): bulkInsert(db, l, line[12:]) case strings.HasPrefix(line, "find "): find(db, line[5:]) case strings.HasPrefix(line, "search "): search(db, l, line[7:]) case strings.HasPrefix(line, "update "): update(db, l, line[7:]) case strings.HasPrefix(line, "delete "): deleteRecord(db, line[7:]) case strings.HasPrefix(line, "bulk-delete "): bulkDelete(db, l, line[12:]) case strings.HasPrefix(strings.Trim(line, " "), "show-tree"): showTree(db) case line == "exit": goto exit case line == "help": usage(l.Stderr()) case line == "": default: log.Error("Unknown command:", strconv.Quote(line)) } } exit: } func setLogLevel(level string) { switch level { case "debug": log.SetLevel(log.DebugLevel) case "info": log.SetLevel(log.InfoLevel) case "warn": log.SetLevel(log.WarnLevel) default: fmt.Printf("Invalid log level: %#v", level) } } func insert(db sjdb.SimpleJSONDB, l *readline.Instance, args string) { idAndJson := strings.SplitN(args, " ", 2) if len(idAndJson) != 2 { usage(l.Stderr()) } id, err := strconv.ParseUint(idAndJson[0], 10, 32) if err != nil { log.Error(err) return } if err = db.InsertRecord(uint32(id), idAndJson[1]); err != nil { log.Error(err) } } func update(db sjdb.SimpleJSONDB, l *readline.Instance, args string) { idAndJson := strings.SplitN(args, " ", 2) if len(idAndJson) != 2 { usage(l.Stderr()) } id, err := strconv.ParseUint(idAndJson[0], 10, 32) if err != nil { log.Error(err) return } if err = db.UpdateRecord(uint32(id), idAndJson[1]); err != nil { log.Error(err) } log.Warn("Record updated") } func bulkInsert(db sjdb.SimpleJSONDB, l *readline.Instance, args string) { argsArr := strings.SplitN(args, " ", 3) if len(argsArr) != 3 { usage(l.Stderr()) return } initialID, err := strconv.ParseUint(strings.Trim(argsArr[0], " "), 10, 32) if err != nil { log.Error(err) return } lastID, err := strconv.ParseUint(strings.Trim(argsArr[1], " "), 10, 32) if err != nil { log.Error(err) return } if initialID > lastID { log.Error("Invalid ID range provided") return } jsonStringTemplate := argsArr[2] for id := initialID; id <= lastID; id++ { log.Warnf("Inserting %v", id) if err = db.InsertRecord(uint32(id), jsonStringTemplate); err != nil { log.Error(err) return } } log.Warnf("%d records inserted", lastID-initialID+1) } func bulkDelete(db sjdb.SimpleJSONDB, l *readline.Instance, args string) { argsArr := strings.SplitN(args, " ", 2) if len(argsArr) != 2 { usage(l.Stderr()) return } initialID, err := strconv.ParseUint(strings.Trim(argsArr[0], " "), 10, 32) if err != nil { log.Error(err) return } lastID, err := strconv.ParseUint(strings.Trim(argsArr[1], " "), 10, 32) if err != nil { log.Error(err) return } if initialID > lastID { log.Error("Invalid ID range provided") return } for id := initialID; id <= lastID; id++ { log.Warnf("Deleting %v", id) if err = db.DeleteRecord(uint32(id)); err != nil { log.Error(err) return } } log.Warnf("%d records removed", lastID-initialID+1) } func find(db sjdb.SimpleJSONDB, args string) { id, err := strconv.ParseUint(strings.Trim(args, " "), 10, 32) if err != nil { log.Error(err) return } record, err := db.FindRecord(uint32(id)) if err != nil { log.Error(err) return } var out bytes.Buffer json.Indent(&out, record.Data, "", " ") out.WriteString("\n") out.WriteTo(os.Stdout) } func search(db sjdb.SimpleJSONDB, l *readline.Instance, args string) { argsArr := strings.SplitN(args, " ", 3) if len(argsArr) != 2 { usage(l.Stderr()) return } records, err := db.SearchRecords(argsArr[0], argsArr[1]) if err != nil { log.Error(err) return } if len(records) == 0 { fmt.Println("No records found") return } for _, record := range records { fmt.Printf("\tID: %04d | DATA: `%s`\n", record.ID, record.Data) } } func deleteRecord(db sjdb.SimpleJSONDB, args string) { id, err := strconv.ParseUint(strings.Trim(args, " "), 10, 32) if err != nil { log.Error(err) return } if err = db.DeleteRecord(uint32(id)); err != nil { log.Error(err) return } fmt.Printf("Record %d deleted\n", id) log.Warnf("Record %d deleted", id) } func showTree(db sjdb.SimpleJSONDB) { println(db.DumpIndex()) }
func main() { l, err := readline.NewEx(&readline.Config{ Prompt: "\033[31m»\033[0m ", HistoryFile: "/tmp/readline.tmp", AutoComplete: completer, }) if err != nil { panic(err) } defer l.Close() log.SetOutput(l.Stderr()) for { line, err := l.Readline() if err != nil { break } line = strings.TrimSpace(line) switch { 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") } case line == "login": pswd, err := l.ReadPassword("please enter your password: "******"you enter:", strconv.Quote(string(pswd))) case line == "help": usage(l.Stderr()) case strings.HasPrefix(line, "setprompt"): prompt := line[10:] if prompt == "" { log.Println("setprompt <prompt>") break } l.SetPrompt(prompt) case strings.HasPrefix(line, "say"): line := strings.TrimSpace(line[3:]) if len(line) == 0 { log.Println("say what?") break } go func() { for _ = range time.Tick(time.Second) { log.Println(line) } }() case line == "bye": goto exit case line == "": default: log.Println("you said:", strconv.Quote(line)) } } exit: }
func main() { flag.Parse() if *server == "" { fmt.Fprintf(os.Stderr, "--server cannot be empty.\n") os.Exit(1) } if *port != 0 { http.Handle("/metrics", prometheus.Handler()) go http.ListenAndServe(fmt.Sprintf(":%v", *port), nil) } var opts []grpc.DialOption if len(*caFile) != 0 { var creds credentials.TransportAuthenticator var err error creds, err = credentials.NewClientTLSFromFile(*caFile, "") if err != nil { log.Exitf("Failed to create TLS credentials %v\n", err) } opts = append(opts, grpc.WithTransportCredentials(creds)) } else { opts = append(opts, grpc.WithInsecure()) } c := &Multiclient{ addr: *server, opts: []doorman.Option{doorman.DialOpts(opts...)}, clients: make(map[string]*doorman.Client), resources: make(map[key]doorman.Resource), capacities: make(map[key]float64), } defer c.Close() line, err := readline.NewEx(&readline.Config{ Prompt: "> ", HistoryFile: "/tmp/doorman_shell.tmp", InterruptPrompt: "\nInterrupt, Press Ctrl+D to exit", }) if err != nil { fmt.Printf("ERROR: %v\n", err) os.Exit(1) } for { data, err := line.Readline() if err == io.EOF { break } if err != nil { fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) } command, err := shlex.Split(data) if err != nil { fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) } err = c.Eval(command) if err == io.EOF { break } if err != nil { fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) } } }
func main() { loop := true if len(os.Args) < 4 { fmt.Printf("Too few arguments\n") return } addr := os.Args[1] user := os.Args[2] service := os.Args[3] c := &convenience.Client{} err := c.Dial("tcp", addr, user, service) if err != nil { fmt.Printf("Connect failed: %v\n", err) return } var cmds map[string]func(string) cmds = map[string]func(string){ "ls": func(s string) { if s == "" { s = "/" } strs, err := c.List(s) if err != nil { fmt.Printf("ls failed: %v\n", err) return } fmt.Printf("%v\n", strs) }, "cat": func(s string) { strs, err := c.Read(s) if err != nil { fmt.Printf("cat failed: %v\n", err) return } fmt.Printf("%v\n", strs) }, "get": func(string) { fmt.Printf("get is not yet implemented\n") }, "put": func(string) { fmt.Printf("put is not yet implemented\n") }, "mkdir": func(s string) { err := c.Create(s, true) if err != nil { fmt.Printf("mkdir failed: %v\n", err) return } }, "rm": func(s string) { err := c.Remove(s) if err != nil { fmt.Printf("rm failed: %v\n", err) return } }, "chmod": func(string) { fmt.Printf("chmod is not yet implemented\n") }, "quit": func(string) { fmt.Printf("bye\n") loop = false }, "help": func(string) { fmt.Printf("Available commands: \n") for k := range cmds { fmt.Printf("\t%s\n", k) } }, } completer := readline.NewPrefixCompleter() for k := range cmds { completer.Children = append(completer.Children, readline.PcItem(k)) } rl, err := readline.NewEx(&readline.Config{ Prompt: "9p> ", AutoComplete: completer, }) if err != nil { fmt.Printf("failed to create readline: %v\n", err) return } defer rl.Close() for loop { line, err := rl.Readline() if err != nil { // io.EOF break } idx := strings.Index(line, " ") var cmd, args string if idx != -1 { cmd = line[:idx] args = line[idx+1:] } else { cmd = line } f, ok := cmds[cmd] if !ok { fmt.Printf("no such command: [%s]\n", cmd) continue } f(args) } }
// runInteractive runs the SQL client interactively, presenting // a prompt to the user for each statement. func runInteractive(conn *sqlConn, config *readline.Config) (exitErr error) { fullPrompt, continuePrompt := preparePrompts(conn.url) ins, err := readline.NewEx(config) if err != nil { return err } if isInteractive { // We only enable history management when the terminal is actually // interactive. This saves on memory when e.g. piping a large SQL // script through the command-line client. userAcct, err := user.Current() if err != nil { if log.V(2) { log.Warningf("cannot retrieve user information: %s", err) log.Info("cannot load or save the command-line history") } } else { histFile := filepath.Join(userAcct.HomeDir, ".cockroachdb_history") cfg := ins.Config.Clone() cfg.HistoryFile = histFile ins.SetConfig(cfg) } } if isInteractive { fmt.Print(infoMessage) } var stmt []string syntax := parser.Traditional for isFinished := false; !isFinished; { thisPrompt := fullPrompt if !isInteractive { thisPrompt = "" } else if len(stmt) > 0 { thisPrompt = continuePrompt } ins.SetPrompt(thisPrompt) l, err := ins.Readline() if !isInteractive && err == io.EOF { // In non-interactive mode, we want EOF to finish the last statement. err = nil isFinished = true } if err == readline.ErrInterrupt || err == io.EOF { break } else if err != nil { fmt.Fprintf(osStderr, "input error: %s\n", err) return err } // Check if this is a request for help or a client-side command. // If so, process it directly and skip query processing below. status, hasSet := handleInputLine(ins, &stmt, l, syntax) if status == cliExit { break } else if status == cliNextLine && !isFinished { // Ask for more input unless we reached EOF. continue } else if isFinished && len(stmt) == 0 { // Exit if we reached EOF and the currently built-up statement is empty. break } // We join the statements back together with newlines in case // there is a significant newline inside a string literal. However // we join with spaces for keeping history, because otherwise a // history recall will only pull one line from a multi-line // statement. fullStmt := strings.Join(stmt, "\n") // Ensure the statement is terminated with a semicolon. This // catches cases where the last line before EOF was not terminated // properly. if len(fullStmt) > 0 && !strings.HasSuffix(fullStmt, ";") { fmt.Fprintln(osStderr, "no semicolon at end of statement; statement ignored") continue } if isInteractive { // We save the history between each statement, This enables // reusing history in another SQL shell without closing the // current shell. addHistory(ins, fullStmt) } if exitErr = runQueryAndFormatResults(conn, os.Stdout, makeQuery(fullStmt), cliCtx.prettyFmt); exitErr != nil { fmt.Fprintln(osStderr, exitErr) } // Clear the saved statement. stmt = stmt[:0] if hasSet { newSyntax, err := getSyntax(conn) if err != nil { fmt.Fprintf(osStderr, "could not get session syntax: %s", err) } else { syntax = newSyntax } } } return exitErr }