TUIOSTUIOS

Library Usage

Embed TUIOS in your own Bubble Tea application

TUIOS ships as a Go package as well as a binary. pkg/tuios exposes the window manager as a Bubble Tea model, so you can run it standalone, embed it, or serve it over a PTY of your own.

Installation

go get github.com/Gaurav-Gosain/tuios

The package is pre-1.0 and the API can change between releases. Model is a type alias for an internal type, so any method the internal model gains or loses is visible to you immediately. Pin a version in your go.mod.

Basic Usage

tuios.New returns a *Model that implements tea.Model. You construct the Bubble Tea program yourself, which means you keep control of the program options and the error handling.

package main

import (
	"log"

	tea "charm.land/bubbletea/v2"
	"github.com/Gaurav-Gosain/tuios/pkg/tuios"
)

func main() {
	model := tuios.New()

	p := tea.NewProgram(model, tuios.ProgramOptions()...)
	if _, err := p.Run(); err != nil {
		log.Fatal(err)
	}
}

There is no tuios.Run function. Constructing the model and running the program are separate steps.

Options

Configuration uses functional options passed to New. Each corresponds to a field on the Options struct, and DefaultOptions() returns the defaults.

model := tuios.New(
	tuios.WithTheme("dracula"),
	tuios.WithShowKeys(true),
	tuios.WithAnimations(false),
	tuios.WithWorkspaces(4),
	tuios.WithBorderStyle("thick"),
	tuios.WithScrollbackLines(50000),
)
OptionTypeDefaultNotes
WithThemestringemptyTheme name. Empty uses standard terminal colors.
WithShowKeysboolfalseShow the pressed-keys overlay.
WithAnimationsbooltrueWhen off, windows snap instantly.
WithASCIIOnlyboolfalseUse ASCII instead of Nerd Font icons.
WithWorkspacesint9Clamped to 1-9.
WithBorderStylestring"rounded"See Configuration.
WithDockbarPositionstring"bottom"bottom, top, or hidden.
WithHideWindowButtonsboolfalseHide minimize, maximize, and close.
WithWindowButtonStylestring"pill"pill (glyphs on a filled pill) or dots (macOS traffic lights).
WithWindowButtonPositionstring"right"right or left end of the title bar.
WithScrollbackLinesint10000Clamped to 100-1000000.
WithSizeint, intautoInitial size, detected if unset.
WithSSHModeboolfalseAdjusts behaviour for SSH serving.
WithUserConfig*config.UserConfigloaded from diskSupply a config instead of reading the user's file.

Out-of-range values are clamped rather than rejected. WithWorkspaces(50) gives you 9 and WithScrollbackLines(10) gives you 100, with no error.

Serving a PTY

NewForPTY sizes the model from a PTY. Anything with Width() int and Height() int satisfies the PTY interface, which keeps the package independent of any particular SSH or web terminal library.

type PTY interface {
	Width() int
	Height() int
}

func NewForPTY(pty PTY, opts ...Option) *Model

The doc comment above the PTY interface in the source still refers to a NewForSession constructor. No such function exists; the constructor is NewForPTY.

Program Options

ProgramOptions() returns the Bubble Tea options TUIOS expects, currently the frame rate. Pass them through rather than writing your own, so you inherit later additions.

FilterMouseMotion is a tea.WithFilter function that drops mouse motion events when nothing is being dragged, resized, or selected. Terminal applications generate a lot of motion events and forwarding all of them costs measurable CPU.

p := tea.NewProgram(
	model,
	tea.WithFilter(tuios.FilterMouseMotion),
)

Motion passes through during window drags and resizes, overlay panel drags, scrollback browser selection, text selection, and when the focused window is an alt-screen application tracking the mouse itself. Everything else is filtered out.

Modes

Mode is an alias for the internal mode type, with two exported constants. WindowManagementMode is what TUIOS starts in.

if model.Mode == tuios.TerminalMode {
	// input is going to the focused terminal
}

Configuration Access

tuios.Config re-exports three configuration functions so you can work with user configuration without importing an internal package:

cfg, err := tuios.Config.LoadUserConfig()
if err != nil {
	cfg = tuios.Config.DefaultConfig()
}

model := tuios.New(tuios.WithUserConfig(cfg))

tuios.Config.GetConfigPath() returns the path the configuration is read from.

Limitations

Worth knowing before you build on this:

  • Daemon mode is not available through the library. Sessions, detach and reattach, and the control protocol live in an internal package and are reachable only through the tuios binary. pkg/tuios gives you an in-process window manager.
  • SSH serving is not exported. The binary's tuios ssh is implemented internally. You can serve TUIOS over SSH by wiring NewForPTY into your own server, but there is no RunSSH helper.
  • Several options set process-global state. WithASCIIOnly, WithBorderStyle, WithDockbarPosition, WithHideWindowButtons, WithWindowButtonStyle, WithWindowButtonPosition, WithScrollbackLines, and WithAnimations write to package-level variables in the config package. Two models in one process do not get independent values for these, and the last one constructed wins. This matters if you serve several sessions from a single process.
  • There is no Go example directory. The repository's examples/ directory holds .tape scripts for the tape player, not Go programs.

On this page