// TODO(xiaq): Currently only the editor deals with signals. func interact() { ev, st := newEvalerAndStore() datadir, err := store.EnsureDataDir() printError(err) if err == nil { // XXX err := ev.Source(datadir + "/rc.elv") if err != nil && !os.IsNotExist(err) { printError(err) } } cmdNum := 0 username := "******" user, err := user.Current() if err == nil { username = user.Username } hostname, err := os.Hostname() if err != nil { hostname = "???" } rpromptStr := username + "@" + hostname sigch := make(chan os.Signal, sigchSize) signal.Notify(sigch) ed := edit.NewEditor(os.Stdin, sigch, ev, st) for { cmdNum++ name := fmt.Sprintf("<tty %d>", cmdNum) prompt := func() string { return osutil.Getwd() + "> " } rprompt := func() string { return rpromptStr } lr := ed.ReadLine(prompt, rprompt) // signal.Stop(sigch) if lr.EOF { break } else if lr.Err != nil { fmt.Println("Editor error:", lr.Err) fmt.Println("My pid is", os.Getpid()) } n, err := parse.Parse(name, lr.Line) printError(err) if err == nil { err := ev.Eval(name, lr.Line, n) printError(err) } } }
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) } } }
func newEvalerAndStore() (*eval.Evaler, *store.Store) { dataDir, err := store.EnsureDataDir() if err != nil { fmt.Fprintln(os.Stderr, "Warning: cannot create data dir ~/.elvish") } var st *store.Store if err == nil { st, err = store.NewStore(dataDir) if err != nil { fmt.Fprintln(os.Stderr, "Warning: cannot connect to store:", err) } } return eval.NewEvaler(st), st }
// TODO(xiaq): Currently only the editor deals with signals. func interact() { ev, st := newEvalerAndStore() sigch := make(chan os.Signal, sigchSize) signal.Notify(sigch) ed := edit.NewEditor(os.Stdin, sigch, ev, st) datadir, err := store.EnsureDataDir() printError(err) if err == nil { // XXX err := ev.Source(datadir + "/rc.elv") if err != nil && !os.IsNotExist(err) { printError(err) } } cmdNum := 0 username := "******" user, err := user.Current() if err == nil { username = user.Username } hostname, err := os.Hostname() if err != nil { hostname = "???" } rpromptStr := username + "@" + hostname prompt := func() string { return osutil.Getwd() + "> " } rprompt := func() string { return rpromptStr } readLine := func() edit.LineRead { return ed.ReadLine(prompt, rprompt) } usingBasic := false if !sys.IsATTY(0) { readLine = basicReadLine usingBasic = true } for { cmdNum++ // name := fmt.Sprintf("<tty %d>", cmdNum) lr := readLine() // signal.Stop(sigch) if lr.EOF { break } else if lr.Err != nil { fmt.Println("Editor error:", lr.Err) if !usingBasic { fmt.Println("Falling back to basic line editor") readLine = basicReadLine usingBasic = true } continue } n, err := parse.Parse(lr.Line) printError(err) if err == nil { err := ev.EvalInteractive(lr.Line, n) printError(err) } } }