ANSI compression is now opt-in via the WithANSICompressor program option

This commit is contained in:
Christian Rocha 2021-10-30 12:29:30 -04:00
parent 56aa4efb60
commit 119144e78c
3 changed files with 38 additions and 15 deletions

View File

@ -119,3 +119,14 @@ func WithoutRenderer() ProgramOption {
m.renderer = &nilRenderer{}
}
}
// WithANSICompressor removes redundant ANSI sequences to produce potentially
// smaller output, at the cost of some processing overhead.
//
// This feature is provisional, and may be changed removed in a future version
// of this package.
func WithANSICompressor() ProgramOption {
return func(p *Program) {
p.startupOptions |= withANSICompressor
}
}

View File

@ -23,14 +23,15 @@ const (
// In cases where very high performance is needed the renderer can be told
// to exclude ranges of lines, allowing them to be written to directly.
type standardRenderer struct {
out io.WriteCloser
buf bytes.Buffer
framerate time.Duration
ticker *time.Ticker
mtx *sync.Mutex
done chan struct{}
lastRender string
linesRendered int
out io.Writer
buf bytes.Buffer
framerate time.Duration
ticker *time.Ticker
mtx *sync.Mutex
done chan struct{}
lastRender string
linesRendered int
useANSICompressor bool
// essentially whether or not we're using the full size of the terminal
altScreenActive bool
@ -45,12 +46,17 @@ type standardRenderer struct {
// newRenderer creates a new renderer. Normally you'll want to initialize it
// with os.Stdout as the first argument.
func newRenderer(out io.Writer, mtx *sync.Mutex) renderer {
return &standardRenderer{
out: &compressor.Writer{Forward: out},
mtx: mtx,
framerate: defaultFramerate,
func newRenderer(out io.Writer, mtx *sync.Mutex, useANSICompressor bool) renderer {
r := &standardRenderer{
out: out,
mtx: mtx,
framerate: defaultFramerate,
useANSICompressor: useANSICompressor,
}
if r.useANSICompressor {
r.out = &compressor.Writer{Forward: out}
}
return r
}
// start starts the renderer.
@ -67,7 +73,12 @@ func (r *standardRenderer) stop() {
r.flush()
clearLine(r.out)
close(r.done)
r.out.Close()
if r.useANSICompressor {
if w, ok := r.out.(io.WriteCloser); ok {
_ = w.Close()
}
}
}
// kill halts the renderer. The final frame will not be rendered.

3
tea.go
View File

@ -71,6 +71,7 @@ const (
withMouseAllMotion
withInputTTY
withCustomInput
withANSICompressor
)
// Program is a terminal user interface.
@ -360,7 +361,7 @@ func (p *Program) StartReturningModel() (Model, error) {
// If no renderer is set use the standard one.
if p.renderer == nil {
p.renderer = newRenderer(p.output, p.mtx)
p.renderer = newRenderer(p.output, p.mtx, p.startupOptions.has(withANSICompressor))
}
// Honor program startup options.