summaryrefslogtreecommitdiff
path: root/state.go
blob: 17d595d6263a744d1b98472cafcecfc5979f8aec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package main

import (
	"bytes"
	"errors"
	"fmt"
	"net/url"
	"os"
	"os/exec"

	"github.com/charmbracelet/lipgloss"
	"github.com/chzyer/readline"
)

type BrowserState struct {
	*History
	*Config

	Modal []byte

	Marks map[string]string

	Identities Identities

	NamedTours  map[string]*Tour
	DefaultTour Tour
	CurrentTour *Tour

	Readline *readline.Instance
	Printer  Printer
}

type History struct {
	Url *url.URL

	Depth     int
	DocType   string
	Body      []byte
	Formatted string
	Links     []Link

	Back    *History
	Forward *History

	// Non-negative if we browsed here via a page link, else -1.
	//
	// The non-negative value is the index in the "back" page's
	// list of links that got us here.
	NavIndex int
}

type Link struct {
	Text   string
	Target *url.URL
	Prompt bool
}

func NewBrowserState(conf *Config) *BrowserState {
	state := &BrowserState{
		History: &History{
			Url:      nil,
			Depth:    0,
			NavIndex: -1,
		},
		Config: conf,
	}
	state.CurrentTour = &state.DefaultTour
	return state
}

type Printer interface {
	PrintModal(*BrowserState, []byte) error
	PrintPage(*BrowserState, string) error
	PrintError(string) error
}

type PromptPrinter struct{}

func (PromptPrinter) PrintModal(state *BrowserState, contents []byte) error {
	_, err := os.Stdout.Write(contents)
	return err
}

func (PromptPrinter) PrintPage(state *BrowserState, body string) error {
	if state.Quiet {
		return nil
	}

	lessarg := []string{"-R"}
	switch state.Pager {
	case "auto":
		lessarg = append(lessarg, "-F")
		fallthrough
	case "always":
		less, err := exec.LookPath("less")
		if err != nil {
			return err
		}
		cmd := exec.Command(less, lessarg...)
		cmd.Stdin = bytes.NewBufferString(body)
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		return cmd.Run()
	case "never":
		_, err := os.Stdout.WriteString(body)
		return err
	default:
		return errors.New("invalid 'pager' value in configuration")
	}
}

var promptErrorStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("196")).Bold(true)

func (PromptPrinter) PrintError(msg string) error {
	_, err := fmt.Println(promptErrorStyle.Render(msg))
	return err
}