buffer

package
v0.1.5 Latest Latest
Warning

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

Go to latest
Published: Mar 6, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package buffer implements the pure, grapheme-accurate document model for Flourish.

Coordinates are 0-based (Row, GraphemeCol) in grapheme clusters. Ranges are half-open selections in document coordinates: [Start, End).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ComparePos

func ComparePos(a, b Pos) int

func GraphemeColFromRuneOffsetInLine

func GraphemeColFromRuneOffsetInLine(line string, runeOff int, clamp OffsetClampMode) (int, bool)

func RuneOffsetFromGraphemeColInLine

func RuneOffsetFromGraphemeColInLine(line string, graphemeCol int, clamp OffsetClampMode) (int, bool)

Types

type AppliedEdit

type AppliedEdit struct {
	RangeBefore Range
	RangeAfter  Range
	InsertText  string
	DeletedText string
}

AppliedEdit describes one effective edit in a change transaction.

type ApplyRemoteOptions

type ApplyRemoteOptions struct {
	BaseVersion         uint64
	ClampPolicy         ConvertPolicy
	VersionMismatchMode VersionMismatchMode
}

type ApplyRemoteResult

type ApplyRemoteResult struct {
	Change Change
	Remap  RemapReport
}

type Buffer

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

Buffer is the pure document state: text, cursor, and selection.

func New

func New(text string, opt Options) *Buffer

func (*Buffer) Apply

func (b *Buffer) Apply(edits ...TextEdit)

Apply applies a sequence of text edits in order. Each edit's range is interpreted against the buffer state at the time that edit is applied.

v0 semantics: - Edit ranges are clamped into current document bounds. - Empty range + non-empty text inserts. - Cursor moves to the end of the last applied (effective) edit. - Selection is cleared if any edit applies.

func (*Buffer) ApplyRemote

func (b *Buffer) ApplyRemote(edits []RemoteEdit, opts ApplyRemoteOptions) (ApplyRemoteResult, bool)

ApplyRemote applies remote edits in order and returns a change payload with deterministic cursor/selection remap details.

func (*Buffer) ByteOffsetFromPos

func (b *Buffer) ByteOffsetFromPos(pos Pos, p ConvertPolicy) (int, bool)

func (*Buffer) CanRedo

func (b *Buffer) CanRedo() bool

func (*Buffer) CanUndo

func (b *Buffer) CanUndo() bool

func (*Buffer) ClearSelection

func (b *Buffer) ClearSelection()

func (*Buffer) Cursor

func (b *Buffer) Cursor() Pos

func (*Buffer) DeleteBackward

func (b *Buffer) DeleteBackward()

DeleteBackward applies backspace semantics.

func (*Buffer) DeleteForward

func (b *Buffer) DeleteForward()

DeleteForward applies delete-key semantics.

func (*Buffer) DeleteSelection

func (b *Buffer) DeleteSelection()

DeleteSelection deletes the active selection, if any.

func (*Buffer) GapFromPos

func (b *Buffer) GapFromPos(pos Pos, bias GapBias) (Gap, bool)

func (*Buffer) InsertGrapheme

func (b *Buffer) InsertGrapheme(g string)

InsertGrapheme inserts a single grapheme cluster at the cursor, or replaces the active selection.

func (*Buffer) InsertNewline

func (b *Buffer) InsertNewline()

InsertNewline inserts a line break at the cursor, or replaces the active selection.

func (*Buffer) InsertText

func (b *Buffer) InsertText(s string)

InsertText inserts text at the cursor, or replaces the active selection.

func (*Buffer) LastChange

func (b *Buffer) LastChange() (Change, bool)

LastChange returns the most recent effective change.

func (*Buffer) LineCount added in v0.1.2

func (b *Buffer) LineCount() int

LineCount returns the number of lines in the buffer.

func (*Buffer) Move

func (b *Buffer) Move(m Move)

func (*Buffer) PosFromByteOffset

func (b *Buffer) PosFromByteOffset(off int, p ConvertPolicy) (Pos, bool)

func (*Buffer) PosFromGap

func (b *Buffer) PosFromGap(g Gap, p ConvertPolicy) (Pos, bool)

func (*Buffer) PosFromRuneOffset

func (b *Buffer) PosFromRuneOffset(off int, p ConvertPolicy) (Pos, bool)

func (*Buffer) PosFromUTF16Offset

func (b *Buffer) PosFromUTF16Offset(off int, p ConvertPolicy) (Pos, bool)

func (*Buffer) RawLines added in v0.1.3

func (b *Buffer) RawLines() []string

RawLines returns the document as a slice of strings (one per line), joining grapheme clusters directly without the serialize-then-split round-trip of Text() + strings.Split().

func (*Buffer) Redo

func (b *Buffer) Redo() bool

func (*Buffer) RuneOffsetFromPos

func (b *Buffer) RuneOffsetFromPos(pos Pos, p ConvertPolicy) (int, bool)

func (*Buffer) Selection

func (b *Buffer) Selection() (Range, bool)

func (*Buffer) SelectionRaw

func (b *Buffer) SelectionRaw() (Range, bool)

SelectionRaw returns the raw selection anchor/end without normalization.

This is useful for UI layers that need to preserve the selection direction (e.g. shift+click behavior) while still treating empty selections as inactive.

func (*Buffer) SetCursor

func (b *Buffer) SetCursor(p Pos)

func (*Buffer) SetSelection

func (b *Buffer) SetSelection(r Range)

func (*Buffer) Text

func (b *Buffer) Text() string

func (*Buffer) TextInRange added in v0.1.2

func (b *Buffer) TextInRange(r Range) string

TextInRange returns the text contained in the given range, reading directly from the internal grapheme-split line storage. This avoids the full document serialization that Text() + strings.Split would require.

func (*Buffer) TextVersion added in v0.1.1

func (b *Buffer) TextVersion() uint64

TextVersion increments only on effective text mutations.

Cursor/selection-only changes do not change TextVersion.

func (*Buffer) UTF16OffsetFromPos

func (b *Buffer) UTF16OffsetFromPos(pos Pos, p ConvertPolicy) (int, bool)

func (*Buffer) Undo

func (b *Buffer) Undo() bool

func (*Buffer) Version

func (b *Buffer) Version() uint64

type Change

type Change struct {
	Source          ChangeSource
	VersionBefore   uint64
	VersionAfter    uint64
	CursorBefore    Pos
	CursorAfter     Pos
	SelectionBefore SelectionState
	SelectionAfter  SelectionState
	AppliedEdits    []AppliedEdit
}

Change is a normalized, versioned mutation payload.

type ChangeSource

type ChangeSource uint8

ChangeSource identifies where a change originated.

const (
	ChangeSourceLocal ChangeSource = iota
	ChangeSourceRemote
)

type ConvertPolicy

type ConvertPolicy struct {
	ClampMode OffsetClampMode
}

type Gap

type Gap struct {
	RuneOffset int
	Bias       GapBias
}

type GapBias

type GapBias uint8
const (
	GapBiasLeft GapBias = iota
	GapBiasRight
)

type Move

type Move struct {
	Unit MoveUnit
	Dir  MoveDir
	// Count repeats the movement this many times. Values <= 0 are treated as 1.
	Count  int
	Extend bool // if true, updates selection anchor/end; if false clears selection
}

type MoveDir

type MoveDir int
const (
	DirLeft MoveDir = iota
	DirRight
	DirUp
	DirDown
	DirHome // line start (or doc start for MoveDoc)
	DirEnd  // line end (or doc end for MoveDoc)
)

type MoveUnit

type MoveUnit int
const (
	MoveGrapheme MoveUnit = iota
	MoveWord
	MoveParagraph
	MoveLine
	MoveDoc
)

type OffsetClampMode

type OffsetClampMode uint8
const (
	OffsetError OffsetClampMode = iota
	OffsetClamp
)

type Options

type Options struct {
	HistoryLimit int // default: 1000 (wired in later phases)
}

type Pos

type Pos struct {
	Row         int
	GraphemeCol int
}

Pos points into the logical document by (row, grapheme col). Row and GraphemeCol are 0-based.

func ClampPos

func ClampPos(p Pos, rowCount int, lineLen func(row int) int) Pos

ClampPos clamps p into document bounds described by rowCount and lineLen.

- rowCount is the number of logical lines (rows). - lineLen(row) returns the grapheme length of the given row.

The returned Pos always satisfies: - 0 <= Row < rowCount (with rowCount treated as at least 1) - 0 <= GraphemeCol <= lineLen(Row)

type Range

type Range struct {
	Start Pos
	End   Pos
}

Range is a half-open selection in document coordinates: [Start, End). Start <= End in document order.

func ClampRange

func ClampRange(r Range, rowCount int, lineLen func(row int) int) Range

func NormalizeRange

func NormalizeRange(r Range) Range

func (Range) IsEmpty

func (r Range) IsEmpty() bool

type RemapPoint

type RemapPoint struct {
	Before Pos
	After  Pos
	Status RemapStatus
}

type RemapReport

type RemapReport struct {
	Cursor   RemapPoint
	SelStart RemapPoint
	SelEnd   RemapPoint
}

type RemapStatus

type RemapStatus uint8
const (
	RemapUnchanged RemapStatus = iota
	RemapMoved
	RemapClamped
	RemapInvalidated
)

type RemoteEdit

type RemoteEdit struct {
	Range Range
	Text  string
	OpID  string
}

RemoteEdit replaces the text in Range with Text as part of a remote batch.

OpID is an optional host-level operation identifier and is not interpreted by the buffer package.

type SelectionState

type SelectionState struct {
	Active bool
	Range  Range
}

SelectionState captures normalized selection state at a point in time.

type TextEdit

type TextEdit struct {
	Range Range
	Text  string
}

TextEdit replaces the text in Range with Text (which may contain '\n').

type VersionMismatchMode

type VersionMismatchMode uint8
const (
	VersionMismatchReject VersionMismatchMode = iota
	VersionMismatchForceApply
)

Jump to

Keyboard shortcuts

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