Help us shape the future of Go! Take the 2026 Go Developer Survey

editor

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: Sep 26, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package editor implements Cove's editor pane: a virtualized viewport over a buffer.Buffer with multi-cursor editing, undo/redo, and search. It renders only visible lines and never hands the whole file to Bubbletea's render loop — the PRD §5.2 boundary.

Index

Constants

View Source
const (
	ClassNone = iota
	ClassKeyword
	ClassString
	ClassComment
	ClassNumber
	ClassFunction
	ClassType
	ClassConstant
	ClassProperty
	ClassOperator
	ClassDiffAdd // git: added / removed / modified lines (diff views, gutter)
	ClassDiffDel
	ClassDiffMod
	ClassMergeOurs // merge conflict block backgrounds (ours / theirs)
	ClassMergeTheirs
)

Style classes emitted by the highlighter; index into classStyles.

Variables

This section is empty.

Functions

func ApplyTheme

func ApplyTheme(colors map[string]string)

ApplyTheme installs a name->color theme; entries it doesn't set keep their zero style. Called once at startup (and by tests).

func Clip added in v0.16.0

func Clip() string

Clip returns the shared clipboard text ("" if empty).

func LineNumbersEnabled

func LineNumbersEnabled() bool

LineNumbersEnabled reports the current gutter setting.

func SetClip added in v0.16.0

func SetClip(s string)

SetClip replaces the shared clipboard (terminal-selection copy feeds it).

func SetLineNumbers

func SetLineNumbers(on bool)

SetLineNumbers toggles the line-number gutter (config + palette action).

func SetTabStop

func SetTabStop(n int)

SetTabStop configures tab width in cells.

func TabStop added in v0.15.0

func TabStop() int

TabStop reports the configured tab width — for text generators (side-by-side diff) that pre-expand tabs to keep columns straight.

Types

type Cursor

type Cursor struct {
	Anchor, Head int
	// contains filtered or unexported fields
}

Cursor is an anchor+head pair of byte offsets. Anchor == Head means no selection; Head is where the caret blinks.

type DiagSpan

type DiagSpan struct {
	Start, End int
	Severity   int // 1 error, 2 warning, 3+ info
	Message    string
}

DiagSpan is a diagnostic mapped to byte offsets, ready to render.

type Edit

type Edit struct {
	Off      int
	Old, New []byte
}

Edit is a single replacement: Old bytes at Off become New. Offsets are in pre-transaction coordinates; a transaction's edits are ascending and non-overlapping.

type Folder added in v0.14.0

type Folder interface {
	// Folds returns fold regions (startLine, endLine) for the outermost
	// multi-line named nodes starting within [startOff, endOff), sorted.
	Folds(src []byte, startOff, endOff int) [][2]int
}

Folder is the optional fold-range provider a Syntax implementation may offer; plain-text buffers just don't fold.

type HLSpan

type HLSpan struct {
	Start, End int
	Class      int // one of the Class* constants in style.go
}

HLSpan is a highlighted byte range with a style class.

type Model

type Model struct {
	Buf      *buffer.Buffer
	Width    int
	Height   int
	Syntax   Syntax
	Dirty    bool
	ReadOnly bool       // rejects every mutation; navigation/selection still work
	Rev      int        // bumped on every buffer mutation; drives LSP sync
	Diags    []DiagSpan // set by the app; offsets clamped at render time
	Signs    []byte     // git gutter sign per line ('a'/'m'/'d', 0 none); set by the app
	LineBG   []byte     // per-line background class ('a'/'m'/'d', 0 none); set by the app (diff views)
	Ghost    string     // AI completion ghost text; rendered dim after the cursor (see SetGhost)
	GhostOff int        // byte offset the ghost belongs to; a moved cursor hides it
	// contains filtered or unexported fields
}

func New

func New(buf *buffer.Buffer) Model

func (*Model) AcceptGhost added in v0.17.0

func (m *Model) AcceptGhost() bool

AcceptGhost inserts the visible ghost as its own undo step. Reports whether anything was inserted.

func (*Model) AddCursor

func (m *Model) AddCursor(dir int)

func (*Model) ApplyEdits

func (m *Model) ApplyEdits(edits []Edit)

ApplyEdits applies external (LSP) edits as one undoable transaction. Edits must be non-overlapping, ascending, in current-buffer offsets.

func (*Model) Center

func (m *Model) Center()

Center scrolls so the primary cursor's line sits mid-viewport — used after jumps (problems, go-to-definition) so the target has context.

func (*Model) Collapse

func (m *Model) Collapse()

Collapse reduces to a single cursor and clears the search — Esc.

func (*Model) Copy

func (m *Model) Copy()

func (Model) Cursor

func (m Model) Cursor() (int, int)

Cursor returns the primary cursor's (line, col).

func (Model) CursorCount

func (m Model) CursorCount() int

CursorCount returns the number of active cursors.

func (Model) CursorScreen

func (m Model) CursorScreen() (int, int)

CursorScreen returns the primary cursor's position in pane cells (x, y relative to the viewport's top-left, gutter included).

func (*Model) Cut

func (m *Model) Cut()

func (*Model) DeleteLine added in v0.5.0

func (m *Model) DeleteLine()

DeleteLine removes each cursor's whole line.

func (*Model) DeleteRune

func (m *Model) DeleteRune(dir int)

func (*Model) DiagCounts

func (m *Model) DiagCounts() (int, int, int)

DiagCounts returns (errors, warnings, infos+hints).

func (*Model) DiagUnderCursor

func (m *Model) DiagUnderCursor() (DiagSpan, bool)

DiagUnderCursor returns the diagnostic covering the primary cursor.

func (*Model) DuplicateLine added in v0.5.0

func (m *Model) DuplicateLine()

DuplicateLine copies each cursor's line below itself.

func (*Model) ExpandSelection

func (m *Model) ExpandSelection()

func (*Model) FoldAll added in v0.14.0

func (m *Model) FoldAll()

FoldAll folds every outermost region in the file.

func (*Model) FoldedAt added in v0.14.0

func (m *Model) FoldedAt(line int) bool

FoldedAt returns whether line is a fold header (used for the gutter mark).

func (*Model) GhostVisible added in v0.17.0

func (m *Model) GhostVisible() bool

GhostVisible reports whether the ghost currently renders: one cursor, no selection, sitting exactly at the anchor, at end of line. Any edit or cursor move breaks the anchor and hides it.

func (*Model) Go

func (m *Model) Go(line, col int)

Go places a single cursor at (line, col) and scrolls it into view.

func (*Model) IndentLines added in v0.5.0

func (m *Model) IndentLines(dir int)

IndentLines shifts every selected line right (dir>0: insert a tab) or left (dir<0: strip one leading tab or up to 4 leading spaces).

func (Model) Init

func (m Model) Init() tea.Cmd

func (*Model) InsertCloser added in v0.9.1

func (m *Model) InsertCloser(s string)

InsertCloser inserts a closing bracket, first removing one indent level when the cursor sits in pure leading whitespace — typing } on a fresh auto-indented line snaps it back to the opener's level. ponytail: dedents one IndentLines unit (tab, or ≤4 spaces), not to the matching opener's actual column; use tree-sitter if this mis-fires.

func (*Model) InsertNewline added in v0.9.1

func (m *Model) InsertNewline()

InsertNewline inserts \n at every cursor, carrying the current line's leading whitespace onto the new line and adding one indent level when the last non-blank character before the cursor opens a block ({, (, [, :). ponytail: no language awareness and no auto-dedent on }; revisit if tree-sitter indent queries ever land.

func (*Model) InsertText

func (m *Model) InsertText(s string)

InsertText replaces every cursor's selection with s. Line endings are normalized to \n and stray control characters dropped — pastes and fast typing arrive as raw chunks and must not put control bytes in the buffer.

func (*Model) LineEdge

func (m *Model) LineEdge(dir int, extend bool)

LineEdge moves every cursor to the start (dir<0) or end (dir>0) of its line.

func (*Model) MarkSaved added in v0.9.0

func (m *Model) MarkSaved()

MarkSaved records the current state as clean: matching it again — by undoing back or by edits that restore the same content — clears Dirty.

func (*Model) MoveH

func (m *Model) MoveH(dir int, extend bool)

func (*Model) MoveLine added in v0.5.0

func (m *Model) MoveLine(dir int)

MoveLine swaps the primary cursor's line with its neighbor above/below. ponytail: primary cursor only; multi-cursor move-line when someone misses it.

func (*Model) MoveV

func (m *Model) MoveV(delta int, extend bool)

func (*Model) MoveWord

func (m *Model) MoveWord(dir int, extend bool)

func (*Model) NextMatch

func (m *Model) NextMatch(dir int) bool

NextMatch selects the next (dir>0) or previous (dir<0) match relative to the primary cursor, wrapping. Returns false if there are no matches.

func (*Model) Page

func (m *Model) Page(dir int)

func (*Model) Paste

func (m *Model) Paste()

func (*Model) RedoStep

func (m *Model) RedoStep()

RedoStep re-applies the most recently undone transaction.

func (*Model) ReplaceAll

func (m *Model) ReplaceAll(repl string) int

ReplaceAll replaces every match in one undoable transaction. Returns the number of replacements.

func (*Model) ReplaceCurrent

func (m *Model) ReplaceCurrent(repl string)

ReplaceCurrent replaces the primary selection if it is a match, then advances to the next match.

func (*Model) SearchInfo

func (m *Model) SearchInfo() (int, int)

SearchInfo returns (current match 1-based, total). 0 total means no matches.

func (*Model) SelectAll

func (m *Model) SelectAll()

func (*Model) SelectAllOccurrences added in v0.5.0

func (m *Model) SelectAllOccurrences()

SelectAllOccurrences selects every match of the primary selection (or of the word under the cursor).

func (*Model) SelectNext

func (m *Model) SelectNext()

func (Model) Selection

func (m Model) Selection() []byte

Selection returns the primary cursor's selected text, nil if none.

func (Model) SelectionRange added in v0.19.0

func (m Model) SelectionRange() (lo, hi int)

SelectionRange returns the primary cursor's selection as byte offsets (lo == hi when nothing is selected).

func (*Model) SetGhost added in v0.17.0

func (m *Model) SetGhost(text string, off int)

SetGhost installs (or clears, with "") the AI suggestion anchored at byte offset off. Text is sanitized like typed input — control bytes must never reach the buffer on accept.

func (*Model) SetSearch

func (m *Model) SetSearch(pattern string, isRegex bool)

SetSearch sets the live search pattern. Plain search is smart-case: all-lowercase patterns match case-insensitively.

func (*Model) ToggleComment added in v0.5.0

func (m *Model) ToggleComment(prefix string)

ToggleComment strips prefix from every selected line if all non-blank lines carry it, otherwise adds it after the leading whitespace.

func (*Model) ToggleFold added in v0.14.0

func (m *Model) ToggleFold()

ToggleFold folds the region anchored at the primary cursor's line — the outermost node starting there, else the enclosing multi-line node — or unfolds if the line is already a fold header. The cursor moves to the header so it can never sit in a hidden line.

func (*Model) UndoStep

func (m *Model) UndoStep()

UndoStep reverts the most recent transaction.

func (*Model) UnfoldAll added in v0.14.0

func (m *Model) UnfoldAll()

UnfoldAll clears every fold.

func (Model) Update

func (m Model) Update(msg tea.Msg) (Model, tea.Cmd)

func (Model) View

func (m Model) View() string

View renders only the visible window: O(visible area), never O(file). With folds active the window is the visible lines from top, skipping folded bodies; highlight/search windows follow each contiguous run.

type Syntax

type Syntax interface {
	// Edit reports a buffer mutation. Pre-points describe the buffer before
	// the change, newEnd after; the implementation reparses lazily.
	Edit(startOff, oldEndOff, newEndOff int, start, oldEnd, newEnd [2]int)
	// Spans returns highlight spans intersecting [startOff, endOff),
	// sorted by Start.
	Spans(src []byte, startOff, endOff int) []HLSpan
	// Expand grows [lo, hi) to the smallest enclosing syntax node strictly
	// larger than the current range. ok is false at the root.
	Expand(src []byte, lo, hi int) (int, int, bool)
}

Syntax is what the editor needs from a highlighter; wired by the app so this package stays free of the CGo dependency.

type Tx

type Tx struct {
	Edits         []Edit
	Before, After []Cursor
	// contains filtered or unexported fields
}

Tx is one undoable step: a set of simultaneous edits (one per cursor) plus the cursor sets to restore on undo/redo.

Jump to

Keyboard shortcuts

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