Browse Source

improve error handling

pull/3/head
Justin Overfelt 2 years ago
parent
commit
6ea5754e57
  1. 7
      cmdparse/lexer.go
  2. 4
      config/lexer.go
  3. 5
      config/parser.go
  4. 45
      cui/cui.go
  5. 10
      cui/screen.go
  6. 2
      cui/window.go
  7. 2
      gopher/url.go
  8. 92
      main.go

7
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)
}

4
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
}

5
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":

45
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()
}

10
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
}

2
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)

2
gopher/url.go

@ -33,7 +33,7 @@ func MakeUrl(u string) (Url, error) {
re := regexp.MustCompile(`^((?P<scheme>gopher|http|https|ftp|telnet):\/\/)?(?P<host>[\w\-\.\d]+)(?::(?P<port>\d+)?)?(?:/(?P<type>[01345679gIhisp])?)?(?P<resource>(?:[\/|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")
}

92
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 == "" {

Loading…
Cancel
Save