forked from sloum/bombadillo
improve error handling
This commit is contained in:
parent
cecc399c38
commit
6ea5754e57
|
@ -35,9 +35,6 @@ const (
|
||||||
End
|
End
|
||||||
Whitespace
|
Whitespace
|
||||||
|
|
||||||
number
|
|
||||||
letter
|
|
||||||
ws
|
|
||||||
illegal
|
illegal
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -159,7 +156,3 @@ func isLetter(ch rune) bool {
|
||||||
func isDigit(ch rune) bool {
|
func isDigit(ch rune) bool {
|
||||||
return ch >= '0' && ch <= '9'
|
return ch >= '0' && ch <= '9'
|
||||||
}
|
}
|
||||||
|
|
||||||
func isEOF(ch rune) bool {
|
|
||||||
return ch == rune(0)
|
|
||||||
}
|
|
||||||
|
|
|
@ -194,7 +194,3 @@ func isWhitespace(ch rune) bool {
|
||||||
func isText(ch rune) bool {
|
func isText(ch rune) bool {
|
||||||
return ch >= '!' && ch <= '~' && ch != equal && ch != l_brace && ch != r_brace
|
return ch >= '!' && ch <= '~' && ch != equal && ch != l_brace && ch != r_brace
|
||||||
}
|
}
|
||||||
|
|
||||||
func isEOF(ch rune) bool {
|
|
||||||
return ch == eof
|
|
||||||
}
|
|
||||||
|
|
|
@ -86,7 +86,10 @@ func (p *Parser) Parse() (Config, error) {
|
||||||
}
|
}
|
||||||
switch section {
|
switch section {
|
||||||
case "BOOKMARKS":
|
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":
|
case "COLORS":
|
||||||
c.Colors = append(c.Colors, keyval)
|
c.Colors = append(c.Colors, keyval)
|
||||||
case "SETTINGS":
|
case "SETTINGS":
|
||||||
|
|
45
cui/cui.go
45
cui/cui.go
|
@ -57,7 +57,11 @@ func moveCursorToward(dir string, amount int) {
|
||||||
func Exit() {
|
func Exit() {
|
||||||
moveCursorToward("down", 500)
|
moveCursorToward("down", 500)
|
||||||
moveCursorToward("right", 500)
|
moveCursorToward("right", 500)
|
||||||
SetLineMode()
|
err := SetLineMode()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Print("\n")
|
fmt.Print("\n")
|
||||||
fmt.Print("\033[?25h")
|
fmt.Print("\033[?25h")
|
||||||
os.Exit(0)
|
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{}
|
out := []string{}
|
||||||
for _, ln := range s {
|
for _, ln := range s {
|
||||||
if len(ln) <= length {
|
if len(ln) <= length {
|
||||||
|
@ -121,26 +125,43 @@ func Getch() rune {
|
||||||
return char
|
return char
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLine() string {
|
func GetLine() (string, error) {
|
||||||
SetLineMode()
|
err := SetLineMode()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
fmt.Print(": ")
|
fmt.Print(": ")
|
||||||
text, _ := reader.ReadString('\n')
|
text, err := reader.ReadString('\n')
|
||||||
SetCharMode()
|
if err != nil {
|
||||||
return text[:len(text)-1]
|
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 := exec.Command("stty", "cbreak", "-echo")
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Run()
|
err := cmd.Run()
|
||||||
fmt.Print("\033[?25l")
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fmt.Print("\033[?25l")
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetLineMode() {
|
func SetLineMode() error {
|
||||||
cmd := exec.Command("stty", "-cbreak", "echo")
|
cmd := exec.Command("stty", "-cbreak", "echo")
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ func (s *Screen) GetSize() {
|
||||||
|
|
||||||
// NewScreen is a constructor function that returns a pointer
|
// NewScreen is a constructor function that returns a pointer
|
||||||
// to a Screen struct
|
// to a Screen struct
|
||||||
func NewScreen() *Screen {
|
func NewScreen() (*Screen, error) {
|
||||||
if screenInit {
|
if screenInit {
|
||||||
fmt.Println("Fatal error: Cannot create multiple screens")
|
fmt.Println("Fatal error: Cannot create multiple screens")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -152,8 +152,12 @@ func NewScreen() *Screen {
|
||||||
for i := 0; i < s.Height; i++ {
|
for i := 0; i < s.Height; i++ {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
SetCharMode()
|
err := SetCharMode()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
Clear("screen")
|
Clear("screen")
|
||||||
screenInit = true
|
screenInit = true
|
||||||
return &s
|
return &s, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ func (w *Window) DrawContent() {
|
||||||
height := w.Box.row2 - w.Box.row1 + borderThickness
|
height := w.Box.row2 - w.Box.row1 + borderThickness
|
||||||
width := w.Box.col2 - w.Box.col1 + 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 {
|
if len(content) < w.Scrollposition+height {
|
||||||
maxlines = len(content)
|
maxlines = len(content)
|
||||||
|
|
|
@ -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].*)?)?$`)
|
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)
|
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")
|
return out, errors.New("Invalid URL or command character")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
92
main.go
92
main.go
|
@ -27,11 +27,6 @@ var options = map[string]string{
|
||||||
"httpbrowser": "lynx",
|
"httpbrowser": "lynx",
|
||||||
}
|
}
|
||||||
|
|
||||||
func errExit(err string, code int) {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func saveFile(address, name string) error {
|
func saveFile(address, name string) error {
|
||||||
quickMessage("Saving file...", false)
|
quickMessage("Saving file...", false)
|
||||||
defer quickMessage("Saving file...", true)
|
defer quickMessage("Saving file...", true)
|
||||||
|
@ -73,7 +68,12 @@ func search(u string) error {
|
||||||
cui.Clear("line")
|
cui.Clear("line")
|
||||||
fmt.Print("Enter form input: ")
|
fmt.Print("Enter form input: ")
|
||||||
cui.MoveCursorTo(screen.Height-1, 17)
|
cui.MoveCursorTo(screen.Height-1, 17)
|
||||||
entry := cui.GetLine()
|
|
||||||
|
entry, err := cui.GetLine()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
quickMessage("Searching...", false)
|
quickMessage("Searching...", false)
|
||||||
searchurl := fmt.Sprintf("%s\t%s", u, entry)
|
searchurl := fmt.Sprintf("%s\t%s", u, entry)
|
||||||
sv, err := gopher.Visit(searchurl, options["openhttp"])
|
sv, err := gopher.Visit(searchurl, options["openhttp"])
|
||||||
|
@ -126,9 +126,6 @@ func toggleBookmarks() {
|
||||||
bookmarks.Active = true
|
bookmarks.Active = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if screen.Activewindow == 0 {
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
screen.ReflashScreen(false)
|
screen.ReflashScreen(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,10 +227,18 @@ func doLinkCommand(action, target string) error {
|
||||||
switch action {
|
switch action {
|
||||||
case "DELETE", "D":
|
case "DELETE", "D":
|
||||||
err := settings.Bookmarks.Del(num)
|
err := settings.Bookmarks.Del(num)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
screen.Windows[1].Content = settings.Bookmarks.List()
|
screen.Windows[1].Content = settings.Bookmarks.List()
|
||||||
saveConfig()
|
err = saveConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
screen.ReflashScreen(false)
|
screen.ReflashScreen(false)
|
||||||
return err
|
return nil
|
||||||
case "BOOKMARKS", "B":
|
case "BOOKMARKS", "B":
|
||||||
if num > len(settings.Bookmarks.Links)-1 {
|
if num > len(settings.Bookmarks.Links)-1 {
|
||||||
return fmt.Errorf("There is no bookmark with ID %d", num)
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
screen.Windows[1].Content = settings.Bookmarks.List()
|
screen.Windows[1].Content = settings.Bookmarks.List()
|
||||||
saveConfig()
|
err = saveConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
screen.ReflashScreen(false)
|
screen.ReflashScreen(false)
|
||||||
return nil
|
return nil
|
||||||
case "WRITE", "W":
|
case "WRITE", "W":
|
||||||
|
@ -269,8 +279,7 @@ func doCommandAs(action string, values []string) error {
|
||||||
case "SET", "S":
|
case "SET", "S":
|
||||||
if _, ok := options[values[0]]; ok {
|
if _, ok := options[values[0]]; ok {
|
||||||
options[values[0]] = strings.Join(values[1:], " ")
|
options[values[0]] = strings.Join(values[1:], " ")
|
||||||
saveConfig()
|
return saveConfig()
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Unable to set %s, it does not exist", values[0])
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
screen.Windows[1].Content = settings.Bookmarks.List()
|
screen.Windows[1].Content = settings.Bookmarks.List()
|
||||||
saveConfig()
|
|
||||||
|
err = saveConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
screen.ReflashScreen(false)
|
screen.ReflashScreen(false)
|
||||||
return nil
|
return nil
|
||||||
case "WRITE", "W":
|
case "WRITE", "W":
|
||||||
|
@ -329,7 +344,7 @@ func quickMessage(msg string, clearMsg bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveConfig() {
|
func saveConfig() error {
|
||||||
bkmrks := settings.Bookmarks.IniDump()
|
bkmrks := settings.Bookmarks.IniDump()
|
||||||
opts := "\n[SETTINGS]\n"
|
opts := "\n[SETTINGS]\n"
|
||||||
for k, v := range options {
|
for k, v := range options {
|
||||||
|
@ -338,14 +353,19 @@ func saveConfig() {
|
||||||
opts += v
|
opts += v
|
||||||
opts += "\n"
|
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")
|
file, err := os.Open(userinfo.HomeDir + "/.bombadillo.ini")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
saveConfig()
|
err = saveConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
confparser := config.NewParser(file)
|
confparser := config.NewParser(file)
|
||||||
settings, _ = confparser.Parse()
|
settings, _ = confparser.Parse()
|
||||||
file.Close()
|
file.Close()
|
||||||
|
@ -356,6 +376,8 @@ func loadConfig() {
|
||||||
options[lowerkey] = v.Value
|
options[lowerkey] = v.Value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleActiveWindow() {
|
func toggleActiveWindow() {
|
||||||
|
@ -378,10 +400,20 @@ func displayError(err error) {
|
||||||
fmt.Print("\033[41m\033[37m", err, "\033[0m")
|
fmt.Print("\033[41m\033[37m", err, "\033[0m")
|
||||||
}
|
}
|
||||||
|
|
||||||
func initClient() {
|
func initClient() error {
|
||||||
history.Position = -1
|
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.AddWindow(2, 1, screen.Height-2, screen.Width, false, false, true)
|
||||||
screen.Windows[0].Active = true
|
screen.Windows[0].Active = true
|
||||||
screen.AddMsgBar(1, " ((( Bombadillo ))) ", " A fun gopher client!", true)
|
screen.AddMsgBar(1, " ((( Bombadillo ))) ", " A fun gopher client!", true)
|
||||||
|
@ -390,12 +422,18 @@ func initClient() {
|
||||||
bookmarksWidth = screen.Width
|
bookmarksWidth = screen.Width
|
||||||
}
|
}
|
||||||
screen.AddWindow(2, screen.Width-bookmarksWidth, screen.Height-2, screen.Width, false, true, false)
|
screen.AddWindow(2, screen.Width-bookmarksWidth, screen.Height-2, screen.Width, false, true, false)
|
||||||
loadConfig()
|
return loadConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
defer cui.Exit()
|
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]
|
mainWindow := screen.Windows[0]
|
||||||
firstLoad := true
|
firstLoad := true
|
||||||
|
|
||||||
|
@ -440,7 +478,11 @@ func main() {
|
||||||
toggleActiveWindow()
|
toggleActiveWindow()
|
||||||
case ':', ' ':
|
case ':', ' ':
|
||||||
cui.MoveCursorTo(screen.Height-1, 0)
|
cui.MoveCursorTo(screen.Height-1, 0)
|
||||||
entry := cui.GetLine()
|
entry, err := cui.GetLine()
|
||||||
|
if err != nil {
|
||||||
|
displayError(err)
|
||||||
|
}
|
||||||
|
|
||||||
// Clear entry line and error line
|
// Clear entry line and error line
|
||||||
clearInput(true)
|
clearInput(true)
|
||||||
if entry == "" {
|
if entry == "" {
|
||||||
|
|
Loading…
Reference in New Issue