-
Notifications
You must be signed in to change notification settings - Fork 279
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stream content to a viewport #294
Comments
I've the same question |
Firstly, you're doing I/O inside of Check out this tutorial: https://github.com/charmbracelet/bubbletea/tree/master/tutorials/commands/ Secondly, because there's no |
I figured out how to do this, if anyone has any other ideas please let know: package main
import (
"fmt"
"os"
"os/exec"
"strings"
"time"
"github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea"
)
type Model struct {
content strings.Builder
ready bool
viewport viewport.Model
}
func (m *Model) runCmd() tea.Msg {
cmd := exec.Command("bash", "loop.sh")
stdout, _ := cmd.StdoutPipe()
if err := cmd.Start(); err != nil {
return tea.Quit()
}
go func() {
buf := make([]byte, 1024)
for {
n, err := stdout.Read(buf)
if err != nil {
break
}
m.content.Write(buf[:n])
}
}()
return nil
}
func (m *Model) Init() tea.Cmd {
return m.runCmd
}
func (m *Model) View() string {
if !m.ready {
return "Loading..."
}
return m.viewport.View()
}
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
if k := msg.String(); k == "ctrl+c" || k == "q" || k == "esc" {
return m, tea.Quit
}
case tickMsg:
m.viewport.SetContent(m.content.String())
m.viewport.GotoBottom()
case tea.WindowSizeMsg:
if !m.ready {
m.viewport = viewport.New(msg.Width, msg.Height-10)
m.viewport.YPosition = 5
m.viewport.HighPerformanceRendering = false
m.viewport.SetContent("Loading...")
m.ready = true
break
}
m.viewport.Width = msg.Width
m.viewport.Height = msg.Height - 10
}
return m, nil
}
type tickMsg time.Time
func main() {
cmd := tea.NewProgram(&Model{})
go func() {
for c := range time.Tick(300 * time.Millisecond) {
cmd.Send(tickMsg(c))
}
}()
if _, err := cmd.Run(); err != nil {
fmt.Printf("Uh oh: %v\n", err)
os.Exit(1)
}
} |
I was hoping to do the same thing with my logs. I have concerns with using Viewport - I'm not sure how this is normally done but because SetContent() copies the entire string every call then replaces and splits every line, it just feed really inefficient. I'm not sure what the right methodology is but it would be great to wire an io.Writer directly to the viewport. |
Hi,
Let's say I'm running some kind of external software and I want to display the logs of it during its lifetime in a viewport.
How can I do this ? As far as I understand, the viewport can only be updated through the SetContent method.
Ideally, the viewport should update every new line but I don't want to do some weird things if I missed something
Minimal code:
-> /tmp/some-software.sh
Thanks!
The text was updated successfully, but these errors were encountered: