// Package repl implements the main event loop. package repl import ( "fmt" "os" "path" "unicode" "git.lyda.ie/kevin/bulletin/this" "github.com/adrg/xdg" "github.com/chzyer/readline" ) // Loop is the main event loop. func Loop() error { histdir := path.Join(xdg.ConfigHome, "BULLETIN") os.MkdirAll(histdir, 0700) histfile := path.Join(histdir, fmt.Sprintf("%s.history", this.User.Login)) rl, err := readline.NewEx( &readline.Config{ Prompt: "BULLETIN> ", HistoryFile: histfile, // TODO: AutoComplete: completer, InterruptPrompt: "^C", EOFPrompt: "EXIT", HistorySearchFold: true, }) if err != nil { return err } defer rl.Close() // TODO: Remove once commands are implemented. unimplemented := 0 total := len(commands) for c := range commands { if commands[c].Action == nil { unimplemented++ } if len(commands[c].Commands) > 0 { total-- unimplemented-- for subc := range commands[c].Commands { if commands[c].Commands[subc].Action == nil { unimplemented++ } } total += len(commands[c].Commands) } } fmt.Printf("TODO: %d out of %d commands still to be implemented.\n", unimplemented, total) // TODO: END for { line, err := rl.Readline() if err != nil { if err.Error() == "Interrupt" { commands.ParseAndRun("QUIT") } else if err.Error() == "EOF" { commands.ParseAndRun("EXIT") } return err } if len(line) == 0 { continue } prependRead := false for _, r := range line { if unicode.IsDigit(r) { prependRead = true break } if !unicode.IsSpace(r) { break } } if prependRead { line = "READ " + line } err = commands.ParseAndRun(line) if err != nil { fmt.Printf("ERROR: %s.\n", err) } } }