forked from sloum/bombadillo
Merge branch 'add-color' of sloum/bombadillo into develop
This commit is contained in:
commit
8fa7c7a635
|
@ -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
|
||||
|
|
44
client.go
44
client.go
|
@ -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()
|
||||
|
|
|
@ -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
12
main.go
|
@ -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
20
page.go
|
@ -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 {
|
||||
|
|
4
pages.go
4
pages.go
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue