chat

package
v0.0.0-...-7d0a1c9 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Package chat is crates/hover-chat: the chat thread laid out as positioned text boxes and shapes, with selection, copy, scrolling and a painter. It follows the box model of web/office/page.html's #thread, .you, .who, .ans and .md rules.

Index

Constants

View Source
const (
	// Thick is the bar's thickness, and each arrow button's length along the bar.
	Thick = 10

	// LineStep: an arrow button scrolls by 40 px (Chromium's line step); the track by 87.5 % of a page.
	LineStep = 40
)
View Source
const (
	Sans  = `Inter, "Segoe UI Variable Text", "Segoe UI", system-ui, sans-serif`
	Mono  = `"Cascadia Code", Consolas, "DejaVu Sans Mono", monospace`
	Pixel = `"Pixelify Sans", "Cascadia Code", Consolas, monospace`
)

The page asks for Inter first, but Inter is loaded only into WPF, never into WebView2, so the office's text is really the next family the system has: Segoe UI Variable Text on Windows 11, Segoe UI on 10. The native chat resolves the same list against system fonts only (Hover's bundled Inter is not registered here) to land on the same face.

View Source
const (
	ThreadGap = 7
	// .you, .ans { font-size: 12.5px }, .ans { line-height: 1.5 }
	Body   = 12.5
	BodyLH = 1.5
)

Variables

View Source
var (
	Ink          = a(0xf6f2ff, 1.0)
	Dim          = a(0xf6f2ff, 0.62)
	Faint        = a(0xf6f2ff, 0.38)
	Line         = a(0xffffff, 0.09)
	Li           = a(0xc4a2ff, 1.0)
	Ok           = a(0x30d158, 1.0)
	Bad          = a(0xff453a, 1.0)
	LinkLine     = a(0xc4a2ff, 0.4)
	CodeBG       = a(0xffffff, 0.08)
	PreBG        = a(0x000000, 0.35)
	FigureBG     = a(0x000000, 0.25)
	ImgBG        = a(0xffffff, 0.04) // .md img { background: rgba(255,255,255,.04) }
	ThBG         = a(0xffffff, 0.05)
	QuoteBar     = a(0xc4a2ff, 0.4)
	YouBG        = a(0x24212a, 1.0) // .me: graphite, not purple.
	YouEdge      = a(0xffffff, 0.06)
	Selection    = a(0x3390ff, 0.45) // Chromium's selection colour on a dark page.
	DrawerBG     = C(22, 14, 26, 255)
	ScrollTrack  = a(0xfcfcfc, 1.0) // The thin Fluent scrollbar, as Chromium draws it.
	ScrollThumb  = a(0x8b8b8b, 1.0)
	ScrollThumbH = a(0x636363, 1.0)
	Visor        = a(0x121018, 1.0)
	Eye          = a(0xaaf6ff, 1.0)
	Bulb         = a(0xffd24a, 1.0)
)

The chat's look, taken from web/office/page.html. The values are those of the notch (the page's `max-height: 620px` rules apply there, because the office opens 280-600 tall). Sizes are CSS px; the painter multiplies them by the display scale.

View Source
var Bots = [6]Bot{{"Pip", C(0x9b, 0x6b, 0xff, 255)}, {"Juno", C(0x2f, 0xc9, 0xb0, 255)}, {"Moss", C(0xff, 0x9a, 0x4a, 255)},
	{"Nova", C(0xff, 0x6f, 0xae, 255)}, {"Ada", C(0x5a, 0xa8, 0xff, 255)}, {"Rue", C(0xb4, 0xe0, 0x4a, 255)}}

Bots is main.js BOTS: the six bots' names and colours, by `bot` index.

View Source
var ThreadPad = [4]float32{8, 12, 4, 12}

#thread { padding: 8px 12px 4px; gap: 7px }, as top, right, bottom, left.

Functions

func Avatar

func Avatar(out *[]Shape, x, y, w, h, r float32, c Rgba)

Avatar is `.av`: the mascot's head as a little avatar (visor, two eyes, antenna bulb).

func Clock

func Clock(ms float64) string

Clock is main.js `clockOf`: how long a running turn has gone, "m:ss".

func Credits

func Credits(n float64) string

Credits is main.js `credits`: what a turn cost, "0.09 credits", and "<0.01 credits" for less.

func EaseOut

func EaseOut(x float32) float32

EaseOut is CSS `ease-out`, cubic-bezier(0, 0, 0.58, 1).

func Hm

func Hm(ms float64, offsetMin int64) string

Hm is main.js `hm`: toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' }) as en-US writes it ("1:47 PM"), at the given offset from UTC in minutes.

func LogoSVG

func LogoSVG(tool string) string

LogoSVG is `.lg.mini`: the tool's own logo in its 16 px rounded square (main.js LOGOS, on the page's viewBoxes: 24 units, Codex's 3 2.9 18 18.2; OpenCode's drawn for Hover).

func Took

func Took(ms float64) string

Took is main.js `took`: seconds under a minute (at least 1), then "3m 07s", then "1h 05m".

Types

type Act

type Act struct {
	Kind ActKind
	Text string
	I    int
	Now  bool
	K    uint32
}

type ActKind

type ActKind uint8

ActKind is what a click on a drawn control does.

const (
	// ActCopy is a Copy button: Text is what it copies (a code block, a diff, an answer).
	ActCopy ActKind = iota + 1
	// ActStep: a step with a change or output opens or folds: I is the step, Now the "now" row.
	ActStep
	// ActFlag is one of a step's own switches: I is the step, K which. 0 shows all of a long
	// change, output or thought; 1 the subagents past the fourth; 2 + k subagent k's result.
	ActFlag
	// ActOpenDiff: a file under the answer: its change opens in the timeline (I is its step).
	ActOpenDiff
	// ActRetry: the newest turn's Retry: its prompt goes again.
	ActRetry
	// ActRestore: back to just after this turn's answer.
	ActRestore
	// ActTryAgain: back to just before this turn's message, which goes again.
	ActTryAgain
	// ActEdit: a queued reply taken back into the composer to be changed.
	ActEdit
	// ActEditPrompt: a sent prompt's Edit: its words go into the reply box to be changed and sent again.
	ActEditPrompt
	// ActSendNow: a queued reply sent now, ahead of the others.
	ActSendNow
	// ActGroup: a group's header: its steps (from step I) open or fold.
	ActGroup
)

type Bar

type Bar struct {
	Vertical bool
	X, Y     float32
	Len      float32
	// Content is the content's length, View how much of it shows, Pos how far it is scrolled.
	Content, View, Pos float32
}

Bar is one scrollbar: where it is (x, y along the top or left edge, and its length) and what it scrolls.

func (Bar) Along

func (b Bar) Along(px, py float32) (float32, bool)

Along is the point's distance along the bar, or false when it is off the bar.

func (Bar) Drag

func (b Bar) Drag(grab, along float32) float32

Drag is the scroll position for a thumb dragged so that the point grab px into it is at along.

func (Bar) Max

func (b Bar) Max() float32

func (Bar) Part

func (b Bar) Part(along float32) Part

func (Bar) Step

func (b Bar) Step(p Part, along float32) float32

Step is where a press on part scrolls to, one step. A track press stops once the thumb reaches the pointer (at along), as Chromium's repeating track press does.

func (Bar) Thumb

func (b Bar) Thumb() (float32, float32)

Thumb is the thumb's start and length, along the bar from its start.

type BarID

type BarID struct {
	Thread bool
	S, K   int
}

BarID names a scrollbar: the thread's, or a box's by (section, scroller).

type Block

type Block struct {
	Text     string
	Rect     Rect4
	Selected [2]int
	HasSel   bool
}

Block is one text box for assistive technology: its text, its rectangle in thread coordinates, and the part of it that is selected (bytes).

type Bot

type Bot struct {
	Name  string
	Color Rgba
}

Bot is a bot's name and colour.

type BoxBar

type BoxBar struct {
	ID  [2]int
	Bar Bar
}

Bars are the sideways scrollbars, in thread coordinates, with their (section, scroller).

type Boxed

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

Boxed is a block's box: its collapsible outer margins and its border-box height.

type Fetch

type Fetch struct {
	Kind  FetchKind
	Bytes []byte
}

type FetchKind

type FetchKind uint8
const (
	FetchBytes FetchKind = iota
	// FetchPending: asked for, not here yet.
	FetchPending
	FetchFailed
)

type Frag

type Frag struct {
	Texts     []TextBox
	Shapes    []Shape
	Copy      []Tok
	Scrollers []Scroller
	Hits      []HitRect
}

Frag is laid-out content in coordinates relative to its own top left.

type HL

type HL struct {
	B0, B1 int
	Color  Rgba
	Em     bool
}

HL is a coloured stretch of a code block: bytes B0..B1, and whether it is drawn italic.

func Highlight

func Highlight(info, text string) []HL

Highlight is a small tokenizer for the common languages, picked by the fence's language or a file's extension: keywords, calls, capitalised types, numbers, strings, comments. ponytail: a lexer per language would get every case (raw strings, nested comments, heredocs); this gets the common ones, and an unknown language stays plain.

type Hit

type Hit struct {
	Kind    HitKind
	Link    string
	Section int
	Act     Act
	Pos     Pos
}

Hit is what is under a point.

type HitKind

type HitKind uint8
const (
	HitNone HitKind = iota
	HitLink
	// HitAct is a control in a turn: (section, what it does).
	HitAct
	HitText
)

type HitRect

type HitRect struct {
	R   Rect4
	Act Act
}

HitRect is a clickable place and what it does.

type ImageKind

type ImageKind uint8
const (
	ImageReady ImageKind = iota
	ImagePending
	ImageBroken
)

type ImageState

type ImageState struct {
	Kind ImageKind
	W, H float32
}

ImageState is an image as the layout sees it. A pending and a failed image look the same in the page (Chromium shows the broken-image icon and the alt text for both).

type Images

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

func NewImages

func NewImages(l Loader) *Images

func NoImages

func NoImages() *Images

NoImages loads nothing (tests, and the headless screenshots unless told otherwise).

func (*Images) Forget

func (im *Images) Forget(src string)

Forget drops an image, so it is asked for again (a retry, or a file that changed).

func (*Images) Image

func (im *Images) Image(src string) image.Image

Image is the decoded picture, or nil when there is none (yet).

func (*Images) State

func (im *Images) State(src string) ImageState
type Link struct {
	B0, B1 int
	URL    string
}

Link is a stretch of a text box (bytes) that opens an address.

type Loader

type Loader func(src string) Fetch

type Look

type Look struct {
	Size, LH float32
	Color    Rgba
	Weight   float32
	Family   string
}

Look is text styling at one point: what page.html's cascade gives a run.

type NumLine

type NumLine struct {
	N    int64
	HasN bool
	Gap  bool
	Text string
}

Numbered is a step's change as its lines, each with the file's line number when the change says where it is ("@@ -old +new @@" before its lines; hover-agents writes one only when it knows): a removed line has its old number, the others their new one. A line with Gap set is the gap between two parts of the change. With no header, no numbers.

func Numbered

func Numbered(diff string) []NumLine

type Painter

type Painter struct {

	// Images is shared with the thread (it lays images out by their size).
	Images *Images

	// Frames counts painted frames, for the benchmark.
	Frames uint64
	// Time is in seconds, for the live step's shimmer (a 2 s loop, as `@keyframes flow`).
	Time float32
	// Hover is the scrollbar whose thumb is under the pointer (it darkens).
	Hover    BarID
	HasHover bool
	// contains filtered or unexported fields
}

Painter paints the visible part of a thread into a pixel buffer: shapes, selection, glyphs (outlines, unhinted like Chromium's DirectWrite path), decorations, images and diagrams. Only the viewport is painted, and glyph masks, decoded images and rasterised diagrams are cached, so a scroll or a streamed chunk costs one viewport of drawing.

func NewPainter

func NewPainter(sh *Shaper, images *Images) *Painter

NewPainter makes a painter; sh gives a flowchart's text its fonts.

func (*Painter) Bar

func (p *Painter) Bar(cv *raster.Canvas, b Bar, k float32, hover bool, radius [4]float32)

Bar draws a scrollbar (in CSS px of the buffer): the track, the arrow buttons and the 6 px thumb. radius rounds the track's corners (top left, top right, bottom right, bottom left) where the box's border does.

func (*Painter) Fading

func (p *Painter) Fading(th *Thread) bool

Fading says whether a frame drawn now would differ from the last because of time alone (the fresh answer's fade).

func (*Painter) Paint

func (p *Painter) Paint(th *Thread, scroll float32, w, h int, scale float32, bg Rgba) *image.RGBA

Paint paints th from scroll (thread px) into a w x h device-pixel buffer. The buffer is the painter's own and is drawn over by the next call.

type Part

type Part int
const (
	PartBack Part = iota
	PartForward
	PartTrackBack
	PartTrackForward
	PartThumb
)

type Pos

type Pos struct {
	Section, Text, Byte int
}

Pos is a place in the text: a section, a text box in it, and a byte of the box.

type Rect4

type Rect4 [4]float32

Rect4 is x, y, w, h.

type Rgba

type Rgba = color.NRGBA

Rgba is a colour with straight (not premultiplied) alpha.

func C

func C(r, g, b, a uint8) Rgba

C is a colour from its parts (a keyed literal, which go vet wants of an alias).

type Scroller

type Scroller struct {
	// Clip is where the content shows (x, y, w, h): the padding box less the bar, which sits just under it.
	Clip Rect4
	// Content is the scrollable width.
	Content float32
	// Shapes scroll with the content (a table's header fill and row rules).
	Shapes []Shape
}

Scroller is a box with `overflow: auto` that is wider inside than out (a code block, a table): its content scrolls sideways under a thin scrollbar along its bottom.

func (*Scroller) Max

func (s *Scroller) Max() float32

type Section

type Section struct {
	Y, H float32
	Frag *Frag
	// AnswerTok is where the answer's copy tokens start (a select-all inside `.ans`).
	AnswerTok    int
	HasAnswerTok bool
	// AnswerAt is where the answer's texts, shapes and scrolling boxes start (it fades in on its own).
	AnswerAt    [3]int
	HasAnswerAt bool
	// Images are the answer's images, and stale says one of them changed since it was laid out.
	Images []string
	// contains filtered or unexported fields
}

Section is one turn laid out.

type Shape

type Shape struct {
	Kind       ShapeKind
	X, Y, W, H float32
	Radius     [4]float32
	Fill       Rgba
	Stroke     Rgba
	SW         float32
	Src        string // Image: the source; Svg: the document
	Cover      bool   // Image: object-fit: cover (a prompt's thumbnails)
	Pts        [][2]float32
}

Shape is something drawn. A Rect has Radius per corner, a Fill (transparent: none) and a border of width SW in Stroke.

type ShapeKind

type ShapeKind uint8
const (
	ShapeRect ShapeKind = iota
	ShapeImage
	// ShapeLine is an open polyline (Fill is its colour, SW its width).
	ShapeLine
	ShapeSvg
	// ShapeBroken is Chromium's broken-image icon (14 x 16), at the top left of an image that isn't there.
	ShapeBroken
	// ShapeGlow: X, Y the centre and W the radius.
	ShapeGlow
)

type Shaper

type Shaper struct {
	*text.Shaper
}

Shaper lays paragraphs out with the fonts it was made with.

func NewShaper

func NewShaper(f *text.Fonts) *Shaper

type Smooth

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

Smooth is a user scroll's animation, as cc's ScrollOffsetAnimationCurve animates a wheel, arrow or track scroll: ease-in-out (0.42, 0, 0.58, 1) over 6 to 12 frames at 60 Hz, shorter the further it goes (kInverseDelta: 12 frames up to 120 px, 6 from 480 px). A new scroll during one retargets it, keeping its speed (UpdateTarget). Times are seconds from any fixed start.

func NewSmooth

func NewSmooth(from, to float32, now float64) *Smooth

func (*Smooth) Done

func (s *Smooth) Done(now float64) bool

func (*Smooth) Retarget

func (s *Smooth) Retarget(to float32, now float64)

Retarget heads for a new target from where the scroll is now, at the speed it has.

func (*Smooth) Target

func (s *Smooth) Target() float32

func (*Smooth) Value

func (s *Smooth) Value(now float64) float32

type Stage

type Stage uint8

Stage is how far a turn has got.

const (
	StageWaking Stage = iota
	StageWorking
	StageDone
	StageFailed
	StageStopped
)

type Step

type Step struct {
	Kind      StepIcon
	Verb      string
	Name, Dir string
	Cmd       string
	Status    string
	Add, Del  int
	Diff, Out string
	Exit      int
	HasExit   bool
	Ms        float64
	HasMs     bool
	// Tag is the demo's own tag ("81 passed"): a check and the words.
	Tag string
	// Lead is what the agent said just before this step, shown above it.
	Lead string
}

Step is one step as the host sends it (KiroPage.Row): its kind's icon, a verb, and the file (name and folder) or the command it was about, with the change it made or what the command printed, and how it went. A string field is empty when the host sent none.

func StepOf

func StepOf(x any) Step

Step reads a step: an object from Hover, or the demo's array (main.js stepOf).

type StepIcon

type StepIcon uint8

StepIcon is a step's icon (main.js ICON): the host sends one of these per step. Thought is the reasoning the tool exposed; Agent a subagent it started (OpenCode's task tool).

const (
	IconThink StepIcon = iota
	IconRead
	IconEdit
	IconRun
	IconSearch
	IconThought
	IconAgent
)

func ParseIcon

func ParseIcon(s string) StepIcon

type Tail

type Tail uint8

Tail is what a selection that runs on past its last box takes in after it.

const (
	TailNone Tail = iota
	// TailNewline: one newline: a double click at the very end of a block selects the break after it.
	TailNewline
	// TailBlock: the block end's newlines: a triple click selects a whole paragraph.
	TailBlock
)

type TextBox

type TextBox struct {
	Layout *text.Layout
	X, Y   float32
	// Text is the text as laid out, for copying (inline boxes are not in it). Empty for
	// drawn-only text (list markers, the code block's language tag, an ellipsis).
	Text  string
	Links []Link
	// Clip is `overflow: auto` of the box it sits in, in the same coordinates as X, Y.
	Clip *Rect4
	// Shimmer: the live step's moving highlight (`.work .on` in page.html).
	Shimmer bool
	// Cell: a table cell: a double or triple click stays inside it.
	Cell bool
	// Scr is the box that scrolls it sideways: an index into Frag.Scrollers plus one (0: none).
	Scr int
}

TextBox is a laid-out paragraph at a place.

type Thread

type Thread struct {
	Width    float32
	Who      string
	Color    Rgba
	Sections []Section
	Height   float32
	// Selection is the anchor and focus; Tail is what it takes in after its last box.
	Sel    [2]Pos
	HasSel bool
	Tail   Tail
	// ImageState and ImageRule: what the layout knows of an image, and where one may load from.
	ImageState func(string) ImageState
	ImageRule  md.ImageFn

	// Session is the session shown (its id in the state message), for stepsUser.
	Session   uint64
	HideSteps bool
	// Tool is the tool, for its logo over each answer.
	Tool string

	// Copied is the code block just copied (its button says "Copied" a moment).
	Copied *string
	// ViewH is the thread's visible height.
	ViewH float32
	// Relayouts counts section layouts made since the thread was created (for the tests and the benchmark).
	Relayouts int
	// HScroll is how far each sideways-scrolling box is scrolled, by (section, scroller). A
	// section laid out again starts at 0, as the page's re-rendered answer does.
	HScroll map[[2]int]float32
	// Fresh is `.ans.fresh`: the section whose answer just arrived, and when (the painter's clock).
	FreshSection int
	FreshAt      float32
	HasFresh     bool

	// ExtraBottom is room kept under the last turn (the reply circle sits over the thread's corner).
	ExtraBottom float32
	// Ticking: a command is running: its time counts, so the app lays the thread out again each second.
	Ticking bool
	// contains filtered or unexported fields
}

Thread is the whole chat, laid out.

func NewThread

func NewThread(sh *Shaper, who string, color Rgba) *Thread

func (*Thread) AccessibleBlocks

func (th *Thread) AccessibleBlocks() []Block

func (*Thread) AnswerText

func (th *Thread) AnswerText(i int) string

AnswerText is a select-all inside turn i's answer (`.ans`), as the page copies it.

func (*Thread) BoxAt

func (th *Thread) BoxAt(x, y float32) ([2]int, bool)

BoxAt is the sideways-scrolling box under a point in thread coordinates.

func (*Thread) Document

func (th *Thread) Document(src string, width float32)

Document lays src out as Markdown on its own, the way an answer is, for a page outside the chat (the desk's pull request description): one section with no prompt, name or buttons. width is the text's; the painter adds the thread's side padding on each side, so paint it width + 24 wide.

func (*Thread) HBars

func (th *Thread) HBars() []BoxBar

func (*Thread) Hit

func (th *Thread) Hit(x, y float32) Hit

Hit finds what is under a point in thread coordinates (y from the thread's top).

func (*Thread) ImageChanged

func (th *Thread) ImageChanged(src string) bool

ImageChanged: an image arrived (or failed): the sections that show it are laid out again on the next Set. It returns whether any does.

func (*Thread) OffsetOf

func (th *Thread) OffsetOf(section int, t *TextBox) float32

OffsetOf is how far a text box is moved left by the box that scrolls it.

func (*Thread) OpenDiff

func (th *Thread) OpenDiff(turns []Turn, section, j int) (float32, bool)

OpenDiff: a file under the answer was clicked: the timeline opens on its change. It returns where its row is now, in thread coordinates.

func (*Thread) ParagraphAt

func (th *Thread) ParagraphAt(p Pos) (Pos, Pos, Tail)

ParagraphAt is the paragraph a triple click at caret p selects: the line between hard breaks (a <br>, or a newline in code), and the break that ends it. The last line of a block takes the block's end; a table cell is selected alone.

func (*Thread) ScrollBox

func (th *Thread) ScrollBox(id [2]int, pos float32)

ScrollBox scrolls a box sideways (clamped to its content).

func (*Thread) Select

func (th *Thread) Select(anchor, focus Pos)

Select makes a selection from the anchor to the focus (none when they are the same).

func (*Thread) SelectAll

func (th *Thread) SelectAll()

SelectAll selects everything, as a select-all over the thread does.

func (*Thread) SelectUnits

func (th *Thread) SelectUnits(a0, a1 Pos, at Tail, focus Pos, u Unit)

SelectUnits selects a unit, or (after a double or triple click, while dragging) the anchor's unit grown by whole units to the one at focus, as Chromium extends by granularity.

func (*Thread) SelectedIn

func (th *Thread) SelectedIn(section, text int) (int, int, bool)

SelectedIn is the selected bytes of one text box, if any.

func (*Thread) SelectedText

func (th *Thread) SelectedText() string

SelectedText is the selected text as the page would copy it (see Tok).

func (*Thread) SelectionRects

func (th *Thread) SelectionRects(section, text int) []struct{ X0, Y0, X1, Y1 float32 }

SelectionRects are the selection's rectangles for one text box, in its own coordinates.

func (*Thread) Set

func (th *Thread) Set(turns []Turn, width float32)

Set lays the thread out for the drawer's width, re-using every section whose turn, width and step-list state haven't changed.

func (*Thread) SetCopied

func (th *Thread) SetCopied(turns []Turn, t *string)

SetCopied: a code block's Copy was clicked: its button says so until the copy is done with.

func (*Thread) ToggleFlag

func (th *Thread) ToggleFlag(turns []Turn, section, j int, k uint32)

ToggleFlag flips a step's switch (a long change shown whole, more subagents, one's result).

func (*Thread) ToggleGroup

func (th *Thread) ToggleGroup(turns []Turn, ti, first int)

ToggleGroup: a click on a group's header: it opens or folds, and stays that way.

func (*Thread) ToggleStep

func (th *Thread) ToggleStep(turns []Turn, section, j int, now bool)

ToggleStep: a click on a step with a change or output: its block opens or folds.

func (*Thread) ToggleSteps

func (th *Thread) ToggleSteps(turns []Turn, i int)

ToggleSteps opens or folds all of turn i's step groups, as its first one goes.

func (*Thread) TrailingSpace

func (th *Thread) TrailingSpace(p Pos) Pos

TrailingSpace: WebView2 (Windows editing behaviour) also selects the spaces after a double-clicked word, up to the next non-space or line break, inside the block.

func (*Thread) UnitAt

func (th *Thread) UnitAt(p Pos, u Unit) (Pos, Pos, Tail)

UnitAt is the unit around caret p, as (start, end, tail).

func (*Thread) UseImages

func (th *Thread) UseImages(im *Images)

UseImages lays images out by their state in a shared cache (the painter's).

func (*Thread) WordAt

func (th *Thread) WordAt(p Pos) (Pos, Pos, Tail)

WordAt is the word a double click at caret p selects. The caret is the boundary nearest the pointer, and the word is the one that starts there when it is on a boundary (Chromium's word granularity), so the right half of a word's last letter selects what follows it; but at the end of a soft-wrapped line it is the word before (ChooseWordSide in Blink's selection_adjuster.cc). At a block's end that is the break to the next block; a table cell selects nothing there.

type Tok

type Tok struct {
	Kind TokKind
	N    int
	S    string
}

Tok is what a copy is made of, in document order: the page's selection serialiser (Chromium's) adds newlines at block edges, and this reproduces what it gives for the blocks md.js writes. The rules were read off the real page (tests/golden/copy.json and the block-pair table in port/phase1/REPORT.md).

type TokKind

type TokKind uint8

TokKind is a piece of what a copy is made of.

const (
	// TokText is a selectable text box (N is an index into Frag.Texts).
	TokText TokKind = iota
	// TokReq: at least N newlines before the next text: the edge of a block.
	TokReq
	// TokLit: characters between two boxes of one block (a table's tab, a <br> before an image).
	TokLit
	// TokImg: a paragraph that is only an image (display: block, no text).
	TokImg
	// TokHr is a rule.
	TokHr
	// TokVirt is text that is copied but drawn by something else (a diagram's labels).
	TokVirt
	// TokTableEnd is a table's end: one newline, and Chromium writes it even when the table is last.
	TokTableEnd
)

type Turn

type Turn struct {
	Prompt string
	// Images are the prompt's pasted images (URLs the painter's loader can fetch).
	Images []string
	Queued bool
	Steps  []Step
	// Took is how long it worked ("3m 07s"); TookMs the same in ms.
	Took      string
	TookMs    float64
	HasTookMs bool
	// Credits is what the turn cost ("0.09 credits"), when the tool says.
	Credits string
	Stage   Stage
	// Live: the turn running now (working, or waiting on the user).
	Live bool
	// Clock is how long the live turn has gone ("0:12").
	Clock string
	// When the prompt was sent (.me .when).
	When   string
	Status string
	Answer string
	// Waiting: the live turn waits on the user (a question, a permission).
	Waiting bool
	// Stopping: asked to stop or pause, and the tool hasn't said it has yet.
	Stopping bool
	// Restore and Again: its acts row offers Restore (the chat and the folder back to just
	// after this answer) and Try again (the folder back to before this message, which goes
	// again): a checkpoint was kept there and nothing runs.
	Restore, Again bool
}

Turn is one turn as the office shows it.

func NewTurn

func NewTurn(prompt string) Turn

func Turns

func Turns(session any) []Turn

Turns is TurnsAt with no running clock, times in UTC (a finished session, the tests).

func TurnsAt

func TurnsAt(session any, now float64, hm func(ms float64) string) []Turn

TurnsAt reads a session of the state message as the thread shows it. now is the clock in Unix ms (a running turn shows how long it has gone); hm writes a turn's start time.

func (*Turn) Equal

func (t *Turn) Equal(o *Turn) bool

Equal says whether two turns would be laid out alike.

type Unit

type Unit uint8

Unit is what a click selects: a caret (1), a word (2) or a paragraph (3 and more).

const (
	UnitChar Unit = iota
	UnitWord
	UnitPara
)

Jump to

Keyboard shortcuts

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