diff --git a/options.go b/options.go index b133e8a..3459b4d 100644 --- a/options.go +++ b/options.go @@ -28,6 +28,13 @@ func WithInput(input io.Reader) ProgramOption { } } +// WithInputTTY open a new TTY for input (or console input device on Windows). +func WithInputTTY() ProgramOption { + return func(p *Program) { + p.startupOptions |= withInputTTY + } +} + // WithoutCatchPanics disables the panic catching that Bubble Tea does by // default. If panic catching is disabled the terminal will be in a fairly // unusable state after a panic because Bubble Tea will not perform its usual diff --git a/tea.go b/tea.go index 2f285a2..12046ad 100644 --- a/tea.go +++ b/tea.go @@ -58,11 +58,16 @@ type Cmd func() Msg // The options here are treated as bits. type startupOptions byte +func (s startupOptions) has(option startupOptions) bool { + return s&option != 0 +} + // Available startup options. const ( withAltScreen startupOptions = 1 << iota withMouseCellMotion withMouseAllMotion + withInputTTY ) // inputStatus indicates the current state of the input. By default, input is @@ -297,6 +302,15 @@ func (p *Program) Start() error { p.outputIsTTY = isatty.IsTerminal(f.Fd()) } + // Open a new TTY, by request + if p.startupOptions.has(withInputTTY) { + f, err := openInputTTY() + if err != nil { + return err + } + p.input = f + } + // Is input a terminal? if f, ok := p.input.(*os.File); ok { p.inputIsTTY = isatty.IsTerminal(f.Fd())