func interact(ev *eval.Evaler, st *store.Store) { // Build Editor. sigch := make(chan os.Signal) signal.Notify(sigch) ed := edit.NewEditor(os.Stdin, sigch, ev, st) // Source rc.elv. datadir, err := store.EnsureDataDir() if err != nil { fmt.Fprintln(os.Stderr, err) } else { source(ev, datadir+"/rc.elv", true) } // Build readLine function. readLine := func() (string, error) { return ed.ReadLine() } cooldown := time.Second usingBasic := false cmdNum := 0 for { cmdNum++ // name := fmt.Sprintf("<tty %d>", cmdNum) line, err := readLine() if err == io.EOF { break } else if err != nil { fmt.Println("Editor error:", err) if !usingBasic { fmt.Println("Falling back to basic line editor") readLine = basicReadLine usingBasic = true } else { fmt.Println("Don't know what to do, pid is", os.Getpid()) fmt.Println("Restarting editor in", cooldown) time.Sleep(cooldown) if cooldown < time.Minute { cooldown *= 2 } } continue } // No error; reset cooldown. cooldown = time.Second n, err := parse.Parse(line) printError(err, "<interact>", "parse error", line) if err == nil { err := ev.EvalInteractive(line, n) printError(err, "<interact>", "eval error", line) } } }