forked from sloum/bombadillo
Worked out resizing and wrapping bugs. Now hard wraps, rather than soft.
This commit is contained in:
parent
bccca61ec2
commit
98e34576ca
|
@ -106,11 +106,11 @@ func (b Bookmarks) Render(termwidth, termheight int) []string {
|
||||||
bl = cui.Shapes["bl"]
|
bl = cui.Shapes["bl"]
|
||||||
}
|
}
|
||||||
|
|
||||||
out := make([]string, 5)
|
out := make([]string, 0, 5)
|
||||||
top := fmt.Sprintf("%s%s%s", tl, strings.Repeat(ceil, width-2), tr)
|
top := fmt.Sprintf("%s%s%s", tl, strings.Repeat(ceil, width-2), tr)
|
||||||
out = append(out, top)
|
out = append(out, top)
|
||||||
marks := b.List()
|
marks := b.List()
|
||||||
contentWidth := termwidth - 2
|
contentWidth := width - 2
|
||||||
for i := 0; i < termheight - 2; i++ {
|
for i := 0; i < termheight - 2; i++ {
|
||||||
if i + b.Position >= b.Length {
|
if i + b.Position >= b.Length {
|
||||||
out = append(out, fmt.Sprintf("%s%-*.*s%s", wall, contentWidth, contentWidth, "", wall ))
|
out = append(out, fmt.Sprintf("%s%-*.*s%s", wall, contentWidth, contentWidth, "", wall ))
|
||||||
|
|
72
client.go
72
client.go
|
@ -59,32 +59,45 @@ func (c *client) GetSize() {
|
||||||
c.Height = h
|
c.Height = h
|
||||||
c.Width = w
|
c.Width = w
|
||||||
|
|
||||||
|
|
||||||
if redraw {
|
if redraw {
|
||||||
c.Draw()
|
c.Draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(500 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) Draw() {
|
func (c *client) Draw() {
|
||||||
var screen strings.Builder
|
var screen strings.Builder
|
||||||
screen.Grow(c.Height * c.Width)
|
screen.Grow(c.Height * c.Width)
|
||||||
screen.WriteString(c.TopBar.Render(c.Width, "This is a test"))
|
screen.WriteString(c.TopBar.Render(c.Width))
|
||||||
screen.WriteString("\n")
|
screen.WriteString("\n")
|
||||||
pageContent := c.PageState.Render(c.Height)
|
pageContent := c.PageState.Render(c.Height, c.Width)
|
||||||
if c.BookMarks.IsOpen {
|
if c.BookMarks.IsOpen {
|
||||||
bm := c.BookMarks.Render(c.Width, c.Height)
|
bm := c.BookMarks.Render(c.Width, c.Height)
|
||||||
bmWidth := len([]rune(bm[0]))
|
bmWidth := 40
|
||||||
for i, ln := range pageContent {
|
for i := 0; i < c.Height - 3; i++ {
|
||||||
screen.WriteString(ln[:len(ln) - bmWidth])
|
if c.Width > bmWidth {
|
||||||
|
contentWidth := c.Width - bmWidth - 1
|
||||||
|
if i < len(pageContent) - 1 {
|
||||||
|
screen.WriteString(fmt.Sprintf("%-*.*s", contentWidth, contentWidth, pageContent[i]))
|
||||||
|
} else {
|
||||||
|
screen.WriteString(fmt.Sprintf("%-*.*s", contentWidth, contentWidth, " "))
|
||||||
|
}
|
||||||
|
}
|
||||||
screen.WriteString(bm[i])
|
screen.WriteString(bm[i])
|
||||||
screen.WriteString("\n")
|
screen.WriteString("\n")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, ln := range pageContent {
|
for i := 0; i < c.Height - 3; i++ {
|
||||||
screen.WriteString(ln)
|
if i < len(pageContent) - 1 {
|
||||||
screen.WriteString("\n")
|
screen.WriteString(pageContent[i])
|
||||||
|
screen.WriteString("\n")
|
||||||
|
} else {
|
||||||
|
screen.WriteString(fmt.Sprintf("%*s", c.Width, " "))
|
||||||
|
screen.WriteString("\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
screen.WriteString("\n") // for the input line
|
screen.WriteString("\n") // for the input line
|
||||||
|
@ -92,6 +105,7 @@ func (c *client) Draw() {
|
||||||
cui.Clear("screen")
|
cui.Clear("screen")
|
||||||
cui.MoveCursorTo(0,0)
|
cui.MoveCursorTo(0,0)
|
||||||
fmt.Print(screen.String())
|
fmt.Print(screen.String())
|
||||||
|
c.DrawMessage()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) TakeControlInput() {
|
func (c *client) TakeControlInput() {
|
||||||
|
@ -100,34 +114,49 @@ func (c *client) TakeControlInput() {
|
||||||
switch input {
|
switch input {
|
||||||
case 'j', 'J':
|
case 'j', 'J':
|
||||||
// scroll down one line
|
// scroll down one line
|
||||||
|
c.ClearMessage()
|
||||||
|
c.ClearMessageLine()
|
||||||
c.Scroll(1)
|
c.Scroll(1)
|
||||||
case 'k', 'K':
|
case 'k', 'K':
|
||||||
// scroll up one line
|
// scroll up one line
|
||||||
|
c.ClearMessage()
|
||||||
|
c.ClearMessageLine()
|
||||||
c.Scroll(-1)
|
c.Scroll(-1)
|
||||||
case 'q', 'Q':
|
case 'q', 'Q':
|
||||||
// quite bombadillo
|
// quite bombadillo
|
||||||
cui.Exit()
|
cui.Exit()
|
||||||
case 'g':
|
case 'g':
|
||||||
// scroll to top
|
// scroll to top
|
||||||
|
c.ClearMessage()
|
||||||
|
c.ClearMessageLine()
|
||||||
c.Scroll(-len(c.PageState.History[c.PageState.Position].WrappedContent))
|
c.Scroll(-len(c.PageState.History[c.PageState.Position].WrappedContent))
|
||||||
case 'G':
|
case 'G':
|
||||||
// scroll to bottom
|
// scroll to bottom
|
||||||
|
c.ClearMessage()
|
||||||
|
c.ClearMessageLine()
|
||||||
c.Scroll(len(c.PageState.History[c.PageState.Position].WrappedContent))
|
c.Scroll(len(c.PageState.History[c.PageState.Position].WrappedContent))
|
||||||
case 'd':
|
case 'd':
|
||||||
// scroll down 75%
|
// scroll down 75%
|
||||||
|
c.ClearMessage()
|
||||||
|
c.ClearMessageLine()
|
||||||
distance := c.Height - c.Height / 4
|
distance := c.Height - c.Height / 4
|
||||||
c.Scroll(distance)
|
c.Scroll(distance)
|
||||||
case 'u':
|
case 'u':
|
||||||
// scroll up 75%
|
// scroll up 75%
|
||||||
|
c.ClearMessage()
|
||||||
|
c.ClearMessageLine()
|
||||||
distance := c.Height - c.Height / 4
|
distance := c.Height - c.Height / 4
|
||||||
c.Scroll(-distance)
|
c.Scroll(-distance)
|
||||||
case 'b':
|
case 'b':
|
||||||
// go back
|
// go back
|
||||||
|
c.ClearMessage()
|
||||||
|
c.ClearMessageLine()
|
||||||
err := c.PageState.NavigateHistory(-1)
|
err := c.PageState.NavigateHistory(-1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.SetMessage(err.Error(), false)
|
c.SetMessage(err.Error(), false)
|
||||||
c.DrawMessage()
|
c.DrawMessage()
|
||||||
} else {
|
} else {
|
||||||
|
c.SetHeaderUrl()
|
||||||
c.Draw()
|
c.Draw()
|
||||||
}
|
}
|
||||||
case 'B':
|
case 'B':
|
||||||
|
@ -136,11 +165,14 @@ func (c *client) TakeControlInput() {
|
||||||
c.Draw()
|
c.Draw()
|
||||||
case 'f', 'F':
|
case 'f', 'F':
|
||||||
// go forward
|
// go forward
|
||||||
|
c.ClearMessage()
|
||||||
|
c.ClearMessageLine()
|
||||||
err := c.PageState.NavigateHistory(1)
|
err := c.PageState.NavigateHistory(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.SetMessage(err.Error(), false)
|
c.SetMessage(err.Error(), false)
|
||||||
c.DrawMessage()
|
c.DrawMessage()
|
||||||
} else {
|
} else {
|
||||||
|
c.SetHeaderUrl()
|
||||||
c.Draw()
|
c.Draw()
|
||||||
}
|
}
|
||||||
case '\t':
|
case '\t':
|
||||||
|
@ -151,7 +183,6 @@ func (c *client) TakeControlInput() {
|
||||||
// Process a command
|
// Process a command
|
||||||
c.ClearMessage()
|
c.ClearMessage()
|
||||||
c.ClearMessageLine()
|
c.ClearMessageLine()
|
||||||
cui.MoveCursorTo(c.Height-2, 0)
|
|
||||||
entry, err := cui.GetLine()
|
entry, err := cui.GetLine()
|
||||||
c.ClearMessageLine()
|
c.ClearMessageLine()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -378,13 +409,13 @@ func (c *client) search() {
|
||||||
|
|
||||||
func (c *client) Scroll(amount int) {
|
func (c *client) Scroll(amount int) {
|
||||||
page := c.PageState.History[c.PageState.Position]
|
page := c.PageState.History[c.PageState.Position]
|
||||||
bottom := len(page.WrappedContent) - c.Height
|
bottom := len(page.WrappedContent) - c.Height + 3 // 3 for the three bars: top, msg, bottom
|
||||||
if amount < 0 && page.ScrollPosition == 0 {
|
if amount < 0 && page.ScrollPosition == 0 {
|
||||||
c.SetMessage("You are already at the top", false)
|
c.SetMessage("You are already at the top", false)
|
||||||
c.DrawMessage()
|
c.DrawMessage()
|
||||||
fmt.Print("\a")
|
fmt.Print("\a")
|
||||||
return
|
return
|
||||||
} else if amount > 0 && page.ScrollPosition == bottom || bottom < 0 {
|
} else if (amount > 0 && page.ScrollPosition == bottom) || bottom < 0 {
|
||||||
c.SetMessage("You are already at the bottom", false)
|
c.SetMessage("You are already at the bottom", false)
|
||||||
c.DrawMessage()
|
c.DrawMessage()
|
||||||
fmt.Print("\a")
|
fmt.Print("\a")
|
||||||
|
@ -398,7 +429,7 @@ func (c *client) Scroll(amount int) {
|
||||||
newScrollPosition = bottom
|
newScrollPosition = bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
page.ScrollPosition = newScrollPosition
|
c.PageState.History[c.PageState.Position].ScrollPosition = newScrollPosition
|
||||||
c.Draw()
|
c.Draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,9 +495,15 @@ func (c *client) goToLink(l string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.SetMessage(fmt.Sprintf("Invalid link id: %s", l), true)
|
func (c *client) SetHeaderUrl() {
|
||||||
c.DrawMessage()
|
if c.PageState.Length > 0 {
|
||||||
|
u := c.PageState.History[c.PageState.Position].Location.Full
|
||||||
|
c.TopBar.url = u
|
||||||
|
} else {
|
||||||
|
c.TopBar.url = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) Visit(url string) {
|
func (c *client) Visit(url string) {
|
||||||
|
@ -487,6 +524,8 @@ func (c *client) Visit(url string) {
|
||||||
c.DrawMessage()
|
c.DrawMessage()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
c.SetMessage("Loading...", false)
|
||||||
|
c.DrawMessage()
|
||||||
content, links, err := gopher.Visit(u.Mime, u.Host, u.Port, u.Resource)
|
content, links, err := gopher.Visit(u.Mime, u.Host, u.Port, u.Resource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.SetMessage(err.Error(), true)
|
c.SetMessage(err.Error(), true)
|
||||||
|
@ -496,6 +535,9 @@ func (c *client) Visit(url string) {
|
||||||
pg := MakePage(u, content, links)
|
pg := MakePage(u, content, links)
|
||||||
pg.WrapContent(c.Width)
|
pg.WrapContent(c.Width)
|
||||||
c.PageState.Add(pg)
|
c.PageState.Add(pg)
|
||||||
|
c.ClearMessage()
|
||||||
|
c.ClearMessageLine()
|
||||||
|
c.SetHeaderUrl()
|
||||||
c.Draw()
|
c.Draw()
|
||||||
case "gemini":
|
case "gemini":
|
||||||
// TODO send over to gemini request
|
// TODO send over to gemini request
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
type Headbar struct {
|
type Headbar struct {
|
||||||
title string
|
title string
|
||||||
|
url string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,9 +28,9 @@ func (h *Headbar) Draw() {
|
||||||
// without having to redraw everything else
|
// without having to redraw everything else
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Headbar) Render(width int, message string) string {
|
func (h *Headbar) Render(width int) string {
|
||||||
maxMsgWidth := width - len([]rune(h.title))
|
maxMsgWidth := width - len([]rune(h.title))
|
||||||
return fmt.Sprintf("\033[7m%s%-*.*s\033[0m", h.title, maxMsgWidth, maxMsgWidth, message)
|
return fmt.Sprintf("\033[7m%s%-*.*s\033[0m", h.title, maxMsgWidth, maxMsgWidth, h.url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,6 +39,6 @@ func (h *Headbar) Render(width int, message string) string {
|
||||||
//--------------------------------------------------\\
|
//--------------------------------------------------\\
|
||||||
|
|
||||||
func MakeHeadbar(title string) Headbar {
|
func MakeHeadbar(title string) Headbar {
|
||||||
return Headbar{title}
|
return Headbar{title, ""}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
main.go
8
main.go
|
@ -163,6 +163,10 @@ func loadConfig() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i, v := range settings.Bookmarks.Titles {
|
||||||
|
bombadillo.BookMarks.Add([]string{v, settings.Bookmarks.Links[i]})
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,8 +178,8 @@ func initClient() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// cui.HandleAlternateScreen("smcup")
|
cui.HandleAlternateScreen("smcup")
|
||||||
// defer cui.Exit()
|
defer cui.Exit()
|
||||||
err := initClient()
|
err := initClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// if we can't initialize we should bail out
|
// if we can't initialize we should bail out
|
||||||
|
|
45
page.go
45
page.go
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"bytes"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//------------------------------------------------\\
|
//------------------------------------------------\\
|
||||||
|
@ -42,35 +41,31 @@ func (p *Page) ScrollPositionRange(termHeight int) (int, int) {
|
||||||
func (p *Page) WrapContent(width int) {
|
func (p *Page) WrapContent(width int) {
|
||||||
// TODO this is a temporary wrapping function
|
// TODO this is a temporary wrapping function
|
||||||
// in order to test. Rebuild it.
|
// in order to test. Rebuild it.
|
||||||
src := strings.Split(p.RawContent, "\n")
|
counter := 0
|
||||||
out := []string{}
|
var content strings.Builder
|
||||||
for _, ln := range src {
|
content.Grow(len(p.RawContent))
|
||||||
if len([]rune(ln)) <= width {
|
for _, ch := range p.RawContent {
|
||||||
out = append(out, ln)
|
if ch == '\n' {
|
||||||
|
content.WriteRune(ch)
|
||||||
|
counter = 0
|
||||||
} else {
|
} else {
|
||||||
words := strings.SplitAfter(ln, " ")
|
if counter < width {
|
||||||
var subout bytes.Buffer
|
content.WriteRune(ch)
|
||||||
for i, wd := range words {
|
counter++
|
||||||
sublen := subout.Len()
|
} else {
|
||||||
wdlen := len([]rune(wd))
|
content.WriteRune('\n')
|
||||||
if sublen+wdlen <= width {
|
counter = 0
|
||||||
subout.WriteString(wd)
|
if p.Location.Mime == "1" {
|
||||||
if i == len(words)-1 {
|
spacer := " "
|
||||||
out = append(out, subout.String())
|
content.WriteString(spacer)
|
||||||
}
|
counter += len(spacer)
|
||||||
} else {
|
|
||||||
out = append(out, subout.String())
|
|
||||||
subout.Reset()
|
|
||||||
subout.WriteString(wd)
|
|
||||||
if i == len(words)-1 {
|
|
||||||
out = append(out, subout.String())
|
|
||||||
subout.Reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
content.WriteRune(ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.WrappedContent = out
|
|
||||||
|
p.WrappedContent = strings.Split(content.String(), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------\\
|
//------------------------------------------------\\
|
||||||
|
|
30
pages.go
30
pages.go
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//------------------------------------------------\\
|
//------------------------------------------------\\
|
||||||
|
@ -49,13 +48,32 @@ func (p *Pages) Add(pg Page) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pages) Render(termHeight int) []string {
|
func (p *Pages) Render(termHeight, termWidth int) []string {
|
||||||
if p.Length < 1 {
|
if p.Length < 1 {
|
||||||
msg := "Welcome to Bombadillo,\nif this is your first time here\ntype:\n\n:help\n(and then press enter)"
|
return []string{""}
|
||||||
return strings.Split(msg, "\n")
|
|
||||||
}
|
}
|
||||||
beg, end := p.History[p.Position].ScrollPositionRange(termHeight)
|
pos := p.History[p.Position].ScrollPosition
|
||||||
return p.History[p.Position].WrappedContent[beg:end]
|
prev := len(p.History[p.Position].WrappedContent)
|
||||||
|
p.History[p.Position].WrapContent(termWidth)
|
||||||
|
now := len(p.History[p.Position].WrappedContent)
|
||||||
|
if prev > now {
|
||||||
|
diff := prev - now
|
||||||
|
pos = pos - diff
|
||||||
|
} else if prev < now {
|
||||||
|
diff := now - prev
|
||||||
|
pos = pos + diff
|
||||||
|
if pos > now - termHeight {
|
||||||
|
pos = now - termHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if pos < 0 || now < termHeight - 3 {
|
||||||
|
pos = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
p.History[p.Position].ScrollPosition = pos
|
||||||
|
|
||||||
|
return p.History[p.Position].WrappedContent[pos:]
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------\\
|
//------------------------------------------------\\
|
||||||
|
|
2
url.go
2
url.go
|
@ -78,7 +78,7 @@ func MakeUrl(u string) (Url, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if out.Scheme == "gopher" && out.Mime == "" {
|
if out.Scheme == "gopher" && out.Mime == "" {
|
||||||
out.Mime = "0"
|
out.Mime = "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
if out.Mime == "" && (out.Resource == "" || out.Resource == "/") && out.Scheme == "gopher" {
|
if out.Mime == "" && (out.Resource == "" || out.Resource == "/") && out.Scheme == "gopher" {
|
||||||
|
|
Loading…
Reference in New Issue