129 lines
2.3 KiB
Go
129 lines
2.3 KiB
Go
package cmd
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"code.icb4dc0.de/buildr/buildr/internal/tui"
|
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
"github.com/charmbracelet/glamour"
|
|
"github.com/muesli/termenv"
|
|
)
|
|
|
|
var (
|
|
_ Pager = (*TUIPager)(nil)
|
|
_ Pager = (*CommandPager)(nil)
|
|
)
|
|
|
|
func NewTUIPager(title string) (*TUIPager, error) {
|
|
renderer, err := glamour.NewTermRenderer(
|
|
glamour.WithStyles(glamour.DraculaStyleConfig),
|
|
glamour.WithEmoji(),
|
|
glamour.WithAutoStyle(),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &TUIPager{
|
|
title: title,
|
|
renderer: renderer,
|
|
}, nil
|
|
}
|
|
|
|
type TUIPager struct {
|
|
renderer *glamour.TermRenderer
|
|
title string
|
|
}
|
|
|
|
func (t *TUIPager) Write(p []byte) (n int, err error) {
|
|
return t.renderer.Write(p)
|
|
}
|
|
|
|
func (t *TUIPager) Display() error {
|
|
if err := t.renderer.Close(); err != nil {
|
|
return err
|
|
}
|
|
|
|
builder := new(strings.Builder)
|
|
_, _ = io.Copy(builder, t.renderer)
|
|
|
|
tuiProgram := tea.NewProgram(
|
|
tui.NewPager(t.title, builder.String()),
|
|
tea.WithAltScreen(),
|
|
)
|
|
|
|
_, err := tuiProgram.Run()
|
|
return err
|
|
}
|
|
|
|
func NewCmdPager(ctx context.Context, pagerCmd string, colorize bool) (p *CommandPager, err error) {
|
|
var (
|
|
renderer *glamour.TermRenderer
|
|
buf *bytes.Buffer
|
|
)
|
|
if colorize {
|
|
renderer, err = glamour.NewTermRenderer(
|
|
glamour.WithStyles(glamour.DraculaStyleConfig),
|
|
glamour.WithColorProfile(termenv.TrueColor),
|
|
glamour.WithEmoji(),
|
|
glamour.WithAutoStyle(),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else {
|
|
buf = bytes.NewBuffer(nil)
|
|
}
|
|
|
|
split := strings.Split(pagerCmd, " ")
|
|
var (
|
|
executable = split[0]
|
|
args []string
|
|
)
|
|
|
|
if len(split) > 1 {
|
|
args = split[1:]
|
|
}
|
|
|
|
return &CommandPager{
|
|
cmd: exec.CommandContext(ctx, executable, args...),
|
|
renderer: renderer,
|
|
buf: buf,
|
|
}, nil
|
|
}
|
|
|
|
type CommandPager struct {
|
|
cmd *exec.Cmd
|
|
renderer *glamour.TermRenderer
|
|
buf *bytes.Buffer
|
|
}
|
|
|
|
func (c *CommandPager) Write(p []byte) (n int, err error) {
|
|
if c.renderer != nil {
|
|
return c.renderer.Write(p)
|
|
}
|
|
return c.buf.Write(p)
|
|
}
|
|
|
|
func (c *CommandPager) Display() error {
|
|
if c.renderer != nil {
|
|
if err := c.renderer.Close(); err != nil {
|
|
return err
|
|
}
|
|
c.cmd.Stdin = c.renderer
|
|
} else {
|
|
c.cmd.Stdin = c.buf
|
|
}
|
|
|
|
c.cmd.Stdout = os.Stdout
|
|
c.cmd.Stderr = os.Stderr
|
|
|
|
return c.cmd.Run()
|
|
}
|