diff --git a/cmdparse/lexer.go b/cmdparse/lexer.go index 4be43d9..91d5f43 100644 --- a/cmdparse/lexer.go +++ b/cmdparse/lexer.go @@ -35,9 +35,6 @@ const ( End Whitespace - number - letter - ws illegal ) @@ -159,7 +156,3 @@ func isLetter(ch rune) bool { func isDigit(ch rune) bool { return ch >= '0' && ch <= '9' } - -func isEOF(ch rune) bool { - return ch == rune(0) -} diff --git a/config/lexer.go b/config/lexer.go index fd398d9..74e39c7 100644 --- a/config/lexer.go +++ b/config/lexer.go @@ -194,7 +194,3 @@ func isWhitespace(ch rune) bool { func isText(ch rune) bool { return ch >= '!' && ch <= '~' && ch != equal && ch != l_brace && ch != r_brace } - -func isEOF(ch rune) bool { - return ch == eof -} diff --git a/config/parser.go b/config/parser.go index 831d0c3..4661ac6 100644 --- a/config/parser.go +++ b/config/parser.go @@ -86,7 +86,10 @@ func (p *Parser) Parse() (Config, error) { } switch section { case "BOOKMARKS": - c.Bookmarks.Add([]string{keyval.Value, keyval.Key}) + err := c.Bookmarks.Add([]string{keyval.Value, keyval.Key}) + if err != nil { + return c, err + } case "COLORS": c.Colors = append(c.Colors, keyval) case "SETTINGS": diff --git a/cui/cui.go b/cui/cui.go index d8685f8..8833ba6 100644 --- a/cui/cui.go +++ b/cui/cui.go @@ -57,7 +57,11 @@ func moveCursorToward(dir string, amount int) { func Exit() { moveCursorToward("down", 500) moveCursorToward("right", 500) - SetLineMode() + err := SetLineMode() + if err != nil { + panic(err) + } + fmt.Print("\n") fmt.Print("\033[?25h") os.Exit(0) @@ -79,7 +83,7 @@ func Clear(dir string) { } -func WrapLines(s []string, length int) []string { +func wrapLines(s []string, length int) []string { out := []string{} for _, ln := range s { if len(ln) <= length { @@ -121,26 +125,43 @@ func Getch() rune { return char } -func GetLine() string { - SetLineMode() +func GetLine() (string, error) { + err := SetLineMode() + if err != nil { + return "", err + } + reader := bufio.NewReader(os.Stdin) fmt.Print(": ") - text, _ := reader.ReadString('\n') - SetCharMode() - return text[:len(text)-1] + text, err := reader.ReadString('\n') + if err != nil { + return "", err + } + + err = SetCharMode() + if err != nil { + return "", err + } + + return text[:len(text)-1], nil } -func SetCharMode() { +func SetCharMode() error { cmd := exec.Command("stty", "cbreak", "-echo") cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout - cmd.Run() - fmt.Print("\033[?25l") + err := cmd.Run() + if err != nil { + return err + } + + _, err = fmt.Print("\033[?25l") + return err } -func SetLineMode() { +func SetLineMode() error { cmd := exec.Command("stty", "-cbreak", "echo") cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout - cmd.Run() + return cmd.Run() } diff --git a/cui/screen.go b/cui/screen.go index 73ed3db..1763caa 100644 --- a/cui/screen.go +++ b/cui/screen.go @@ -142,7 +142,7 @@ func (s *Screen) GetSize() { // NewScreen is a constructor function that returns a pointer // to a Screen struct -func NewScreen() *Screen { +func NewScreen() (*Screen, error) { if screenInit { fmt.Println("Fatal error: Cannot create multiple screens") os.Exit(1) @@ -152,8 +152,12 @@ func NewScreen() *Screen { for i := 0; i < s.Height; i++ { fmt.Println() } - SetCharMode() + err := SetCharMode() + if err != nil { + return nil, err + } + Clear("screen") screenInit = true - return &s + return &s, nil } diff --git a/cui/window.go b/cui/window.go index 49deeef..4569e5f 100644 --- a/cui/window.go +++ b/cui/window.go @@ -64,7 +64,7 @@ func (w *Window) DrawContent() { height := w.Box.row2 - w.Box.row1 + borderThickness width := w.Box.col2 - w.Box.col1 + borderThickness - content := WrapLines(w.Content, width) + content := wrapLines(w.Content, width) if len(content) < w.Scrollposition+height { maxlines = len(content) diff --git a/gopher/url.go b/gopher/url.go index 2bfb743..fd467f4 100644 --- a/gopher/url.go +++ b/gopher/url.go @@ -33,7 +33,7 @@ func MakeUrl(u string) (Url, error) { re := regexp.MustCompile(`^((?Pgopher|http|https|ftp|telnet):\/\/)?(?P[\w\-\.\d]+)(?::(?P\d+)?)?(?:/(?P[01345679gIhisp])?)?(?P(?:[\/|Uu].*)?)?$`) match := re.FindStringSubmatch(u) - if valid := re.MatchString(u); valid != true { + if valid := re.MatchString(u); !valid { return out, errors.New("Invalid URL or command character") } diff --git a/main.go b/main.go index a438e0e..ebc06f9 100644 --- a/main.go +++ b/main.go @@ -27,11 +27,6 @@ var options = map[string]string{ "httpbrowser": "lynx", } -func errExit(err string, code int) { - fmt.Println(err) - os.Exit(code) -} - func saveFile(address, name string) error { quickMessage("Saving file...", false) defer quickMessage("Saving file...", true) @@ -73,7 +68,12 @@ func search(u string) error { cui.Clear("line") fmt.Print("Enter form input: ") cui.MoveCursorTo(screen.Height-1, 17) - entry := cui.GetLine() + + entry, err := cui.GetLine() + if err != nil { + return err + } + quickMessage("Searching...", false) searchurl := fmt.Sprintf("%s\t%s", u, entry) sv, err := gopher.Visit(searchurl, options["openhttp"]) @@ -126,9 +126,6 @@ func toggleBookmarks() { bookmarks.Active = true } - if screen.Activewindow == 0 { - } else { - } screen.ReflashScreen(false) } @@ -230,10 +227,18 @@ func doLinkCommand(action, target string) error { switch action { case "DELETE", "D": err := settings.Bookmarks.Del(num) + if err != nil { + return err + } + screen.Windows[1].Content = settings.Bookmarks.List() - saveConfig() + err = saveConfig() + if err != nil { + return err + } + screen.ReflashScreen(false) - return err + return nil case "BOOKMARKS", "B": if num > len(settings.Bookmarks.Links)-1 { return fmt.Errorf("There is no bookmark with ID %d", num) @@ -260,8 +265,13 @@ func doCommandAs(action string, values []string) error { if err != nil { return err } + screen.Windows[1].Content = settings.Bookmarks.List() - saveConfig() + err = saveConfig() + if err != nil { + return err + } + screen.ReflashScreen(false) return nil case "WRITE", "W": @@ -269,8 +279,7 @@ func doCommandAs(action string, values []string) error { case "SET", "S": if _, ok := options[values[0]]; ok { options[values[0]] = strings.Join(values[1:], " ") - saveConfig() - return nil + return saveConfig() } return fmt.Errorf("Unable to set %s, it does not exist", values[0]) } @@ -295,8 +304,14 @@ func doLinkCommandAs(action, target string, values []string) error { if err != nil { return err } + screen.Windows[1].Content = settings.Bookmarks.List() - saveConfig() + + err = saveConfig() + if err != nil { + return err + } + screen.ReflashScreen(false) return nil case "WRITE", "W": @@ -329,7 +344,7 @@ func quickMessage(msg string, clearMsg bool) { } } -func saveConfig() { +func saveConfig() error { bkmrks := settings.Bookmarks.IniDump() opts := "\n[SETTINGS]\n" for k, v := range options { @@ -338,14 +353,19 @@ func saveConfig() { opts += v opts += "\n" } - ioutil.WriteFile(userinfo.HomeDir+"/.bombadillo.ini", []byte(bkmrks+opts), 0644) + + return ioutil.WriteFile(userinfo.HomeDir+"/.bombadillo.ini", []byte(bkmrks+opts), 0644) } -func loadConfig() { +func loadConfig() error { file, err := os.Open(userinfo.HomeDir + "/.bombadillo.ini") if err != nil { - saveConfig() + err = saveConfig() + if err != nil { + return err + } } + confparser := config.NewParser(file) settings, _ = confparser.Parse() file.Close() @@ -356,6 +376,8 @@ func loadConfig() { options[lowerkey] = v.Value } } + + return nil } func toggleActiveWindow() { @@ -378,10 +400,20 @@ func displayError(err error) { fmt.Print("\033[41m\033[37m", err, "\033[0m") } -func initClient() { +func initClient() error { history.Position = -1 - screen = cui.NewScreen() - cui.SetCharMode() + + var err error + screen, err = cui.NewScreen() + if err != nil { + return err + } + + err = cui.SetCharMode() + if err != nil { + return err + } + screen.AddWindow(2, 1, screen.Height-2, screen.Width, false, false, true) screen.Windows[0].Active = true screen.AddMsgBar(1, " ((( Bombadillo ))) ", " A fun gopher client!", true) @@ -390,12 +422,18 @@ func initClient() { bookmarksWidth = screen.Width } screen.AddWindow(2, screen.Width-bookmarksWidth, screen.Height-2, screen.Width, false, true, false) - loadConfig() + return loadConfig() } func main() { defer cui.Exit() - initClient() + err := initClient() + if err != nil { + // if we can't initialize the window, + // we can't do anything! + panic(err) + } + mainWindow := screen.Windows[0] firstLoad := true @@ -440,7 +478,11 @@ func main() { toggleActiveWindow() case ':', ' ': cui.MoveCursorTo(screen.Height-1, 0) - entry := cui.GetLine() + entry, err := cui.GetLine() + if err != nil { + displayError(err) + } + // Clear entry line and error line clearInput(true) if entry == "" {