Something went wrong. Try again.
Go bindings for libghostty-vt. pkg.go.dev/go.mitchellh.com/libghostty
ghostty
Something went wrong. Try again.
go-libghostty screen.go
17 kB · 521 lines
Go
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522package libghostty
/*#include <ghostty/vt.h>*/import "C"
import ( "errors" "unsafe")
// CellData identifies a data field for cell queries.// C: GhosttyCellDatatype CellData int
const ( // CellDataInvalid is an invalid data type. CellDataInvalid CellData = C.GHOSTTY_CELL_DATA_INVALID
// CellDataCodepoint is the codepoint of the cell (uint32_t). CellDataCodepoint CellData = C.GHOSTTY_CELL_DATA_CODEPOINT
// CellDataContentTag is the content tag describing what kind of // content is in the cell (GhosttyCellContentTag). CellDataContentTag CellData = C.GHOSTTY_CELL_DATA_CONTENT_TAG
// CellDataWide is the wide property of the cell (GhosttyCellWide). CellDataWide CellData = C.GHOSTTY_CELL_DATA_WIDE
// CellDataHasText indicates whether the cell has text to render (bool). CellDataHasText CellData = C.GHOSTTY_CELL_DATA_HAS_TEXT
// CellDataHasStyling indicates whether the cell has non-default // styling (bool). CellDataHasStyling CellData = C.GHOSTTY_CELL_DATA_HAS_STYLING
// CellDataStyleID is the style ID for the cell (uint16_t). CellDataStyleID CellData = C.GHOSTTY_CELL_DATA_STYLE_ID
// CellDataHasHyperlink indicates whether the cell has a hyperlink // (bool). CellDataHasHyperlink CellData = C.GHOSTTY_CELL_DATA_HAS_HYPERLINK
// CellDataProtected indicates whether the cell is protected (bool). CellDataProtected CellData = C.GHOSTTY_CELL_DATA_PROTECTED
// CellDataSemanticContent is the semantic content type of the cell // (GhosttyCellSemanticContent). CellDataSemanticContent CellData = C.GHOSTTY_CELL_DATA_SEMANTIC_CONTENT
// CellDataColorPalette is the palette index for the cell's background // color (GhosttyColorPaletteIndex). CellDataColorPalette CellData = C.GHOSTTY_CELL_DATA_COLOR_PALETTE
// CellDataColorRGBValue is the RGB value for the cell's background // color (GhosttyColorRgb). CellDataColorRGBValue CellData = C.GHOSTTY_CELL_DATA_COLOR_RGB)
// RowData identifies a data field for row queries.// C: GhosttyRowDatatype RowData int
const ( // RowDataInvalid is an invalid data type. RowDataInvalid RowData = C.GHOSTTY_ROW_DATA_INVALID
// RowDataWrap indicates whether the row is soft-wrapped (bool). RowDataWrap RowData = C.GHOSTTY_ROW_DATA_WRAP
// RowDataWrapContinuation indicates whether the row is a continuation // of a soft-wrapped row (bool). RowDataWrapContinuation RowData = C.GHOSTTY_ROW_DATA_WRAP_CONTINUATION
// RowDataGrapheme indicates whether any cells in the row have grapheme // clusters (bool). RowDataGrapheme RowData = C.GHOSTTY_ROW_DATA_GRAPHEME
// RowDataStyled indicates whether any cells in the row have styling // (bool). RowDataStyled RowData = C.GHOSTTY_ROW_DATA_STYLED
// RowDataHyperlink indicates whether any cells in the row have // hyperlinks (bool). RowDataHyperlink RowData = C.GHOSTTY_ROW_DATA_HYPERLINK
// RowDataSemanticPrompt is the semantic prompt state of the row // (GhosttyRowSemanticPrompt). RowDataSemanticPrompt RowData = C.GHOSTTY_ROW_DATA_SEMANTIC_PROMPT
// RowDataKittyVirtualPlaceholder indicates whether the row contains // a Kitty virtual placeholder (bool). RowDataKittyVirtualPlaceholder RowData = C.GHOSTTY_ROW_DATA_KITTY_VIRTUAL_PLACEHOLDER
// RowDataDirty indicates whether the row is dirty and requires a // redraw (bool). RowDataDirty RowData = C.GHOSTTY_ROW_DATA_DIRTY)
// Cell is a wrapper around a packed terminal grid cell value. Portable callers// should use its typed getter methods. Callers that need to avoid per-field cgo// calls may read [Cell.PackedValue] and decode it using the GhosttyCell layout// in [TypeJSON]; the packed bit positions are not stable across versions.//// A Cell is a copied value snapshot, not a borrowed handle, so it may be// retained after the [GridRef] or render-state iterator that produced it// becomes invalid.// C: GhosttyCelltype Cell struct { c C.GhosttyCell}
// CellsView is a borrowed view of contiguous packed terminal cell values.// Views are produced by [RenderStateRowIterator.CellsRaw] and are only valid// until the owning render state is updated. Individual cells returned by// [CellsView.Cell] and all values returned by [CellsView.Clone] are copied and// may be retained.// C: GhosttyCellsViewtype CellsView struct { ptr *C.GhosttyCell len int}
// cellsViewFromC converts a borrowed C GhosttyCellsView to its Go wrapper.func cellsViewFromC(view C.GhosttyCellsView) CellsView { return CellsView{ ptr: view.ptr, len: int(view.len), }}
// Len returns the number of cells in the view.func (v CellsView) Len() int { return v.len}
// Cell returns a copied cell at index. It panics when index is outside the// view, matching normal Go slice indexing behavior.func (v CellsView) Cell(index int) *Cell { return &Cell{c: unsafe.Slice(v.ptr, v.len)[index]}}
// Clone copies every cell in the view into Go-owned memory. The returned cells// remain valid after the render state is updated.func (v CellsView) Clone() []Cell { if v.len == 0 { return nil }
raw := unsafe.Slice(v.ptr, v.len) result := make([]Cell, len(raw)) for i, cell := range raw { result[i].c = cell } return result}
// Row is a wrapper around an opaque terminal grid row value.// Use getter methods to extract data from it. A Row is a copied value// snapshot, not a borrowed handle, so it may be retained after the// [GridRef] or render-state iterator that produced it becomes invalid.// C: GhosttyRowtype Row struct { c C.GhosttyRow}
// PackedValue returns the raw packed cell value. Decode it using the// GhosttyCell descriptor returned by [TypeJSON]; hardcoded bit positions are// unsupported because the packed layout is not ABI-stable.func (c *Cell) PackedValue() uint64 { return uint64(c.c)}
// CellContentTag describes what kind of content a cell holds.// C: GhosttyCellContentTagtype CellContentTag int
const ( // CellContentCodepoint means a single codepoint (may be zero for empty). CellContentCodepoint CellContentTag = C.GHOSTTY_CELL_CONTENT_CODEPOINT
// CellContentCodepointGrapheme means a codepoint that is part of a // multi-codepoint grapheme cluster. CellContentCodepointGrapheme CellContentTag = C.GHOSTTY_CELL_CONTENT_CODEPOINT_GRAPHEME
// CellContentBgColorPalette means no text; background color from palette. CellContentBgColorPalette CellContentTag = C.GHOSTTY_CELL_CONTENT_BG_COLOR_PALETTE
// CellContentBgColorRGB means no text; background color as RGB. CellContentBgColorRGB CellContentTag = C.GHOSTTY_CELL_CONTENT_BG_COLOR_RGB)
// CellWide describes the width behavior of a cell.// C: GhosttyCellWidetype CellWide int
const ( // CellWideNarrow means not a wide character, cell width 1. CellWideNarrow CellWide = C.GHOSTTY_CELL_WIDE_NARROW
// CellWideWide means wide character, cell width 2. CellWideWide CellWide = C.GHOSTTY_CELL_WIDE_WIDE
// CellWideSpacerTail means spacer after wide character (do not render). CellWideSpacerTail CellWide = C.GHOSTTY_CELL_WIDE_SPACER_TAIL
// CellWideSpacerHead means spacer at end of soft-wrapped line for a // wide character. CellWideSpacerHead CellWide = C.GHOSTTY_CELL_WIDE_SPACER_HEAD)
// CellSemanticContent is the semantic content type of a cell,// as set by OSC 133 sequences.// C: GhosttyCellSemanticContenttype CellSemanticContent int
const ( // CellSemanticOutput means regular output content (e.g. command output). CellSemanticOutput CellSemanticContent = C.GHOSTTY_CELL_SEMANTIC_OUTPUT
// CellSemanticInput means content that is part of user input. CellSemanticInput CellSemanticContent = C.GHOSTTY_CELL_SEMANTIC_INPUT
// CellSemanticPrompt means content that is part of a shell prompt. CellSemanticPrompt CellSemanticContent = C.GHOSTTY_CELL_SEMANTIC_PROMPT)
// RowSemanticPrompt indicates whether any cells in a row are part of// a shell prompt, as reported by OSC 133 sequences.// C: GhosttyRowSemanticPrompttype RowSemanticPrompt int
const ( // RowSemanticNone means no prompt cells in this row. RowSemanticNone RowSemanticPrompt = C.GHOSTTY_ROW_SEMANTIC_NONE
// RowSemanticPromptPrimary means prompt cells exist and this is a // primary prompt line. RowSemanticPromptPrimary RowSemanticPrompt = C.GHOSTTY_ROW_SEMANTIC_PROMPT
// RowSemanticPromptContinuation means prompt cells exist and this is // a continuation line. RowSemanticPromptContinuation RowSemanticPrompt = C.GHOSTTY_ROW_SEMANTIC_PROMPT_CONTINUATION)
// GetMulti queries multiple cell data fields in a single cgo call.// This is a low-level function. Prefer the typed getters (Codepoint,// Wide, HasText, etc.) for normal use. GetMulti is useful when you// need many fields at once and want to avoid per-field cgo overhead.//// Each element in keys specifies a data kind, and the corresponding// element in values must be an unsafe.Pointer to a variable whose type// matches the "Output type" documented for that key in the upstream C// header (ghostty/vt/screen.h, GhosttyCellData enum).// Use a Go type with the same size as the C type, such as uint32// for uint32_t, bool for bool, and int32 for an enum.//// GetMulti returns an error if keys and values have different lengths// or if a key cannot be read. In the second case, values for the keys// before it may already have been written.//// Example://// var cp uint32// var hasText bool// err := cell.GetMulti(// []CellData{CellDataCodepoint, CellDataHasText},// []unsafe.Pointer{unsafe.Pointer(&cp), unsafe.Pointer(&hasText)},// )//// C: ghostty_cell_get_multifunc (c *Cell) GetMulti(keys []CellData, values []unsafe.Pointer) error { if len(keys) != len(values) { return errors.New("libghostty: keys and values must have the same length") } if len(keys) == 0 { return nil } // Copy the keys and output pointers into C memory. See get_multi.go. var args getMultiArgs cKeys, err := allocWithKeys[C.GhosttyCellData](&args, keys, values) if err != nil { return err } defer args.free() return resultError(C.ghostty_cell_get_multi( c.c, C.size_t(len(keys)), cKeys, args.values, nil, ))}
// Codepoint returns the codepoint of the cell (0 if empty).func (c *Cell) Codepoint() (uint32, error) { var v C.uint32_t if err := resultError(C.ghostty_cell_get(c.c, C.GHOSTTY_CELL_DATA_CODEPOINT, unsafe.Pointer(&v))); err != nil { return 0, err } return uint32(v), nil}
// ContentTag returns the content tag describing what kind of content// the cell holds.func (c *Cell) ContentTag() (CellContentTag, error) { var v C.GhosttyCellContentTag if err := resultError(C.ghostty_cell_get(c.c, C.GHOSTTY_CELL_DATA_CONTENT_TAG, unsafe.Pointer(&v))); err != nil { return 0, err } return CellContentTag(v), nil}
// Wide returns the wide property of the cell.func (c *Cell) Wide() (CellWide, error) { var v C.GhosttyCellWide if err := resultError(C.ghostty_cell_get(c.c, C.GHOSTTY_CELL_DATA_WIDE, unsafe.Pointer(&v))); err != nil { return 0, err } return CellWide(v), nil}
// HasText reports whether the cell has text to render.func (c *Cell) HasText() (bool, error) { var v C.bool if err := resultError(C.ghostty_cell_get(c.c, C.GHOSTTY_CELL_DATA_HAS_TEXT, unsafe.Pointer(&v))); err != nil { return false, err } return bool(v), nil}
// HasStyling reports whether the cell has non-default styling.func (c *Cell) HasStyling() (bool, error) { var v C.bool if err := resultError(C.ghostty_cell_get(c.c, C.GHOSTTY_CELL_DATA_HAS_STYLING, unsafe.Pointer(&v))); err != nil { return false, err } return bool(v), nil}
// StyleID returns the style ID for the cell.func (c *Cell) StyleID() (uint16, error) { var v C.uint16_t if err := resultError(C.ghostty_cell_get(c.c, C.GHOSTTY_CELL_DATA_STYLE_ID, unsafe.Pointer(&v))); err != nil { return 0, err } return uint16(v), nil}
// HasHyperlink reports whether the cell has a hyperlink.func (c *Cell) HasHyperlink() (bool, error) { var v C.bool if err := resultError(C.ghostty_cell_get(c.c, C.GHOSTTY_CELL_DATA_HAS_HYPERLINK, unsafe.Pointer(&v))); err != nil { return false, err } return bool(v), nil}
// Protected reports whether the cell is protected.func (c *Cell) Protected() (bool, error) { var v C.bool if err := resultError(C.ghostty_cell_get(c.c, C.GHOSTTY_CELL_DATA_PROTECTED, unsafe.Pointer(&v))); err != nil { return false, err } return bool(v), nil}
// Semantic returns the semantic content type of the cell.func (c *Cell) Semantic() (CellSemanticContent, error) { var v C.GhosttyCellSemanticContent if err := resultError(C.ghostty_cell_get(c.c, C.GHOSTTY_CELL_DATA_SEMANTIC_CONTENT, unsafe.Pointer(&v))); err != nil { return 0, err } return CellSemanticContent(v), nil}
// ColorPalette returns the palette index for the cell's background// color. Only valid when the cell's content tag is CellContentBgColorPalette.func (c *Cell) ColorPalette() (uint8, error) { var v C.GhosttyColorPaletteIndex if err := resultError(C.ghostty_cell_get(c.c, C.GHOSTTY_CELL_DATA_COLOR_PALETTE, unsafe.Pointer(&v))); err != nil { return 0, err } return uint8(v), nil}
// ColorRGB returns the RGB color for the cell's background color.// Only valid when the cell's content tag is CellContentBgColorRGB.func (c *Cell) ColorRGB() (ColorRGB, error) { var v C.GhosttyColorRgb if err := resultError(C.ghostty_cell_get(c.c, C.GHOSTTY_CELL_DATA_COLOR_RGB, unsafe.Pointer(&v))); err != nil { return ColorRGB{}, err } return ColorRGB{R: uint8(v.r), G: uint8(v.g), B: uint8(v.b)}, nil}
// GetMulti queries multiple row data fields in a single cgo call.// This is a low-level function. Prefer the typed getters (Wrap,// Grapheme, Styled, Semantic, etc.) for normal use. GetMulti is// useful when you need many fields at once and want to avoid// per-field cgo overhead.//// Each element in keys specifies a data kind, and the corresponding// element in values must be an unsafe.Pointer to a variable whose type// matches the "Output type" documented for that key in the upstream C// header (ghostty/vt/screen.h, GhosttyRowData enum).// Use a Go type with the same size as the C type, such as uint32// for uint32_t, bool for bool, and int32 for an enum.//// GetMulti returns an error if keys and values have different lengths// or if a key cannot be read. In the second case, values for the keys// before it may already have been written.//// Example://// var wrap, styled bool// err := row.GetMulti(// []RowData{RowDataWrap, RowDataStyled},// []unsafe.Pointer{unsafe.Pointer(&wrap), unsafe.Pointer(&styled)},// )//// C: ghostty_row_get_multifunc (r *Row) GetMulti(keys []RowData, values []unsafe.Pointer) error { if len(keys) != len(values) { return errors.New("libghostty: keys and values must have the same length") } if len(keys) == 0 { return nil } // Copy the keys and output pointers into C memory. See get_multi.go. var args getMultiArgs cKeys, err := allocWithKeys[C.GhosttyRowData](&args, keys, values) if err != nil { return err } defer args.free() return resultError(C.ghostty_row_get_multi( r.c, C.size_t(len(keys)), cKeys, args.values, nil, ))}
// Wrap reports whether the row is soft-wrapped.func (r *Row) Wrap() (bool, error) { var v C.bool if err := resultError(C.ghostty_row_get(r.c, C.GHOSTTY_ROW_DATA_WRAP, unsafe.Pointer(&v))); err != nil { return false, err } return bool(v), nil}
// WrapContinuation reports whether the row is a continuation of// a soft-wrapped row.func (r *Row) WrapContinuation() (bool, error) { var v C.bool if err := resultError(C.ghostty_row_get(r.c, C.GHOSTTY_ROW_DATA_WRAP_CONTINUATION, unsafe.Pointer(&v))); err != nil { return false, err } return bool(v), nil}
// Grapheme reports whether any cells in the row have grapheme clusters.func (r *Row) Grapheme() (bool, error) { var v C.bool if err := resultError(C.ghostty_row_get(r.c, C.GHOSTTY_ROW_DATA_GRAPHEME, unsafe.Pointer(&v))); err != nil { return false, err } return bool(v), nil}
// Styled reports whether any cells in the row have styling// (may have false positives).func (r *Row) Styled() (bool, error) { var v C.bool if err := resultError(C.ghostty_row_get(r.c, C.GHOSTTY_ROW_DATA_STYLED, unsafe.Pointer(&v))); err != nil { return false, err } return bool(v), nil}
// Hyperlink reports whether any cells in the row have hyperlinks// (may have false positives).func (r *Row) Hyperlink() (bool, error) { var v C.bool if err := resultError(C.ghostty_row_get(r.c, C.GHOSTTY_ROW_DATA_HYPERLINK, unsafe.Pointer(&v))); err != nil { return false, err } return bool(v), nil}
// Semantic returns the semantic prompt state of the row.func (r *Row) Semantic() (RowSemanticPrompt, error) { var v C.GhosttyRowSemanticPrompt if err := resultError(C.ghostty_row_get(r.c, C.GHOSTTY_ROW_DATA_SEMANTIC_PROMPT, unsafe.Pointer(&v))); err != nil { return 0, err } return RowSemanticPrompt(v), nil}
// KittyVirtualPlaceholder reports whether the row contains a// Kitty virtual placeholder.func (r *Row) KittyVirtualPlaceholder() (bool, error) { var v C.bool if err := resultError(C.ghostty_row_get(r.c, C.GHOSTTY_ROW_DATA_KITTY_VIRTUAL_PLACEHOLDER, unsafe.Pointer(&v))); err != nil { return false, err } return bool(v), nil}
// Dirty reports whether the row is dirty and requires a redraw.func (r *Row) Dirty() (bool, error) { var v C.bool if err := resultError(C.ghostty_row_get(r.c, C.GHOSTTY_ROW_DATA_DIRTY, unsafe.Pointer(&v))); err != nil { return false, err } return bool(v), nil}