← back

okami.mom/ultraviolet

git clone https://git.nkp.pet/okami.mom/ultraviolet

nekomimi.petfix(input): keep control strings whole when they span reads7bfbaab

main
5 folders85 files

files

.github/
examples/
internal/
layout/
screen/
.gitattributes15 B
.golangci.yml790 B
.goreleaser.yml168 B
LICENSE1.0 KiB
README.md5.6 KiB
TUTORIAL.md3.9 KiB
border.go6.2 KiB
border_test.go8.0 KiB
buffer.go23.2 KiB
buffer_test.go19.5 KiB
cancelreader_other.go373 B
cancelreader_test.go102 B
cancelreader_windows.go3.2 KiB
cell.go11.2 KiB
cell_iszero_test.go2.6 KiB
cell_test.go16.2 KiB
console.go5.5 KiB
console_unix.go200 B
console_windows.go204 B
cursor.go481 B
cursor_test.go530 B
decoder.go53.9 KiB
decoder_test.go18.2 KiB
doc.go1.4 KiB
environ.go904 B
event.go16.9 KiB
event_test.go9.9 KiB
go.mod649 B
go.sum2.6 KiB
grapheme_width_test.go3.8 KiB
key.go16.2 KiB
key_table.go22.6 KiB
key_test.go63.1 KiB
logger.go119 B
mouse.go4.8 KiB
pipeconsole_test.go2.7 KiB
poll.go1.3 KiB
poll_bsd.go3.5 KiB
poll_default.go435 B
poll_default_test.go1.6 KiB
poll_fallback.go3.1 KiB
poll_fallback_test.go1.8 KiB
poll_linux.go3.6 KiB
poll_select.go3.2 KiB
poll_solaris.go265 B
poll_test.go278 B
poll_windows.go5.6 KiB
split_string_test.go2.1 KiB
styled.go14.5 KiB
styled_test.go24.7 KiB
tabstop.go3.0 KiB
tabstop_test.go6.3 KiB
terminal.go11.4 KiB
terminal_bsdly.go189 B
terminal_bsdly_other.go155 B
terminal_input_test.go2.0 KiB
terminal_other.go660 B
terminal_reader.go14.6 KiB
terminal_reader_other.go262 B
terminal_reader_windows.go9.6 KiB
terminal_renderer.go60.3 KiB
terminal_renderer_hardscroll.go5.7 KiB
terminal_renderer_hashmap.go7.2 KiB
terminal_renderer_output_test.go7.3 KiB
terminal_renderer_test.go67.1 KiB
terminal_screen.go25.8 KiB
terminal_stop_test.go1.2 KiB
terminal_tabdly.go228 B
terminal_tabdly_other.go196 B
terminal_test.go620 B
terminal_unix.go1.3 KiB
terminal_windows.go2.1 KiB
transformline_bug_test.go1.4 KiB
tty.go1.3 KiB
tty_other.go633 B
tty_unix.go947 B
tty_windows.go1007 B
utils.go186 B
uv.go11.4 KiB
widecell_placeholder_test.go1.9 KiB
width_test.go3.3 KiB
winch.go1.4 KiB
winch_other.go474 B
winch_unix.go996 B
window.go4.6 KiB

Ultraviolet

[!NOTE] This is a fork of charmbracelet/ultraviolet used by albedo. main is upstream (the upstream branch) plus one patch: the input reader keeps OSC, DCS and other ST-terminated replies whole when a read ends between the ESC and backslash of the terminator, and holds a partial OSC 5522 clipboard reply up to 5 seconds instead of flushing it at the 50 ms escape timeout. Use it with replace github.com/charmbracelet/ultraviolet => tangled.org/okami.mom/ultraviolet <version>.

<img width="400" alt="Charm Ultraviolet" src="https://github.com/user-attachments/assets/3484e4b0-3741-4e8c-bebf-9ea51f5bb49c" /> <p> <a href="https://pkg.go.dev/github.com/charmbracelet/ultraviolet?tab=doc"><img src="https://godoc.org/github.com/charmbracelet/ultraviolet?status.svg" alt="GoDoc"></a> <a href="https://github.com/charmbracelet/ultraviolet/actions"><img src="https://github.com/charmbracelet/ultraviolet/actions/workflows/build.yml/badge.svg" alt="Build Status"></a> </p>

Ultraviolet is a set of primitives for building terminal user interfaces in Go. It provides cell-based rendering, cross-platform input handling, and a diffing renderer inspired by ncurses—without the need for terminfo or termcap databases.

Ultraviolet powers Bubble Tea v2 and Lip Gloss v2. It replaces the ad-hoc terminal primitives from earlier versions with a cohesive, imperative API that can also be used standalone.

Install

go get github.com/charmbracelet/ultraviolet@latest

Quick Start

package main

import (
	"log"

	uv "github.com/charmbracelet/ultraviolet"
	"github.com/charmbracelet/ultraviolet/screen"
)

func main() {
	t := uv.DefaultTerminal()
	scr := t.Screen()

	scr.EnterAltScreen()

	if err := t.Start(); err != nil {
		log.Fatalf("failed to start terminal: %v", err)
	}
	defer t.Stop()

	ctx := screen.NewContext(scr)
	text := "Hello, World!"
	textWidth := scr.StringWidth(text)

	display := func() {
		screen.Clear(scr)
		bounds := scr.Bounds()
		x := (bounds.Dx() - textWidth) / 2
		y := bounds.Dy() / 2
		ctx.DrawString(text, x, y)
		scr.Render()
		scr.Flush()
	}

	for ev := range t.Events() {
		switch ev := ev.(type) {
		case uv.WindowSizeEvent:
			scr.Resize(ev.Width, ev.Height)
			display()
		case uv.KeyPressEvent:
			if ev.MatchString("q", "ctrl+c") {
				return
			}
		}
	}
}

Architecture

Ultraviolet is organized as a set of layered primitives:

Features

Examples

See the examples/ directory for core examples and examples/advanced/ for more complex demos.

Tutorial

See TUTORIAL.md for a step-by-step guide to building your first Ultraviolet application.

[!NOTE] Ultraviolet is in active development. The API may change.

Feedback

We'd love to hear your thoughts on this project. Feel free to drop us a note!

License

MIT


Part of Charm.

<a href="https://charm.sh/"><img alt="The Charm logo" width="400" src="https://stuff.charm.sh/charm-banner-next.jpg" /></a>

Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة