Skip to content

Instantly share code, notes, and snippets.

@burbma
Created February 22, 2024 01:58
Show Gist options
  • Save burbma/7ca9c91c5f59afa062d293235fa2126b to your computer and use it in GitHub Desktop.
Save burbma/7ca9c91c5f59afa062d293235fa2126b to your computer and use it in GitHub Desktop.
Pass VT to Bubbletea
// Incomplete code, leaves out the imports and Bubbletea model and setup
func nextFreeConsole() (int, error) {
f, err := os.OpenFile("/dev/tty0", os.O_WRONLY, 0)
if err != nil {
return 0, err
}
defer f.Close()
free, err := unix.IoctlGetInt(int(f.Fd()), linuxvt.VT_OPENQRY)
if err != nil {
return 0, fmt.Errorf("VT_OPENQRY: %v", err)
}
if err := f.Close(); err != nil {
return 0, err
}
return free, nil
}
func main() {
free, err := nextFreeConsole()
if err != nil {
log.Print(err)
}
log.Printf("opening next free console /dev/tty%d", free)
f, err := os.OpenFile(fmt.Sprintf("/dev/tty%d", free), os.O_RDWR, 0)
if err != nil {
log.Print(err)
}
var state linuxvt.VTState
_, _, eno := unix.Syscall(unix.SYS_IOCTL, f.Fd(), linuxvt.VT_GETSTATE, uintptr(unsafe.Pointer(&state)))
if eno != 0 {
log.Printf("VT_GETSTATE: %v", eno)
}
if err := unix.IoctlSetInt(int(f.Fd()), linuxvt.VT_ACTIVATE, free); err != nil {
log.Printf("VT_ACTIVATE: %v", err)
}
if err := unix.IoctlSetInt(int(f.Fd()), linuxvt.VT_WAITACTIVE, free); err != nil {
log.Printf("VT_WAITACTIVE: %v", err)
}
// Here you see me actually passing the TTY into tea.
if _, err := tea.NewProgram(model{}, tea.WithInput(f), tea.WithOutput(f)).Run(); err != nil {
log.Printf("Error running program: %v", err)
os.Exit(1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment