1
0
mirror of https://github.com/makew0rld/amfora.git synced 2024-12-04 14:46:29 -05:00
amfora/render/renderer.go

92 lines
2.2 KiB
Go

package render
import (
"bytes"
"fmt"
"io"
"github.com/makeworld-the-better-one/amfora/config"
"github.com/spf13/viper"
"gitlab.com/tslocum/cview"
)
// Renderer renderers network bytes into something that can be displayed on a
// cview.TextView.
type Renderer interface {
io.ReadWriter
// Links returns a channel that yields Link URLs as they are parsed.
// It is buffered. The channel might be closed to indicate links are supported
// for this renderer.
Links() <-chan string
}
type PlaintextRenderer struct {
*io.PipeReader
w *io.PipeWriter
}
func NewPlaintextRenderer() *PlaintextRenderer {
pr, pw := io.Pipe()
return &PlaintextRenderer{pr, pw}
}
func (r *PlaintextRenderer) Write(p []byte) (n int, err error) {
// TODO: The escaping will fail if the Write bytes end in the middle of a tag
// How can this be avoided by users of this func?
return r.w.Write(cview.EscapeBytes(p))
}
func (r *PlaintextRenderer) Links() <-chan string {
ch := make(chan string)
close(ch)
return ch
}
type ANSIRenderer struct {
*io.PipeReader
pw *io.PipeWriter
ansiWriter io.Writer // cview.ANSIWriter
buf bytes.Buffer
}
func NewANSIRenderer() *ANSIRenderer {
pr, pw := io.Pipe()
var ansiWriter io.Writer = nil // When ANSI is disabled
var buf bytes.Buffer
if viper.GetBool("a-general.color") && viper.GetBool("a-general.ansi") {
// ANSI enabled
ansiWriter = cview.ANSIWriter(&buf)
}
return &ANSIRenderer{pr, pw, ansiWriter, buf}
}
func (r *ANSIRenderer) Write(p []byte) (n int, err error) {
if r.ansiWriter == nil {
// ANSI disabled
return r.pw.Write(ansiRegex.ReplaceAll(p, []byte{}))
}
// ANSI enabled
r.buf.Reset()
r.ansiWriter.Write(p) // Shouldn't error because everything it writes to are all bytes.Buffer
return r.pw.Write(
// The ANSIWriter injects tags like [-:-:-]
// but this will reset the background to use the user's terminal color.
// These tags need to be replaced with resets that use the theme color.
bytes.ReplaceAll(
r.buf.Bytes(),
[]byte("[-:-:-]"),
[]byte(fmt.Sprintf("[-:%s:-]", config.GetColorString("bg"))),
),
)
}
func (r *ANSIRenderer) Links() <-chan string {
ch := make(chan string)
close(ch)
return ch
}