Merge branch 'add-color' of sloum/bombadillo into develop

This commit is contained in:
Sloom Sloum Sluom IV 2019-12-14 10:38:15 -05:00 committed by Gitea
commit 8fa7c7a635
6 changed files with 58 additions and 28 deletions

View File

@ -38,7 +38,7 @@ Basic support is provided for the finger protocol. The format is: \fIfinger://[[
.TP
.B
local
Local is similar to the \fIfile\fP protocol used in web browsers or the like, with a smaller set of features. Users can use the local scheme to view files on their local system. Directories are supported as viewable text object as well as any files. Wildcards and globbing are not supported. Using \fI~\fP to represent a user's home directory, as well as relative paths, are supported.
Local is similar to the \fIfile\fP protocol used in web browsers or the like, with a smaller set of features. Users can use the local scheme to view files on their local system. Directories are supported as viewable text object as well as any files. Wildcards and globbing are not supported. Using \fI~\fP to represent a user's home directory, as well as relative paths, are supported. The \fIcolor\fP theme has no effect on this protocol and all terminal escape sequences will be rendered to the screen literally.
.TP
.B
telnet
@ -231,7 +231,7 @@ Tells the browser what command to use to start a telnet session. Should be a val
.TP
.B
theme
Can toggle between visual modes. Valid values are \fInormal\fP and \fIinverse\fP. When set to inverse, the terminal color mode is inverted.
Can toggle between visual modes. Valid values are \fInormal\fP, \fIcolor\fP, and \fIinverse\fP. When set to inverse, the normal mode colors are inverted. Both normal and inverse modes filter out terminal escape sequences. When set to color, Bombadillo will render terminal escape sequences representing colors when it finds them in documents.
.TP
.B
tlscertificate

View File

@ -86,9 +86,12 @@ func (c *client) Draw() {
screen.WriteString("\033[0m")
screen.WriteString(c.TopBar.Render(c.Width, c.Options["theme"]))
screen.WriteString("\n")
pageContent := c.PageState.Render(c.Height, c.Width-1)
pageContent := c.PageState.Render(c.Height, c.Width-1, (c.Options["theme"] == "color"))
var re *regexp.Regexp
if c.Options["theme"] == "inverse" {
screen.WriteString("\033[7m")
} else if c.Options["theme"] == "color" {
re = regexp.MustCompile(`\033\[(?:\d*;?)+[A-Za-z]`)
}
if c.BookMarks.IsOpen {
bm := c.BookMarks.Render(c.Width, c.Height)
@ -97,7 +100,14 @@ func (c *client) Draw() {
if c.Width > bmWidth {
contentWidth := c.Width - bmWidth
if i < len(pageContent) {
screen.WriteString(fmt.Sprintf("%-*.*s", contentWidth, contentWidth, pageContent[i]))
extra := 0
if c.Options["theme"] == "color" {
escapes := re.FindAllString(pageContent[i], -1)
for _, esc := range escapes {
extra += len(esc)
}
}
screen.WriteString(fmt.Sprintf("%-*.*s", contentWidth+extra, contentWidth+extra, pageContent[i]))
} else {
screen.WriteString(fmt.Sprintf("%-*.*s", contentWidth, contentWidth, " "))
}
@ -110,6 +120,9 @@ func (c *client) Draw() {
screen.WriteString("\033[2m")
}
if c.Options["theme"] == "color" {
screen.WriteString("\033[0m")
}
screen.WriteString(bm[i])
if c.Options["theme"] == "inverse" && !c.BookMarks.IsFocused {
@ -123,7 +136,14 @@ func (c *client) Draw() {
} else {
for i := 0; i < c.Height-3; i++ {
if i < len(pageContent) {
screen.WriteString(fmt.Sprintf("%-*.*s", c.Width, c.Width, pageContent[i]))
extra := 0
if c.Options["theme"] == "color" {
escapes := re.FindAllString(pageContent[i], -1)
for _, esc := range escapes {
extra += len(esc)
}
}
screen.WriteString(fmt.Sprintf("%-*.*s", c.Width+extra, c.Width+extra, pageContent[i]))
screen.WriteString("\n")
} else {
screen.WriteString(fmt.Sprintf("%-*.*s", c.Width, c.Width, " "))
@ -219,7 +239,7 @@ func (c *client) TakeControlInput() {
// Process a command
c.ClearMessage()
c.ClearMessageLine()
if c.Options["theme"] == "normal" {
if c.Options["theme"] == "normal" || c.Options["theme"] == "color" {
fmt.Printf("\033[7m%*.*s\r", c.Width, c.Width, "")
}
entry, err := cui.GetLine()
@ -620,7 +640,7 @@ func (c *client) search(query, url, question string) {
if query == "" {
c.ClearMessage()
c.ClearMessageLine()
if c.Options["theme"] == "normal" {
if c.Options["theme"] == "normal" || c.Options["theme"] == "color" {
fmt.Printf("\033[7m%*.*s\r", c.Width, c.Width, "")
}
fmt.Print(question)
@ -773,7 +793,7 @@ func (c *client) DrawMessage() {
func (c *client) RenderMessage() string {
leadIn, leadOut := "", ""
if c.Options["theme"] == "normal" {
if c.Options["theme"] == "normal" || c.Options["theme"] == "color" {
leadIn = "\033[7m"
leadOut = "\033[0m"
}
@ -782,7 +802,7 @@ func (c *client) RenderMessage() string {
leadIn = "\033[31;1m"
leadOut = "\033[0m"
if c.Options["theme"] == "normal" {
if c.Options["theme"] == "normal" || c.Options["theme"] == "color" {
leadIn = "\033[41;1;7m"
}
}
@ -891,7 +911,7 @@ func (c *client) handleGopher(u Url) {
return
}
pg := MakePage(u, content, links)
pg.WrapContent(c.Width - 1)
pg.WrapContent(c.Width-1, (c.Options["theme"] == "color"))
c.PageState.Add(pg)
c.SetPercentRead()
c.ClearMessage()
@ -914,7 +934,7 @@ func (c *client) handleGemini(u Url) {
case 2:
if capsule.MimeMaj == "text" {
pg := MakePage(u, capsule.Content, capsule.Links)
pg.WrapContent(c.Width - 1)
pg.WrapContent(c.Width-1, (c.Options["theme"] == "color"))
c.PageState.Add(pg)
c.SetPercentRead()
c.ClearMessage()
@ -962,7 +982,7 @@ func (c *client) handleLocal(u Url) {
return
}
pg := MakePage(u, content, links)
pg.WrapContent(c.Width - 1)
pg.WrapContent(c.Width-1, (c.Options["theme"] == "color"))
c.PageState.Add(pg)
c.SetPercentRead()
c.ClearMessage()
@ -978,7 +998,7 @@ func (c *client) handleFinger(u Url) {
return
}
pg := MakePage(u, content, []string{})
pg.WrapContent(c.Width - 1)
pg.WrapContent(c.Width-1, (c.Options["theme"] == "color"))
c.PageState.Add(pg)
c.SetPercentRead()
c.ClearMessage()
@ -998,7 +1018,7 @@ func (c *client) handleWeb(u Url) {
return
}
pg := MakePage(u, page.Content, page.Links)
pg.WrapContent(c.Width - 1)
pg.WrapContent(c.Width-1, (c.Options["theme"] == "color"))
c.PageState.Add(pg)
c.SetPercentRead()
c.ClearMessage()

View File

@ -51,7 +51,7 @@ var defaultOptions = map[string]string{
"telnetcommand": "telnet",
"configlocation": xdgConfigPath(),
"defaultscheme": "gopher", // "gopher", "gemini", "http", "https"
"theme": "normal", // "normal", "inverted"
"theme": "normal", // "normal", "inverted", "color"
"tlscertificate": "",
"tlskey": "",
"webmode": "none", // "none", "gui", "lynx", "w3m", "elinks"

12
main.go
View File

@ -47,10 +47,6 @@ func saveConfig() error {
opts.WriteString("\n[SETTINGS]\n")
for k, v := range bombadillo.Options {
if k == "theme" && v != "normal" && v != "inverse" {
v = "normal"
bombadillo.Options["theme"] = "normal"
}
opts.WriteString(k)
opts.WriteRune('=')
opts.WriteString(v)
@ -67,7 +63,7 @@ func saveConfig() error {
func validateOpt(opt, val string) bool {
var validOpts = map[string][]string{
"webmode": []string{"none", "gui", "lynx", "w3m", "elinks"},
"theme": []string{"normal", "inverse"},
"theme": []string{"normal", "inverse", "color"},
"defaultscheme": []string{"gopher", "gemini", "http", "https"},
}
@ -117,11 +113,7 @@ func loadConfig() {
for _, v := range settings.Settings {
lowerkey := strings.ToLower(v.Key)
if lowerkey == "configlocation" {
// The config defaults to the home folder.
// Users cannot really edit this value. But
// a compile time override is available.
// It is still stored in the ini and as a part
// of the options map.
// Read only
continue
}

20
page.go
View File

@ -47,15 +47,23 @@ func (p *Page) ScrollPositionRange(termHeight int) (int, int) {
// width and updates the WrappedContent
// of the Page struct width a string slice
// of the wrapped data
func (p *Page) WrapContent(width int) {
func (p *Page) WrapContent(width int, color bool) {
counter := 0
var content strings.Builder
var esc strings.Builder
escape := false
content.Grow(len(p.RawContent))
for _, ch := range []rune(p.RawContent) {
if escape {
if color {
esc.WriteRune(ch)
}
if (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') {
escape = false
if ch == 'm' {
content.WriteString(esc.String())
esc.Reset()
}
}
continue
}
@ -74,7 +82,17 @@ func (p *Page) WrapContent(width int) {
// Get rid of control characters we dont want
continue
} else if ch == 27 {
if p.Location.Scheme == "local" {
if counter+4 >= width {
content.WriteRune('\n')
}
content.WriteString("\\033")
continue
}
escape = true
if color {
esc.WriteRune(ch)
}
continue
} else {
if counter < width {

View File

@ -60,13 +60,13 @@ func (p *Pages) Add(pg Page) {
// Render wraps the content for the current page and returns
// the page content as a string slice
func (p *Pages) Render(termHeight, termWidth int) []string {
func (p *Pages) Render(termHeight, termWidth int, color bool) []string {
if p.Length < 1 {
return make([]string, 0)
}
pos := p.History[p.Position].ScrollPosition
prev := len(p.History[p.Position].WrappedContent)
p.History[p.Position].WrapContent(termWidth)
p.History[p.Position].WrapContent(termWidth, color)
now := len(p.History[p.Position].WrappedContent)
if prev > now {
diff := prev - now