document

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: May 30, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package document implements Gap Buffer based text storage and editing.

Design: Gap Buffer is one of the classic in-memory structures for text editors. It splits the buffer into three parts:

[left half] [gap] [right half]

The cursor position corresponds to the gap start. Inserting at the cursor writes characters into the gap and advances the gap pointer without moving large amounts of data. Deleting simply expands the gap.

Complexity: - Insert/Delete: amortized O(1) - Line-based access: requires scanning, O(n), but can be optimized with line start caching

Package document provides the data structures for editor documents, including encoding detection and conversion support.

Package document's undo.go implements the undo/redo system.

Design: Uses the Command Pattern — each edit operation is recorded as an UndoStep. The stack capacity is configurable (default 100 steps); oldest records are dropped when exceeded. Merge strategy: consecutive insert operations are merged into one step to reduce redundancy.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EncodeFromUTF8

func EncodeFromUTF8(text string, enc CommonEncoding) ([]byte, error)

EncodeFromUTF8 encodes a UTF-8 string back to the given encoding.

func GBKToUTF8

func GBKToUTF8(data []byte) (string, error)

GBKToUTF8 converts a GBK-encoded byte slice to a UTF-8 string.

func StripBOM

func StripBOM(data []byte) []byte

StripBOM removes BOM bytes from data if present.

func UTF8ToGBK

func UTF8ToGBK(text string) ([]byte, error)

UTF8ToGBK converts a UTF-8 string to a GBK-encoded byte slice.

Types

type CommonEncoding

type CommonEncoding int

CommonEncoding represents a human-readable encoding name.

const (
	EncUnknown CommonEncoding = iota
	EncUTF8
	EncUTF16LE
	EncUTF16BE
	EncGBK
	EncBig5
	EncShiftJIS
	EncEUCJP
	EncEUCKR
	EncLatin1
)

func DecodeToUTF8

func DecodeToUTF8(data []byte) (string, CommonEncoding, error)

DecodeToUTF8 decodes raw bytes to a UTF-8 string. Returns the decoded string, detected encoding, and any error.

func DetectEncoding

func DetectEncoding(data []byte) CommonEncoding

DetectEncoding detects the character encoding of raw byte data.

func (CommonEncoding) BOM

func (e CommonEncoding) BOM() []byte

BOM returns an ASCII/UTF-8 BOM sequence for UTF-16 encodings (empty for others).

func (CommonEncoding) String

func (e CommonEncoding) String() string

type Document

type Document struct {
	Buffer   *GapBuffer     // underlying gap buffer
	FilePath string         // file path
	Modified bool           // modified flag
	Encoding CommonEncoding // detected file encoding
}

Document is the high-level document structure wrapping GapBuffer.

func NewDocument

func NewDocument() *Document

NewDocument creates a new empty document.

func NewDocumentFromString

func NewDocumentFromString(s string) *Document

NewDocumentFromString creates a document from a string.

func (*Document) Content

func (d *Document) Content() string

Content returns the complete text content.

func (*Document) DeleteRange

func (d *Document) DeleteRange(pos, length int) []rune

DeleteRange deletes 'length' characters starting at pos, returning the deleted text.

func (*Document) DeleteRuneAt

func (d *Document) DeleteRuneAt(pos int) rune

DeleteRuneAt deletes the character at position pos, returning the deleted rune.

func (*Document) GetIndent

func (d *Document) GetIndent(line int) string

GetIndent returns the indentation string for the given line.

func (*Document) InsertRune

func (d *Document) InsertRune(pos int, ch rune)

InsertRune inserts a single rune at position pos.

func (*Document) InsertText

func (d *Document) InsertText(pos int, text string)

InsertText inserts a string at position pos.

func (*Document) Len

func (d *Document) Len() int

Len returns the total number of characters.

func (*Document) Line

func (d *Document) Line(n int) string

Line returns the content of the specified line.

func (*Document) LineColToPos

func (d *Document) LineColToPos(line, col int) int

LineColToPos converts (line, column) to a global position.

func (*Document) LineCount

func (d *Document) LineCount() int

LineCount returns the total number of lines.

func (*Document) LineLen

func (d *Document) LineLen(line int) int

LineLen returns the number of characters on the given line.

func (*Document) PosToLineCol

func (d *Document) PosToLineCol(pos int) (int, int)

PosToLineCol converts a global position to (line, column).

type GapBuffer

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

GapBuffer is the gap buffer data structure.

func NewGapBuffer

func NewGapBuffer(capacity int) *GapBuffer

NewGapBuffer creates a gap buffer with the specified initial capacity.

func NewGapBufferFromRunes

func NewGapBufferFromRunes(runes []rune) *GapBuffer

NewGapBufferFromRunes creates a GapBuffer from a rune slice.

func (*GapBuffer) BytePos

func (gb *GapBuffer) BytePos(runePos int) int

BytePos converts a rune position to a byte position.

func (*GapBuffer) Cap

func (gb *GapBuffer) Cap() int

Cap returns the total buffer capacity.

func (*GapBuffer) Content

func (gb *GapBuffer) Content() string

Content returns the complete text content as a string.

func (*GapBuffer) Delete

func (gb *GapBuffer) Delete(pos, length int)

Delete deletes 'length' characters starting at position pos.

func (*GapBuffer) Indentation

func (gb *GapBuffer) Indentation(line int) string

Indentation returns the whitespace indentation string for the given line.

func (*GapBuffer) Insert

func (gb *GapBuffer) Insert(pos int, text []rune)

Insert inserts a rune slice at position pos.

func (*GapBuffer) Len

func (gb *GapBuffer) Len() int

Len returns the number of valid characters (excluding the gap).

func (*GapBuffer) Line

func (gb *GapBuffer) Line(line int) string

Line returns the content of the specified line as a string.

func (*GapBuffer) LineColToPos

func (gb *GapBuffer) LineColToPos(line, col int) int

LineColToPos converts (line, column) to a global position. Clamps out-of-range values.

func (*GapBuffer) LineCount

func (gb *GapBuffer) LineCount() int

LineCount returns the total number of lines. An empty buffer counts as 1 line. Content ending with a newline counts the trailing newline as starting an additional empty line.

func (*GapBuffer) LineEnd

func (gb *GapBuffer) LineEnd(line int) int

LineEnd returns the position of the first character after the given line, excluding the newline character. Returns the buffer length if the line has no trailing newline.

func (*GapBuffer) LineLen

func (gb *GapBuffer) LineLen(line int) int

LineLen returns the number of characters on the given line.

func (*GapBuffer) LineStart

func (gb *GapBuffer) LineStart(line int) int

LineStart returns the position of the first character on the given line. Returns -1 if the line is out of range.

func (*GapBuffer) PosToLineCol

func (gb *GapBuffer) PosToLineCol(pos int) (int, int)

PosToLineCol converts a global position to (line, column).

func (*GapBuffer) RuneAt

func (gb *GapBuffer) RuneAt(pos int) rune

RuneAt returns the rune at position pos.

func (*GapBuffer) Slice

func (gb *GapBuffer) Slice(start, end int) []rune

Slice returns a slice of runes from start to end (exclusive). Clamps out-of-range indices.

func (*GapBuffer) String

func (gb *GapBuffer) String() string

String returns the content as a string.

type Position

type Position struct {
	Line int // Line number (0-indexed)
	Col  int // Column number (0-indexed)
}

Position represents a position in the document.

type UndoKind

type UndoKind int

UndoKind represents the operation type.

const (
	UndoInsert  UndoKind = iota // Insert operation
	UndoDelete                  // Delete operation
	UndoReplace                 // Replace operation
)

type UndoStack

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

UndoStack manages the undo/redo stacks.

func NewUndoStack

func NewUndoStack(limit int) *UndoStack

NewUndoStack creates an undo stack with the given step limit.

func (*UndoStack) CanRedo

func (us *UndoStack) CanRedo() bool

CanRedo checks whether redo is available.

func (*UndoStack) CanUndo

func (us *UndoStack) CanUndo() bool

CanUndo checks whether undo is available.

func (*UndoStack) Clear

func (us *UndoStack) Clear()

Clear clears all steps.

func (*UndoStack) Push

func (us *UndoStack) Push(kind UndoKind, pos int, text, deleted []rune)

Push records an operation. Consecutive same-type inserts are merged to reduce steps.

func (*UndoStack) Redo

func (us *UndoStack) Redo() (UndoStep, bool)

Redo pops and returns the top of the redo stack.

func (*UndoStack) RedoCount

func (us *UndoStack) RedoCount() int

RedoCount returns the number of steps in the redo stack.

func (*UndoStack) Undo

func (us *UndoStack) Undo() (UndoStep, bool)

Undo pops and returns the last operation step for undoing.

func (*UndoStack) UndoCount

func (us *UndoStack) UndoCount() int

UndoCount returns the number of steps in the undo stack.

type UndoStep

type UndoStep struct {
	Kind    UndoKind // Operation type
	Pos     int      // Global position where the operation occurred
	Text    []rune   // Inserted text (Insert) or replaced text (Replace)
	Deleted []rune   // Deleted text (Delete) or pre-replacement text (Replace)
}

UndoStep records a single undoable operation step.

Jump to

Keyboard shortcuts

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