tui

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 11 Imported by: 0

README

github.com/stelmakhdigital/stell-tui

Фреймворк терминального UI с дифференциальным рендерингом.

Дифференциальный рендеринг - при каждом обновлении перерисовывается не весь экран, а только разница с предыдущим кадром — изменённые строки/ячейки.

Возможности

  • Дифференциальный рендер (DiffFull / DiffPatch / DiffScroll) и CSI 2026
  • ProcessTerminal — raw mode, bracketed paste, подсказки Kitty keyboard, resize
  • Standalone TUI.Start / Stop или hosted RenderNow для встраивания
  • Компоненты: Container, Text, Box, Loader, SelectList, SettingsList, Markdown, Image, Editor, Input
  • Стек оверлеев: OverlayOptions / OverlayHandle

Карта директорий

Путь Назначение
tui.go, overlay_host.go, export.go хост Start/Stop, фокус, оверлеи, публичные aliases
component/ UI-компоненты
diff/ DiffEngine
terminal/ Terminal / ProcessTerminal
keys/ клавиши и буфер stdin
overlay/ раскладка и композитинг оверлеев
editor/ редактор, input, autocomplete
wrap/ ширина / ANSI / fuzzy
examples/ демо

Внешний код импортирует только github.com/stelmakhdigital/stell-tui (не подпакеты).

Standalone

package main

import "github.com/stelmakhdigital/stell-tui"

func main() {
	term := tui.NewProcessTerminal(nil, nil)
	ui := tui.NewWithTerminal(term, true)

	ui.AddChild(&tui.Text{Lines: []string{"Hello"}})
	ed := tui.NewEditor()
	ed.OnSubmit = func(v string) { /* ... */ }
	ui.AddChild(ed)
	ui.SetFocus(ed)

	ui.AddInputListener(func(data string) bool {
		if tui.MatchesKey(data, "ctrl+c") {
			ui.Stop()
			return true
		}
		return false
	})

	ui.Start()
}

Демо:

go run ./examples/chat_simple

Hosted (встраивание)

Для приложений со своим циклом (например github.com/stelmakhdigital/stell-coding):

ui := tui.New(os.Stdout, true)
defer ui.Close()

restore, _ := tui.EnableRawMode()
defer restore()
defer tui.EnableTerminalFeatures()()

w, h, _ := tui.TermSize()
ui.SetSize(w, h)
ui.SetRoot(tui.NewContainer(root))
_ = ui.RenderNow() // после каждого обновления модели

Маркер курсора

CursorMarker — APC "\x1b_stell:c\x07". При SetShowHardwareCursor(true) движок ищет полную последовательность, снимает её и позиционирует аппаратный курсор. VisibleLen / StripANSI считают APC zero-width.

Documentation

Overview

Package tui — фреймворк терминального UI с дифференциальным рендерингом.

Публичный импорт — `github.com/stelmakhdigital/stell-tui`; реализация разложена по подпакетам (component, diff, editor, keys, overlay, terminal, wrap), реэкспорт — в export.go.

Два режима хоста:

  • Standalone: NewWithTerminal + Start/Stop (см. examples/chat_simple)
  • Hosted: New + RenderNow — цикл событий и raw mode у вызывающего кода

Интерактивный UI coding-agent живёт в github.com/stelmakhdigital/stell-coding/internal/tui и реэкспортирует этот пакет через type aliases.

Index

Constants

