diff --git a/vt/csi_mode.go b/vt/csi_mode.go index 4402905a..65387779 100644 --- a/vt/csi_mode.go +++ b/vt/csi_mode.go @@ -44,7 +44,7 @@ func (e *Emulator) setAltScreenMode(on bool) { e.scr = &e.scrs[1] e.scrs[1].cur = e.scrs[0].cur e.scr.Clear() - e.scr.buf.Touched = nil + e.scr.ClearTouched() e.setCursor(0, 0) } else { e.scr = &e.scrs[0] diff --git a/vt/go.mod b/vt/go.mod index 5f389817..7e370eb4 100644 --- a/vt/go.mod +++ b/vt/go.mod @@ -3,25 +3,25 @@ module github.com/charmbracelet/x/vt go 1.24.2 require ( - github.com/charmbracelet/ultraviolet v0.0.0-20251106193841-7889546fc720 + github.com/charmbracelet/ultraviolet v0.0.0-20260303162955-0b88c25f3fff github.com/charmbracelet/x/ansi v0.11.6 github.com/charmbracelet/x/exp/ordered v0.1.0 ) require ( - github.com/charmbracelet/colorprofile v0.3.3 // indirect + github.com/charmbracelet/colorprofile v0.4.2 // indirect github.com/charmbracelet/x/term v0.2.2 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect github.com/charmbracelet/x/windows v0.2.2 // indirect github.com/clipperhouse/displaywidth v0.9.0 // indirect github.com/clipperhouse/stringish v0.1.1 // indirect - github.com/clipperhouse/uax29/v2 v2.5.0 // indirect + github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-runewidth v0.0.19 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/sync v0.17.0 // indirect - golang.org/x/sys v0.37.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.41.0 // indirect ) diff --git a/vt/go.sum b/vt/go.sum index b4174ba8..92af3a0e 100644 --- a/vt/go.sum +++ b/vt/go.sum @@ -1,7 +1,11 @@ github.com/charmbracelet/colorprofile v0.3.3 h1:DjJzJtLP6/NZ8p7Cgjno0CKGr7wwRJGxWUwh2IyhfAI= github.com/charmbracelet/colorprofile v0.3.3/go.mod h1:nB1FugsAbzq284eJcjfah2nhdSLppN2NqvfotkfRYP4= +github.com/charmbracelet/colorprofile v0.4.2 h1:BdSNuMjRbotnxHSfxy+PCSa4xAmz7szw70ktAtWRYrY= +github.com/charmbracelet/colorprofile v0.4.2/go.mod h1:0rTi81QpwDElInthtrQ6Ni7cG0sDtwAd4C4le060fT8= github.com/charmbracelet/ultraviolet v0.0.0-20251106193841-7889546fc720 h1:Pny/vp+ySKst82CWEME1oP6YEFs/17tlH+QOjqW7VUY= github.com/charmbracelet/ultraviolet v0.0.0-20251106193841-7889546fc720/go.mod h1:Y8B4DzWeTb0ama8l3+KyopZtkE8fZjwRQ3aEAPEXHE0= +github.com/charmbracelet/ultraviolet v0.0.0-20260303162955-0b88c25f3fff h1:uY7A6hTokHPJBHfq7rj9Y/wm+IAjOghZTxKfVW6QLvw= +github.com/charmbracelet/ultraviolet v0.0.0-20260303162955-0b88c25f3fff/go.mod h1:E6/0abq9uG2SnM8IbLB9Y5SW09uIgfaFETk8aRzgXUQ= github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ= github.com/charmbracelet/x/exp/ordered v0.1.0 h1:55/qLwjIh0gL0Vni+QAWk7T/qRVP6sBf+2agPBgnOFE= @@ -18,6 +22,8 @@ github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfa github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U= github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= +github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= +github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= @@ -32,5 +38,9 @@ golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= diff --git a/vt/screen.go b/vt/screen.go index a2eae20b..a4efe92c 100644 --- a/vt/screen.go +++ b/vt/screen.go @@ -10,7 +10,7 @@ type Screen struct { // cb is the callbacks struct to use. cb *Callbacks // The buffer of the screen. - buf uv.Buffer + buf *uv.RenderBuffer // The cur of the screen. cur, saved Cursor // scroll is the scroll region. @@ -19,8 +19,10 @@ type Screen struct { // NewScreen creates a new screen. func NewScreen(w, h int) *Screen { - s := Screen{} - s.Resize(w, h) + s := Screen{ + buf: uv.NewRenderBuffer(w, h), + } + s.scroll = s.buf.Bounds() return &s } @@ -32,6 +34,7 @@ func (s *Screen) Reset() { s.cur = Cursor{} s.saved = Cursor{} s.scroll = s.buf.Bounds() + s.buf.Touched = nil } // Bounds returns the bounds of the screen. @@ -44,6 +47,11 @@ func (s *Screen) Touched() []*uv.LineData { return s.buf.Touched } +// ClearTouched clears the touched state. +func (s *Screen) ClearTouched() { + s.buf.Touched = nil +} + // CellAt returns the cell at the given x, y position. func (s *Screen) CellAt(x int, y int) *uv.Cell { return s.buf.CellAt(x, y) @@ -61,7 +69,12 @@ func (s *Screen) Height() int { // Resize resizes the screen. func (s *Screen) Resize(width int, height int) { - s.buf.Resize(width, height) + if s.buf == nil { + s.buf = uv.NewRenderBuffer(width, height) + } else { + s.buf.Resize(width, height) + s.buf.Touched = nil + } s.scroll = s.buf.Bounds() } @@ -78,6 +91,7 @@ func (s *Screen) Clear() { // ClearArea clears the given area. func (s *Screen) ClearArea(area uv.Rectangle) { s.buf.ClearArea(area) + s.touchArea(area) } // Fill fills the screen or part of it. @@ -88,6 +102,7 @@ func (s *Screen) Fill(c *uv.Cell) { // FillArea fills the given area with the given cell. func (s *Screen) FillArea(c *uv.Cell, area uv.Rectangle) { s.buf.FillArea(c, area) + s.touchArea(area) } // setHorizontalMargins sets the horizontal margins. @@ -327,3 +342,10 @@ func (s *Screen) blankCell() *uv.Cell { c.Style.Bg = s.cur.Pen.Bg return &c } + +// touchArea marks all lines in the given area as touched. +func (s *Screen) touchArea(area uv.Rectangle) { + for y := area.Min.Y; y < area.Max.Y; y++ { + s.buf.TouchLine(area.Min.X, y, area.Max.X-area.Min.X) + } +}