Adds support for a new color theme mode

This commit is contained in:
sloumdrone 2019-12-10 21:56:41 -08:00
parent ccc694fb2f
commit 021678d9da
6 changed files with 49 additions and 27 deletions

View File

@ -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 mode is inverted. When set to color, Bombadillo will render color codes 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"

16
main.go
View File

@ -47,10 +47,10 @@ 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"
}
// if k == "theme" && v != "normal" && v != "inverse" {
// v = "normal"
// bombadillo.Options["theme"] = "normal"
// }
opts.WriteString(k)
opts.WriteRune('=')
opts.WriteString(v)
@ -67,7 +67,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 +117,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
}

View File

@ -47,7 +47,7 @@ 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
escape := false
@ -57,6 +57,9 @@ func (p *Page) WrapContent(width int) {
if (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') {
escape = false
}
if color {
content.WriteRune(ch)
}
continue
}
if ch == '\n' {
@ -75,6 +78,9 @@ func (p *Page) WrapContent(width int) {
continue
} else if ch == 27 {
escape = true
if color {
content.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