charmbracelet / charmbracelet/bubbletea

Automatically open terminal when Stdout is not a terminal

Open
#860 7 comments 8 reactions 0 assignees View on GitHub
enhancement
Dominant language
Go
Stars
44.9k
Forks
1.3k
PR merge metrics
No merged PRs in 30d

Description

# **Is your feature request related to a problem? Please describe.**

## description
Currently, to redirect output results to another file or pipe them to another command is not supported. Therefore, if you write bubbles tea's standard output to a file with the current implementation, the file will have ANSI control characters written directly to it.
this problem is reported in #823 and #792.

## why is this a problem?
- TUI applications will be able to take full advantage of the CLI application, such as the convenience of pipes and redirection.
- It is strange that the input supports pipes and redirects [here in tea.go](https://github.com/charmbracelet/bubbletea/blob/5536bca34e218a1e17a55e5ba36c22fab5784f44/tea.go#L416C2-L452C3), but the output does not.

# **Describe the solution you'd like**

If the standard output of the bubble tea program is connected to something other than a terminal, the program will determine this at startup and change the destination of bubble tea's TUI to the terminal and the destination of stdout to the output specified at startup.

Add the following process
- check whether stdout is a terminal at the start of the program.
- if it is a terminal, proceed with the process as it is now. (just output to stdout)
- if it is not a terminal, open a new "dev/tty" and output to it.

# **Describe alternatives you've considered**
- You can use a golang program to write an output to a file, but it is inconvenient.
- open dev/tty and use `WithOutput` option
```go
func main() {
tty, err := os.OpenFile("/dev/tty", os.O_WRONLY, 0)
if err != nil {
panic(err)
}
defer tty.Close()

p := tea.NewProgram(initialModel(), tea.WithOutput(tty))
fmt.Println("result of command")
if _, err := p.Run(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
```
This works on linux, but this is not crossplatform solution. Also, this is inconsistent interface because you don't have to write any code for input, but have to write for output.

# **Additional context**
I am not sure where i should write the statements to solve this problem.
Currently, Program.output is initialized [here](https://github.com/charmbracelet/bubbletea/blob/5536bca34e218a1e17a55e5ba36c22fab5784f44/tea.go#L203C2-L211C72). I should add the new process here in terms of extending the existing process.
[Here](https://github.com/charmbracelet/bubbletea/blob/5536bca34e218a1e17a55e5ba36c22fab5784f44/tea.go#L416C2-L452C3) is a program from tea.go that creates a new TTY for the input source. The input and output processing are similar in purpose and content, so I should add the processing here.

Contributor guide

Open the contributing guide

Research direction

Start in tea.go where Program.output is initialized, then compare it with the input TTY setup around the referenced tea.go section. Check how stdout is detected and how the requested terminal and output destinations should behave across platforms. Done means non-terminal stdout can be redirected without ANSI TUI output being written there, while terminal output continues to work normally.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
cli
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.