~rafael/gembro

eb2deeb2e37de9c37c7620113bec2314d2c2f1d8 — Rafaël L. Bekkema 3 years ago 2931127
Open URLs by typing number
4 files changed, 54 insertions(+), 10 deletions(-)

M gemini/gemtext.go
M gopher/gopher.go
M text/links.go
M viewport.go
M gemini/gemtext.go => gemini/gemtext.go +3 -2
@@ 53,8 53,9 @@ func ToANSI(data string, availableWidth int, baseURL neturl.URL) (
			if furl.Scheme != "gemini" {
				extra = fmt.Sprintf(" (%s)", furl.Scheme)
			}
			fmt.Fprintf(&s, "> %s%s\n", text.Color(l.Name, text.Clink), extra)
			links.Add(ypos, furl.String(), l.Name)
			count := links.Count() + 1
			links.Add(ypos, count, furl.String(), l.Name)
			fmt.Fprintf(&s, "%d> %s %s\n", count, text.Color(l.Name, text.Clink), extra)
			ypos++
			continue
		}

M gopher/gopher.go => gopher/gopher.go +3 -2
@@ 46,8 46,9 @@ func ToANSI(data []byte, typ byte) (s string, links text.Links) {
			} else {
				url = fmt.Sprintf("gopher://%s:%s/%c%s", f[2], f[3], line[0], f[1])
			}
			links.Add(ypos, url, f[0])
			fmt.Fprintf(&buf, "%s", text.Color(f[0], text.Clink))
			count := links.Count() + 1
			links.Add(ypos, count, url, f[0])
			fmt.Fprintf(&buf, "%d> %s", count, text.Color(f[0], text.Clink))
			switch {
			case external:
				fmt.Fprintf(&buf, " (%s)\n", strings.Split(url, "://")[0])

M text/links.go => text/links.go +16 -2
@@ 2,17 2,18 @@ package text

type Link struct {
	URL, Name string
	index     int
}

type Links struct {
	links map[int]Link
}

func (l *Links) Add(ypos int, url, name string) {
func (l *Links) Add(ypos, index int, url, name string) {
	if l.links == nil {
		l.links = make(map[int]Link)
	}
	l.links[ypos] = Link{url, name}
	l.links[ypos] = Link{url, name, index}
}

func (l Links) LinkAt(y int) *Link {


@@ 21,3 22,16 @@ func (l Links) LinkAt(y int) *Link {
	}
	return nil
}

func (l Links) Number(n int) *Link {
	for _, l := range l.links {
		if l.index == n {
			return &l
		}
	}
	return nil
}

func (l *Links) Count() int {
	return len(l.links)
}

M viewport.go => viewport.go +32 -4
@@ 4,6 4,7 @@ import (
	"fmt"
	"log"
	neturl "net/url"
	"strconv"
	"strings"

	"git.sr.ht/~rafael/gembro/gemini"


@@ 38,6 39,7 @@ type Viewport struct {
	links     text.Links
	lastEvent tea.MouseEventType
	history   *history.History
	digits    string
}

func NewViewport(startURL string, h *history.History) Viewport {


@@ 122,21 124,44 @@ func (v Viewport) Update(msg tea.Msg) (Viewport, tea.Cmd) {
		v, cmd = v.handleMouse(msg)
		cmds = append(cmds, cmd)
	case tea.KeyMsg:
		switch msg.String() {
		switch key := msg.String(); key {
		case "q":
			return v, v.handleButtonClick(buttonCloseTab)
		case "g":
			return v, v.handleButtonClick(buttonGoto)
		case "d":
			return v, v.handleButtonClick(buttonDownload)
		case "h":
		case "H":
			return v, v.handleButtonClick(buttonHome)
		case "b":
			return v, v.handleButtonClick(buttonBookmark)
		case "left":
		case "left", "h":
			return v, v.handleButtonClick(buttonBack)
		case "right":
		case "right", "l":
			return v, v.handleButtonClick(buttonFwd)
		case "esc":
			v.digits = ""
			return v, nil
		case "backspace":
			if len(v.digits) > 0 {
				v.digits = v.digits[0 : len(v.digits)-1]
				return v, nil
			}
		case "enter", "t":
			num, _ := strconv.Atoi(v.digits)
			link := v.links.Number(num)
			if link != nil {
				v.digits = ""
				if key == "t" {
					return v, fireEvent(OpenNewTabEvent{URL: link.URL, Switch: true})
				}
				return v, fireEvent(LoadURLEvent{URL: link.URL, AddHistory: true})
			}
		default:
			if "0" <= key && key <= "9" {
				v.digits += key
				return v, nil
			}
		}
	case ButtonClickEvent:
		return v, v.handleButtonClick(msg.Button)


@@ 192,6 217,9 @@ func (v Viewport) View() string {
	if v.loading {
		headerTail = fmt.Sprintf(" :: %s", v.spinner.View())
	}
	if v.digits != "" {
		headerTail = fmt.Sprintf("%s :: %s", headerTail, v.digits)
	}
	header := fmt.Sprintf("%s%s ", v.URL, headerTail)
	gapSize := v.viewport.Width - text.RuneCount(header)
	header += strings.Repeat("─", gapSize)