Browse Source

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

pull/200/head
Sloom Sloum Sluom IV 5 months ago
parent
commit
33e78753ea
  1. 1
      .gitignore
  2. 4
      DEVELOPING.md
  3. 65
      client.go
  4. 4
      cmdparse/parser.go
  5. 2
      cui/cui.go
  6. 10
      gemini/gemini.go
  7. 3
      gopher/gopher.go
  8. 28
      help.go
  9. 2
      http/http_render.go
  10. 14
      page.go

1
.gitignore

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

4
DEVELOPING.md

@ -25,10 +25,10 @@ Changes are implemented to the default branch when:
### 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. 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. If the PR is approved, it is merged.
1. The version number is incremented, along with any other release activity.

65
client.go

@ -344,23 +344,26 @@ func (c *client) simpleCommand(action string) {
case "SEARCH":
c.search("", "", "?")
case "HELP", "?":
go c.Visit(helplocation)
c.Visit(helplocation)
default:
c.SetMessage(fmt.Sprintf("Unknown action %q", action), true)
c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage()
}
}
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 {
case "CHECK", "C":
case "C", "CHECK":
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":
err := c.Certs.Purge(values[0])
if err != nil {
@ -405,24 +408,22 @@ func (c *client) doCommand(action string, values []string) {
c.saveFile(u, fn)
default:
c.SetMessage(fmt.Sprintf("Unknown action %q", action), true)
c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage()
}
}
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 {
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)
if err != nil {
c.SetMessage(err.Error(), true)
@ -441,8 +442,18 @@ func (c *client) doCommandAs(action string, values []string) {
c.Draw()
}
case "SEARCH":
if len(values) < 2 {
c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage()
return
}
c.search(strings.Join(values, " "), "", "")
case "SET", "S":
if len(values) < 2 {
c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage()
return
}
if _, ok := c.Options[values[0]]; ok {
val := strings.Join(values[1:], " ")
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.DrawMessage()
default:
c.SetMessage(fmt.Sprintf("Unknown command structure"), true)
c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage()
}
}
@ -523,7 +534,7 @@ func (c *client) doLinkCommandAs(action, target string, values []string) {
out = append(out, values...)
c.doCommandAs(action, out)
default:
c.SetMessage(fmt.Sprintf("Unknown command structure"), true)
c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage()
}
}
@ -655,7 +666,7 @@ func (c *client) doLinkCommand(action, target string) {
}
c.saveFile(u, fn)
default:
c.SetMessage("Unknown command structure", true)
c.SetMessage(syntaxErrorMessage(action), true)
c.DrawMessage()
}
@ -977,6 +988,7 @@ func (c *client) handleGemini(u Url) {
case 2:
// Success
if capsule.MimeMaj == "text" || (c.Options["showimages"] == "true" && capsule.MimeMaj == "image") {
u.Mime = capsule.MimeMin
pg := MakePage(u, capsule.Content, capsule.Links)
pg.FileType = capsule.MimeMaj
pg.WrapContent(c.Width-1, (c.Options["theme"] == "color"))
@ -1203,6 +1215,13 @@ func findAvailableFileName(fpath, fname string) (string, error) {
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 {
sec, err := strconv.Atoi(timeoutString)
if err != nil {

4
cmdparse/parser.go

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

2
cui/cui.go

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

10
gemini/gemini.go

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

3
gopher/gopher.go

@ -144,7 +144,8 @@ func parseMap(text string) (string, []string) {
} else {
link := buildLink(line[2], line[3], string(line[0][0]), line[1])
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
}
}

28
help.go

@ -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]]`",
}

2
http/http_render.go

@ -33,7 +33,7 @@ func Visit(webmode, url string, width int) (Page, error) {
return Page{}, fmt.Errorf("Invalid webmode setting")
}
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 parseLinks(string(c)), nil

14
page.go

@ -72,11 +72,17 @@ func (p *Page) WrapContent(width int, color bool) {
}
width = min(width, 100)
counter := 0
spacer := " "
spacer := ""
var content strings.Builder
var esc strings.Builder
escape := false
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) {
if escape {
if color {
@ -125,10 +131,8 @@ func (p *Page) WrapContent(width int, color bool) {
} else {
content.WriteRune('\n')
counter = 0
if p.Location.Mime == "1" {
content.WriteString(spacer)
counter += len(spacer)
}
content.WriteString(spacer)
counter += len(spacer)
content.WriteRune(ch)
counter++
}

Loading…
Cancel
Save