View Source
const (
	DiffFull   = diff.DiffFull
	DiffPatch  = diff.DiffPatch
	DiffScroll = diff.DiffScroll

	ImageNone  = terminal.ImageNone
	ImageKitty = terminal.ImageKitty
	ImageITerm = terminal.ImageITerm

	OverlayAnchorTop          = overlay.OverlayAnchorTop
	OverlayAnchorCenter       = overlay.OverlayAnchorCenter
	OverlayAnchorBottom       = overlay.OverlayAnchorBottom
	OverlayAnchorTopLeft      = overlay.OverlayAnchorTopLeft
	OverlayAnchorTopRight     = overlay.OverlayAnchorTopRight
	OverlayAnchorBottomLeft   = overlay.OverlayAnchorBottomLeft
	OverlayAnchorBottomRight  = overlay.OverlayAnchorBottomRight
	OverlayAnchorTopCenter    = overlay.OverlayAnchorTopCenter
	OverlayAnchorBottomCenter = overlay.OverlayAnchorBottomCenter
	OverlayAnchorLeftCenter   = overlay.OverlayAnchorLeftCenter
	OverlayAnchorRightCenter  = overlay.OverlayAnchorRightCenter

	CursorMarker = wrap.CursorMarker
)

Variables

View Source
var (
	NewContainer         = component.NewContainer
	NewSelectList        = component.NewSelectList
	NewSettingsList      = component.NewSettingsList
	NewMarkdown          = component.NewMarkdown
	DefaultMarkdownTheme = component.DefaultMarkdownTheme
	NewImage             = component.NewImage

	NewDiffEngine = diff.NewDiffEngine

	NewEditor   = editor.NewEditor
	NewInput    = editor.NewInput
	NewKillRing = editor.NewKillRing

	NewKeyMap              = keys.NewKeyMap
	NewKeybindingsManager  = keys.NewKeybindingsManager
	DefaultTUIKeybindings  = keys.DefaultTUIKeybindings
	ParseKey               = keys.ParseKey
	MatchesKey             = keys.MatchesKey
	NormalizeKeyChord      = keys.NormalizeKeyChord
	NormalizeKey           = keys.NormalizeKey
	DecodePrintableKey     = keys.DecodePrintableKey
	IsKeyRelease           = keys.IsKeyRelease
	NewStdinBuffer         = keys.NewStdinBuffer
	SetKittyProtocolActive = keys.SetKittyProtocolActive
	KittyProtocolActive    = keys.KittyProtocolActive

	NewProcessTerminal           = terminal.NewProcessTerminal
	DetectCapabilities           = terminal.DetectCapabilities
	EnableRawMode                = terminal.EnableRawMode
	EnableTerminalFeatures       = terminal.EnableTerminalFeatures
	EnableTerminalFeaturesWriter = terminal.EnableTerminalFeaturesWriter
	TermSize                     = terminal.TermSize
	QueryCellSize                = terminal.QueryCellSize
	QueryCellSizeWriter          = terminal.QueryCellSizeWriter
	WatchResize                  = terminal.WatchResize
	EncodeTerminalImage          = terminal.EncodeTerminalImage
	ImageStub                    = terminal.ImageStub

	ClampOverlayLines     = overlay.ClampOverlayLines
	CompositeOverlayLines = overlay.CompositeOverlayLines

	VisibleLen  = wrap.VisibleLen
	Truncate    = wrap.Truncate
	FuzzyFilter = wrap.FuzzyFilter
	FuzzyScore  = wrap.FuzzyScore
)

Functions

This section is empty.

Types

type Autocomplete

type Autocomplete = editor.Autocomplete

type Box

type Box = component.Box

type CancellableLoader

type CancellableLoader = component.CancellableLoader

type CompleteItem

type CompleteItem = editor.CompleteItem

type Completer

type Completer = editor.Completer

type Component

type Component = component.Component

type Container

type Container = component.Container

type DiffEngine

type DiffEngine = diff.DiffEngine

type DiffStrategy

type DiffStrategy = diff.DiffStrategy

type Editor

type Editor = editor.Editor

type Focusable

type Focusable = component.Focusable

type Image

type Image = component.Image

type ImageProtocol

type ImageProtocol = terminal.ImageProtocol

type ImageRenderOptions

type ImageRenderOptions = terminal.ImageRenderOptions

type Input

type Input = editor.Input

type InputHandler

type InputHandler = component.InputHandler

type InputListener

type InputListener func(data string) (consumed bool)

InputListener получает сырой ввод до маршрутизации фокуса. Верните true, чтобы поглотить событие (не отдавать компоненту).

type Invalidatable

type Invalidatable = component.Invalidatable

type KeyAction

type KeyAction = keys.KeyAction

type KeyDef

type KeyDef = keys.KeyDef

type KeyMap

type KeyMap = keys.KeyMap

type KeybindingsManager

type KeybindingsManager = keys.KeybindingsManager

type KillRing

type KillRing = editor.KillRing

type Loader

type Loader = component.Loader

type Markdown

type Markdown = component.Markdown

type MarkdownTheme

type MarkdownTheme = component.MarkdownTheme

type OverlayAnchor

type OverlayAnchor = overlay.OverlayAnchor

type OverlayHandle

type OverlayHandle struct {
	// contains filtered or unexported fields
}

OverlayHandle управляет показанным оверлеем.

func (*OverlayHandle) Focus

func (h *OverlayHandle) Focus()

Focus фокусирует оверлей и поднимает его визуально наверх.

func (*OverlayHandle) Hide

func (h *OverlayHandle) Hide()

Hide навсегда убирает оверлей из стека.

func (*OverlayHandle) IsFocused

func (h *OverlayHandle) IsFocused() bool

IsFocused сообщает, есть ли сейчас фокус у этого оверлея.

func (*OverlayHandle) IsHidden

func (h *OverlayHandle) IsHidden() bool

IsHidden сообщает, временно ли скрыт оверлей.

func (*OverlayHandle) SetHidden

func (h *OverlayHandle) SetHidden(hidden bool)

SetHidden временно скрывает или показывает оверлей, не удаляя его.

func (*OverlayHandle) Unfocus

func (h *OverlayHandle) Unfocus(opts ...UnfocusOptions)

Unfocus снимает фокус с оверлея.

type OverlayMargin

type OverlayMargin = overlay.OverlayMargin

type OverlayOptions

type OverlayOptions = overlay.OverlayOptions

type ProcessTerminal

type ProcessTerminal = terminal.ProcessTerminal

type SelectList

type SelectList = component.SelectList

type SettingsItem

type SettingsItem = component.SettingsItem

type SettingsList

type SettingsList = component.SettingsList

type Spacer

type Spacer = component.Spacer

type StaticCompleter

type StaticCompleter = editor.StaticCompleter

type StdinBuffer

type StdinBuffer = keys.StdinBuffer

type StdinBufferOptions

type StdinBufferOptions = keys.StdinBufferOptions

type TUI

type TUI struct {
	// contains filtered or unexported fields
}

TUI — корневой контейнер с фокусом, оверлеями и циклом отрисовки.

func New

func New(stdout io.Writer, altScreen bool) *TUI

New создаёт hosted-TUI, пишущий в stdout (цикл событий у вызывающего кода).

func NewWithTerminal

func NewWithTerminal(term terminal.Terminal, altScreen bool) *TUI

NewWithTerminal создаёт TUI, привязанный к Terminal (standalone Start/Stop).

func (*TUI) AddChild

func (t *TUI) AddChild(c component.Component)

AddChild добавляет компонент в корневой контейнер.

func (*TUI) AddInputListener

func (t *TUI) AddInputListener(fn InputListener)

AddInputListener регистрирует обработчик ввода до фокуса.

func (*TUI) CellDimensions

func (t *TUI) CellDimensions() (w, h int)

CellDimensions возвращает последний известный размер ячейки в пикселях (0 если неизвестен).

func (*TUI) ClearOverlay

func (t *TUI) ClearOverlay()

ClearOverlay удаляет все оверлеи.

func (*TUI) Close

func (t *TUI) Close() error

Close восстанавливает терминал (курсор / alt screen).

func (*TUI) ForceFullRedraw

func (t *TUI) ForceFullRedraw()

ForceFullRedraw инвалидирует DiffEngine, чтобы следующий кадр был полной перерисовкой.

func (*TUI) HandleInput

func (t *TUI) HandleInput(data string)

HandleInput маршрутизирует ввод слушателям, оверлею или фокусу.

func (*TUI) HasOverlay

func (t *TUI) HasOverlay() bool

HasOverlay сообщает, есть ли видимый активный оверлей.

func (*TUI) HideOverlay

func (t *TUI) HideOverlay()

HideOverlay скрывает верхний оверлей.

func (*TUI) OnResize

func (t *TUI) OnResize(fn func(w, h int))

OnResize регистрирует колбэк изменения размера.

func (*TUI) RemoveChild

func (t *TUI) RemoveChild(c component.Component)

RemoveChild удаляет первое совпадение компонента из корневого контейнера.

func (*TUI) RenderNow

func (t *TUI) RenderNow() error

RenderNow принудительно пишет кадр (для хостов со своим циклом событий).

func (*TUI) RequestRender

func (t *TUI) RequestRender()

RequestRender помечает кадр грязным.

func (*TUI) Root

func (t *TUI) Root() *component.Container

Root возвращает корневой контейнер.

func (*TUI) SetCellDimensions

func (t *TUI) SetCellDimensions(w, h int)

SetCellDimensions сохраняет размер ячейки в пикселях (CSI 16 t) для масштаба картинок.

func (*TUI) SetDiffStrategy

func (t *TUI) SetDiffStrategy(s diff.DiffStrategy)

SetDiffStrategy выбирает DiffFull / DiffPatch / DiffScroll.

func (*TUI) SetFocus

func (t *TUI) SetFocus(f component.Focusable)

SetFocus устанавливает фокус клавиатуры.

func (*TUI) SetOverlay

func (t *TUI) SetOverlay(c component.Component)

SetOverlay заменяет верхний оверлей (или показывает новый).

func (*TUI) SetRoot

func (t *TUI) SetRoot(c *component.Container)

SetRoot задаёт корневой контейнер.

func (*TUI) SetShowHardwareCursor

func (t *TUI) SetShowHardwareCursor(on bool)

SetShowHardwareCursor включает позиционирование аппаратного курсора по CursorMarker.

func (*TUI) SetShowImages

func (t *TUI) SetShowImages(on bool)

SetShowImages включает инлайн-изображения терминала.

func (*TUI) SetSize

func (t *TUI) SetSize(w, h int)

SetSize задаёт размер терминала.

func (*TUI) SetTerminal

func (t *TUI) SetTerminal(term terminal.Terminal)

SetTerminal привязывает Terminal для Start/Stop (hosted-приложениям можно не вызывать).

func (*TUI) ShowImages

func (t *TUI) ShowImages() bool

ShowImages сообщает, включены ли инлайн-изображения.

func (*TUI) ShowOverlay

func (t *TUI) ShowOverlay(c component.Component, opts ...overlay.OverlayOptions) *OverlayHandle

ShowOverlay показывает компонент как оверлей.

func (*TUI) Start

func (t *TUI) Start()

Start запускает standalone-цикл на привязанном Terminal. Блокируется до Stop. Для standalone предпочтителен NewWithTerminal.

func (*TUI) Stop

func (t *TUI) Stop()

Stop завершает цикл Start и восстанавливает терминал.

type Terminal

type Terminal = terminal.Terminal

type TerminalCapabilities

type TerminalCapabilities = terminal.TerminalCapabilities

type Text

type Text = component.Text

type TruncatedText

type TruncatedText = component.TruncatedText

type UnfocusOptions

type UnfocusOptions struct {
	Target component.Focusable
	Clear  bool
}

UnfocusOptions настраивает OverlayHandle.Unfocus.

Directories

Path Synopsis
examples
chat_simple command
Простое демо чата на github.com/stelmakhdigital/stell-tui (standalone Start/Stop).
Простое демо чата на github.com/stelmakhdigital/stell-tui (standalone Start/Stop).
Package overlay — раскладка и композитинг оверлеев TUI.
Package overlay — раскладка и композитинг оверлеев TUI.
Package wrap — утилиты визуальной ширины строк с учётом ANSI/OSC.
Package wrap — утилиты визуальной ширины строк с учётом ANSI/OSC.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL