selection

package
v0.70.0 Latest Latest
Warning

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

Go to latest
Published: May 15, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package selection provides character-level text selection for terminal UIs.

It handles converting mouse coordinates (in terminal cells) to character positions within rendered ANSI-styled text, supporting multi-byte characters, wide characters (CJK, emoji), and word/line selection via double/triple click.

The approach is modeled after Charm's crush: all coordinate calculations use display columns (terminal cells), not byte offsets or rune counts. The ultraviolet ScreenBuffer provides the bridge between rendered ANSI strings and individual character cells.

Index

Constants

View Source
const ClickTolerance = 2

ClickTolerance is the pixel/cell tolerance for multi-click detection.

View Source
const DoubleClickThreshold = 400 * time.Millisecond

DoubleClickThreshold is the maximum time between clicks for multi-click.

Variables

This section is empty.

Functions

func ExtractText

func ExtractText(line string, startCol, endCol int) string

ExtractText extracts plain text from a rendered ANSI string within the given column range on a single line. Uses ultraviolet to parse ANSI and extract character content.

func FindWordBoundaries

func FindWordBoundaries(line string, col int) (startCol, endCol int)

FindWordBoundaries finds the start and end column of the word at the given column position in a plain-text line (ANSI codes already stripped). Returns (startCol, endCol) where endCol is exclusive. Uses UAX#29 word segmentation and display-width-aware column tracking.

func HighlightLine

func HighlightLine(line string, startCol, endCol int) string

HighlightLine applies reverse-video highlighting to a portion of a rendered line (which may contain ANSI escape codes). startCol/endCol are in display columns. If startCol == -1, the entire line is highlighted. If startCol == endCol, returns the line unchanged.

Uses ultraviolet ScreenBuffer for cell-level ANSI manipulation.

func IsLineInRange

func IsLineInRange(r Range, itemIdx, lineIdx int) (bool, int, int)

IsLineInRange checks if a specific line within an item falls inside the selection range. Returns (inRange, startCol, endCol) where startCol == -1 means the entire line is selected. startCol == endCol means no selection on this line.

Types

type Range

type Range struct {
	StartItemIdx int
	StartLine    int
	StartCol     int
	EndItemIdx   int
	EndLine      int
	EndCol       int
}

Range represents a normalized (start <= end) selection range.

func (Range) IsEmpty

func (r Range) IsEmpty() bool

IsEmpty returns true if the range selects nothing.

type State

type State struct {
	// Whether a mouse button is currently held down.
	MouseDown bool

	// Position where mouse was first pressed (viewport-relative).
	MouseDownItemIdx int
	MouseDownLineIdx int
	MouseDownCol     int

	// Current drag position (viewport-relative).
	DragItemIdx int
	DragLineIdx int
	DragCol     int

	// Multi-click detection.
	LastClickTime time.Time
	LastClickX    int
	LastClickY    int
	ClickCount    int
}

State tracks the full state of a mouse text selection.

func NewState

func NewState() State

NewState creates a new empty selection state.

func (*State) Clear

func (s *State) Clear()

Clear resets all selection state.

func (*State) GetRange

func (s *State) GetRange() Range

GetRange returns the normalized selection range (start <= end).

func (*State) HasSelection

func (s *State) HasSelection() bool

HasSelection returns true if there is a non-empty active selection.

Jump to

Keyboard shortcuts

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