Merge branch 'release2.3.3' into unicode-line-endings

This commit is contained in:
Sloom Sloum Sluom IV 2020-11-05 15:44:50 +00:00
commit 33e78753ea
10 changed files with 96 additions and 37 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
bombadillo bombadillo
*.asciinema *.asciinema
*.swp

View File

@ -25,10 +25,10 @@ Changes are implemented to the default branch when:
### Process for introducing a new change ### Process for introducing a new change
Please refer to our [notes on contributing](README.md#contributing) to get an understanding of how new changes are initiated, the type of changes accepted and the review process. Before you begin, please refer to our [notes on contributing](README.md#contributing) to get an understanding of how new changes are initiated, the type of changes accepted and the review process.
1. Create a new feature branch based on the **develop** branch. 1. Create a new feature branch based on the **develop** branch.
1. Raise a pull request (PR) targeting the **develop** branch. 1. Raise a pull request (PR) targeting the current release branch (confirm this in the issue comments before proceeding).
1. The PR is reviewed. 1. The PR is reviewed.
1. If the PR is approved, it is merged. 1. If the PR is approved, it is merged.
1. The version number is incremented, along with any other release activity. 1. The version number is incremented, along with any other release activity.

View File

@ -344,23 +344,26 @@ func (c *client) simpleCommand(action string) {
case "SEARCH": case "SEARCH":
c.search("", "", "?") c.search("", "", "?")
case "HELP", "?": case "HELP", "?":
go c.Visit(helplocation) c.Visit(helplocation)
default: default:
c.SetMessage(fmt.Sprintf("Unknown action %q", action), true) c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage() c.DrawMessage()
} }
} }
func (c *client) doCommand(action string, values []string) { func (c *client) doCommand(action string, values []string) {
if length := len(values); length != 1 {
c.SetMessage(fmt.Sprintf("Expected 1 argument, received %d", len(values)), true)
c.DrawMessage()
return
}
switch action { switch action {
case "CHECK", "C": case "C", "CHECK":
c.displayConfigValue(values[0]) c.displayConfigValue(values[0])
c.DrawMessage()
case "HELP", "?":
if val, ok := ERRS[values[0]]; ok {
c.SetMessage("Usage: " + val, false)
} else {
msg := fmt.Sprintf("%q is not a valid command; help syntax: %s", values[0], ERRS[action])
c.SetMessage(msg, false)
}
c.DrawMessage()
case "PURGE", "P": case "PURGE", "P":
err := c.Certs.Purge(values[0]) err := c.Certs.Purge(values[0])
if err != nil { if err != nil {
@ -405,24 +408,22 @@ func (c *client) doCommand(action string, values []string) {
c.saveFile(u, fn) c.saveFile(u, fn)
default: default:
c.SetMessage(fmt.Sprintf("Unknown action %q", action), true) c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage() c.DrawMessage()
} }
} }
func (c *client) doCommandAs(action string, values []string) { func (c *client) doCommandAs(action string, values []string) {
if len(values) < 2 {
c.SetMessage(fmt.Sprintf("Expected 2+ arguments, received %d", len(values)), true)
c.DrawMessage()
return
}
if values[0] == "." {
values[0] = c.PageState.History[c.PageState.Position].Location.Full
}
switch action { switch action {
case "ADD", "A": case "ADD", "A":
if len(values) < 2 {
c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage()
return
}
if values[0] == "." {
values[0] = c.PageState.History[c.PageState.Position].Location.Full
}
msg, err := c.BookMarks.Add(values) msg, err := c.BookMarks.Add(values)
if err != nil { if err != nil {
c.SetMessage(err.Error(), true) c.SetMessage(err.Error(), true)
@ -441,8 +442,18 @@ func (c *client) doCommandAs(action string, values []string) {
c.Draw() c.Draw()
} }
case "SEARCH": case "SEARCH":
if len(values) < 2 {
c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage()
return
}
c.search(strings.Join(values, " "), "", "") c.search(strings.Join(values, " "), "", "")
case "SET", "S": case "SET", "S":
if len(values) < 2 {
c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage()
return
}
if _, ok := c.Options[values[0]]; ok { if _, ok := c.Options[values[0]]; ok {
val := strings.Join(values[1:], " ") val := strings.Join(values[1:], " ")
if !validateOpt(values[0], val) { if !validateOpt(values[0], val) {
@ -473,7 +484,7 @@ func (c *client) doCommandAs(action string, values []string) {
c.SetMessage(fmt.Sprintf("Unable to set %s, it does not exist", values[0]), true) c.SetMessage(fmt.Sprintf("Unable to set %s, it does not exist", values[0]), true)
c.DrawMessage() c.DrawMessage()
default: default:
c.SetMessage(fmt.Sprintf("Unknown command structure"), true) c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage() c.DrawMessage()
} }
} }
@ -523,7 +534,7 @@ func (c *client) doLinkCommandAs(action, target string, values []string) {
out = append(out, values...) out = append(out, values...)
c.doCommandAs(action, out) c.doCommandAs(action, out)
default: default:
c.SetMessage(fmt.Sprintf("Unknown command structure"), true) c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage() c.DrawMessage()
} }
} }
@ -655,7 +666,7 @@ func (c *client) doLinkCommand(action, target string) {
} }
c.saveFile(u, fn) c.saveFile(u, fn)
default: default:
c.SetMessage("Unknown command structure", true) c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage() c.DrawMessage()
} }
@ -977,6 +988,7 @@ func (c *client) handleGemini(u Url) {
case 2: case 2:
// Success // Success
if capsule.MimeMaj == "text" || (c.Options["showimages"] == "true" && capsule.MimeMaj == "image") { if capsule.MimeMaj == "text" || (c.Options["showimages"] == "true" && capsule.MimeMaj == "image") {
u.Mime = capsule.MimeMin
pg := MakePage(u, capsule.Content, capsule.Links) pg := MakePage(u, capsule.Content, capsule.Links)
pg.FileType = capsule.MimeMaj pg.FileType = capsule.MimeMaj
pg.WrapContent(c.Width-1, (c.Options["theme"] == "color")) pg.WrapContent(c.Width-1, (c.Options["theme"] == "color"))
@ -1203,6 +1215,13 @@ func findAvailableFileName(fpath, fname string) (string, error) {
return savePath, nil return savePath, nil
} }
func syntaxErrorMessage(action string) string {
if val, ok := ERRS[action]; ok {
return fmt.Sprintf("Incorrect syntax. Try: %s", val)
}
return fmt.Sprintf("Unknown command %q", action)
}
func updateTimeouts(timeoutString string) error { func updateTimeouts(timeoutString string) error {
sec, err := strconv.Atoi(timeoutString) sec, err := strconv.Atoi(timeoutString)
if err != nil { if err != nil {

View File

@ -94,10 +94,10 @@ func (p *Parser) parseAction() (*Command, error) {
case Value: case Value:
cm.Target = t.val cm.Target = t.val
cm.Type = DOLINK cm.Type = DOLINK
case Word: case Word, Action:
cm.Value = append(cm.Value, t.val) cm.Value = append(cm.Value, t.val)
cm.Type = DO cm.Type = DO
case Action, Whitespace: case Whitespace:
return nil, fmt.Errorf("Found %q (%d), expected value", t.val, t.kind) return nil, fmt.Errorf("Found %q (%d), expected value", t.val, t.kind)
} }
t = p.scan() t = p.scan()

View File

@ -102,6 +102,7 @@ func Getch() rune {
func GetLine(prefix string) (string, error) { func GetLine(prefix string) (string, error) {
termios.SetLineMode() termios.SetLineMode()
defer termios.SetCharMode()
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
fmt.Print(prefix) fmt.Print(prefix)
@ -110,7 +111,6 @@ func GetLine(prefix string) (string, error) {
return "", err return "", err
} }
termios.SetCharMode()
return text[:len(text)-1], nil return text[:len(text)-1], nil
} }

View File

@ -361,6 +361,7 @@ func parseGemini(b, currentUrl string) (string, []string) {
links := make([]string, 0, 10) links := make([]string, 0, 10)
inPreBlock := false inPreBlock := false
spacer := " "
outputIndex := 0 outputIndex := 0
for i, ln := range splitContent { for i, ln := range splitContent {
@ -371,7 +372,7 @@ func parseGemini(b, currentUrl string) (string, []string) {
alt := strings.TrimSpace(ln) alt := strings.TrimSpace(ln)
if len(alt) > 3 { if len(alt) > 3 {
alt = strings.TrimSpace(alt[3:]) alt = strings.TrimSpace(alt[3:])
splitContent[outputIndex] = fmt.Sprintf("[ %s ]", alt) splitContent[outputIndex] = fmt.Sprintf("%s[ALT][ %s ]", spacer, alt)
outputIndex++ outputIndex++
} }
} else if isPreBlockDeclaration { } else if isPreBlockDeclaration {
@ -401,7 +402,12 @@ func parseGemini(b, currentUrl string) (string, []string) {
if inPreBlock && (BlockBehavior == "alt" || BlockBehavior == "neither") { if inPreBlock && (BlockBehavior == "alt" || BlockBehavior == "neither") {
continue continue
} }
splitContent[outputIndex] = ln var leader, tail string = "", ""
if len(ln) > 0 && ln[0] == '#' {
leader = "\033[1m"
tail = "\033[0m"
}
splitContent[outputIndex] = fmt.Sprintf("%s%s%s%s", spacer, leader, ln, tail)
outputIndex++ outputIndex++
} }
} }

View File

@ -144,7 +144,8 @@ func parseMap(text string) (string, []string) {
} else { } else {
link := buildLink(line[2], line[3], string(line[0][0]), line[1]) link := buildLink(line[2], line[3], string(line[0][0]), line[1])
links = append(links, link) links = append(links, link)
linktext := fmt.Sprintf("(%s) %2d %s", getType(string(line[0][0])), len(links), title) linkNum := fmt.Sprintf("[%d]",len(links))
linktext := fmt.Sprintf("%s %5s %s", getType(string(line[0][0])), linkNum, title)
splitContent[i] = linktext splitContent[i] = linktext
} }
} }

28
help.go Normal file
View File

@ -0,0 +1,28 @@
package main
// ERRS maps commands to their syntax error message
var ERRS = map[string]string{
"A": "`a [target] [name...]`",
"ADD": "`add [target] [name...]`",
"D": "`d [bookmark-id]`",
"DELETE": "`delete [bookmark-id]`",
"B": "`b [[bookmark-id]]`",
"BOOKMARKS": "`bookmarks [[bookmark-id]]`",
"C": "`c [link_id]` or `c [setting]`",
"CHECK": "`check [link_id]` or `check [setting]`",
"H": "`h`",
"HOME": "`home`",
"P": "`p [host]`",
"PURGE": "`purge [host]`",
"Q": "`q`",
"QUIT": "`quit`",
"R": "`r`",
"RELOAD": "`reload`",
"SEARCH": "`search [[keyword(s)...]]`",
"S": "`s [setting] [value]`",
"SET": "`set [setting] [value]`",
"W": "`w [target]`",
"WRITE": "`write [target]`",
"?": "`? [[command]]`",
"HELP": "`help [[command]]`",
}

View File

@ -33,7 +33,7 @@ func Visit(webmode, url string, width int) (Page, error) {
return Page{}, fmt.Errorf("Invalid webmode setting") return Page{}, fmt.Errorf("Invalid webmode setting")
} }
c, err := exec.Command(webmode, "-dump", w, fmt.Sprintf("%d", width), url).Output() c, err := exec.Command(webmode, "-dump", w, fmt.Sprintf("%d", width), url).Output()
if err != nil { if err != nil && c == nil {
return Page{}, err return Page{}, err
} }
return parseLinks(string(c)), nil return parseLinks(string(c)), nil

14
page.go
View File

@ -72,11 +72,17 @@ func (p *Page) WrapContent(width int, color bool) {
} }
width = min(width, 100) width = min(width, 100)
counter := 0 counter := 0
spacer := " " spacer := ""
var content strings.Builder var content strings.Builder
var esc strings.Builder var esc strings.Builder
escape := false escape := false
content.Grow(len(p.RawContent)) content.Grow(len(p.RawContent))
if p.Location.Mime == "1" { // gopher document
spacer = " "
} else if strings.HasSuffix(p.Location.Mime, "gemini") { //gemini document
spacer = " "
}
for _, ch := range []rune(p.RawContent) { for _, ch := range []rune(p.RawContent) {
if escape { if escape {
if color { if color {
@ -125,10 +131,8 @@ func (p *Page) WrapContent(width int, color bool) {
} else { } else {
content.WriteRune('\n') content.WriteRune('\n')
counter = 0 counter = 0
if p.Location.Mime == "1" { content.WriteString(spacer)
content.WriteString(spacer) counter += len(spacer)
counter += len(spacer)
}
content.WriteRune(ch) content.WriteRune(ch)
counter++ counter++
} }