vim

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package vim is a Vim editing engine over a plain text buffer: modes, counts, registers, motions, operators, text objects, visual selections, undo, dot-repeat, macros, marks, search and substitute, an ex command line, and heading folds. It knows nothing about terminals; the terminal UI feeds it keys and draws what it exposes.

Index

Constants

This section is empty.

Variables

View Source
var (
	KeyEsc       = Special("esc")
	KeyEnter     = Special("enter")
	KeyTab       = Special("tab")
	KeyShiftTab  = Key{Name: "tab", Shift: true}
	KeyBackspace = Special("backspace")
	KeyDelete    = Special("delete")
	KeyUp        = Special("up")
	KeyDown      = Special("down")
	KeyLeft      = Special("left")
	KeyRight     = Special("right")
	KeyHome      = Special("home")
	KeyEnd       = Special("end")
	KeyPgUp      = Special("pgup")
	KeyPgDn      = Special("pgdn")
)

Functions

func KeysString

func KeysString(keys []Key) string

KeysString renders a key sequence in notation.

Types

type Buffer

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

Buffer is the text: a slice of lines without their newlines. Line slices are treated as immutable, so an undo snapshot is just a copy of the outer slice.

func NewBuffer

func NewBuffer(text string) *Buffer

NewBuffer splits text into lines; CRLF is normalized to LF.

func (*Buffer) DeleteLines

func (b *Buffer) DeleteLines(from, to int) []string

DeleteLines removes lines from..to inclusive and returns them. The buffer always keeps one line.

func (*Buffer) DeleteRange

func (b *Buffer) DeleteRange(start, end Pos) string

DeleteRange removes the text between start (inclusive) and end (exclusive) and returns it.

func (*Buffer) InsertLines

func (b *Buffer) InsertLines(at int, lines []string)

InsertLines inserts lines before index at (at may equal LineCount).

func (*Buffer) InsertText

func (b *Buffer) InsertText(p Pos, text string) Pos

InsertText inserts text (which may contain newlines) at p and returns the position just after it.

func (*Buffer) Line

func (b *Buffer) Line(i int) []rune

Line is a line's runes. Callers must not mutate the slice.

func (*Buffer) LineCount

func (b *Buffer) LineCount() int

LineCount is the number of lines, at least one.

func (*Buffer) LineLen

func (b *Buffer) LineLen(i int) int

LineLen is a line's rune count.

func (*Buffer) LineString

func (b *Buffer) LineString(i int) string

LineString is a line as a string.

func (*Buffer) Lines

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

Lines copies every line as a string.

func (*Buffer) Range

func (b *Buffer) Range(start, end Pos) string

Range is the text between start (inclusive) and end (exclusive).

func (*Buffer) ReplaceLine

func (b *Buffer) ReplaceLine(i int, text []rune)

ReplaceLine swaps a line's content.

func (*Buffer) ReplaceLines

func (b *Buffer) ReplaceLines(from, to int, lines []string)

ReplaceLines swaps lines from..to (inclusive) for new ones. Replacing every line replaces the buffer's mandatory single line too, so no empty line lingers.

func (*Buffer) Restore

func (b *Buffer) Restore(lines [][]rune)

Restore puts a snapshot back.

func (*Buffer) SetText

func (b *Buffer) SetText(text string)

SetText replaces the whole buffer.

func (*Buffer) Snapshot

func (b *Buffer) Snapshot() [][]rune

Snapshot copies the outer slice, enough for undo since lines are never mutated in place.

func (*Buffer) Text

func (b *Buffer) Text() string

Text joins the lines with LF.

type Editor

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

Editor is one buffer with its full Vim state.

func New

func New(text string, opts Options, hooks Hooks) *Editor

New creates an editor over text.

func (*Editor) BlockColumns

func (e *Editor) BlockColumns() (left, right int, toEnd bool)

BlockColumns is the column span of a block selection, plus whether `$` extends every line to its end.

func (*Editor) ClearMessage

func (e *Editor) ClearMessage()

ClearMessage drops the status message.

func (*Editor) Cmdline

func (e *Editor) Cmdline() (kind rune, text string, cursor int, active bool)

Cmdline is the command line's current state for rendering.

func (*Editor) Completions

func (e *Editor) Completions() ([]string, int)

Completions lists the current completion candidates (for a wildmenu).

func (*Editor) Cursor

func (e *Editor) Cursor() Pos

func (*Editor) Dirty

func (e *Editor) Dirty() bool

Dirty is true when the buffer changed since the last MarkSaved.

func (*Editor) EnsureCursorVisible

func (e *Editor) EnsureCursorVisible()

EnsureCursorVisible scrolls so the cursor is on screen, honoring scrolloff.

func (*Editor) ExecuteEx

func (e *Editor) ExecuteEx(line string)

ExecuteEx runs an ex command line from the host (`:` prefix optional).

func (*Editor) Feed

func (e *Editor) Feed(notation string)

Feed runs keys given in Vim notation.

func (*Editor) Folds

func (e *Editor) Folds() map[int]int

Folds lists closed folds as start..end pairs.

func (*Editor) GotoLine

func (e *Editor) GotoLine(line int)

GotoLine moves to a 1-based line as a jump.

func (*Editor) HandleKey

func (e *Editor) HandleKey(k Key) bool

HandleKey processes one keystroke. It reports false only in plain (non Vim) mode for keys the editor has no use for, so the host may act.

func (*Editor) Hidden

func (e *Editor) Hidden(line int) bool

Hidden reports whether a line is inside a closed fold (not its first line).

func (*Editor) HighlightOn

func (e *Editor) HighlightOn() bool

HighlightOn reports whether search matches are shown.

func (*Editor) IncrementalHighlights

func (e *Editor) IncrementalHighlights(line int) [][2]int

IncrementalHighlights lists spans of the pattern being typed on a line.

func (*Editor) InsertAtCursor

func (e *Editor) InsertAtCursor(text string)

InsertAtCursor inserts text as one undoable change and leaves the cursor after it.

func (*Editor) IsFoldStart

func (e *Editor) IsFoldStart(line int) (int, bool)

IsFoldStart reports whether line starts a closed fold, and where it ends.

func (*Editor) LastSearch

func (e *Editor) LastSearch() string

LastSearch is the last pattern.

func (*Editor) Line

func (e *Editor) Line(i int) string

func (*Editor) LineCount

func (e *Editor) LineCount() int

func (*Editor) LineRunes

func (e *Editor) LineRunes(i int) []rune

func (*Editor) Lines

func (e *Editor) Lines() []string

func (*Editor) MarkSaved

func (e *Editor) MarkSaved()

MarkSaved records the current version as the on-disk one.

func (*Editor) Marks

func (e *Editor) Marks() map[rune]Pos

Marks copies the mark table.

func (*Editor) Message

func (e *Editor) Message() (string, bool)

Message is the last status message and whether it is an error.

func (*Editor) Mode

func (e *Editor) Mode() Mode

func (*Editor) OpenCmdline

func (e *Editor) OpenCmdline(kind rune, initial string)

OpenCmdline starts an ex or search line from the host.

func (*Editor) Options

func (e *Editor) Options() Options

func (*Editor) Pending

func (e *Editor) Pending() string

Pending is the keys of an unfinished command, for a showcmd area.

func (*Editor) PendingCount

func (e *Editor) PendingCount() (int, bool)

PendingCount is the count typed so far when the pending keys are only digits: the host reads it before taking over a sequence like `3gt`.

func (*Editor) Recording

func (e *Editor) Recording() rune

Recording is the register a macro is being recorded into, or 0.

func (*Editor) Redo

func (e *Editor) Redo()

Redo re-applies an undone change.

func (*Editor) ReflowParagraph

func (e *Editor) ReflowParagraph()

ReflowParagraph joins the paragraph under the cursor (Alt+Q).

func (*Editor) RegisterText

func (e *Editor) RegisterText(r rune) (Register, bool)

RegisterText reads a register.

func (*Editor) ReplaceAtCursor added in v0.3.0

func (e *Editor) ReplaceAtCursor(before, after int, text string)

ReplaceAtCursor swaps the before runes left of the cursor and the after runes right of it for text and leaves the cursor behind the text: what accepting a completion does. In insert mode it joins the insert in progress, so one undo takes the typing and the completion together.

func (*Editor) ReplaceLineText

func (e *Editor) ReplaceLineText(line int, text string)

ReplaceLineText swaps one line as a change.

func (*Editor) ReplaceLines

func (e *Editor) ReplaceLines(from, to int, lines []string)

ReplaceLines swaps a block of lines as a change.

func (*Editor) ReplaceText

func (e *Editor) ReplaceText(text string)

ReplaceText swaps the text in as a change (undoable) keeping the cursor where it was where possible, for a note reloaded from disk.

func (*Editor) ResetPending

func (e *Editor) ResetPending()

ResetPending drops an unfinished normal-mode command, for a host that takes a key sequence over from the engine.

func (*Editor) Rows

func (e *Editor) Rows() int

func (*Editor) ScrollTop

func (e *Editor) ScrollTop() int

func (*Editor) SearchHighlights

func (e *Editor) SearchHighlights(line int) [][2]int

SearchHighlights lists highlighted spans on a line while search highlighting is on.

func (*Editor) SetCursor

func (e *Editor) SetCursor(p Pos)

SetCursor moves the cursor, clamped for the current mode.

func (*Editor) SetHooks

func (e *Editor) SetHooks(h Hooks)

SetHooks replaces the host hooks.

func (*Editor) SetOptions

func (e *Editor) SetOptions(opts Options)

SetOptions replaces the options live.

func (*Editor) SetScrollTop

func (e *Editor) SetScrollTop(line int)

SetScrollTop moves the viewport.

func (*Editor) SetText

func (e *Editor) SetText(text string)

SetText replaces the text and resets history.

func (*Editor) SetViewport

func (e *Editor) SetViewport(rows int)

SetViewport tells the editor how many screen rows it has.

func (*Editor) StatusSuffix

func (e *Editor) StatusSuffix() string

StatusSuffix is the text a status line shows after the mode: pending keys and the macro being recorded.

func (*Editor) Text

func (e *Editor) Text() string

func (*Editor) ToggleCheckboxAtCursor

func (e *Editor) ToggleCheckboxAtCursor()

ToggleCheckboxAtCursor turns the current line into a checkbox and toggles it on repeat: plain text becomes `- [ ] text`, a bullet keeps its marker, `[ ]` flips to `[x]` and back, `[/]` checks off, `[>]` and `[-]` stay.

func (*Editor) Undo

func (e *Editor) Undo()

Undo reverts the last change.

func (*Editor) Version

func (e *Editor) Version() int

func (*Editor) VisualRange

func (e *Editor) VisualRange() (start, end Pos, mode Mode, ok bool)

VisualRange is the normalized selection: start..end inclusive, the mode, and ok when a selection is active. For block mode the columns come from BlockColumns.

func (*Editor) WordUnderCursor

func (e *Editor) WordUnderCursor() string

WordUnderCursor is the keyword at or after the cursor on its line.

type ExCommand

type ExCommand struct {
	Name  string
	Args  string
	Bang  bool
	Range Range
	Raw   string
}

ExCommand is a command the editor hands to its host.

type Hooks

type Hooks struct {
	// ExCommand runs a command the editor does not own; handled false means
	// unknown command.
	ExCommand func(cmd ExCommand) (handled bool, err error)
	// ExComplete proposes completions for the ex line. It receives the text
	// before the cursor and returns the part to keep plus the candidates
	// that replace the rest, so a host can complete note titles with spaces
	// as one argument. Nil candidates fall back to the built-in command
	// names.
	ExComplete     func(text string) (keep string, candidates []string)
	ReadClipboard  func() (string, bool)
	WriteClipboard func(text string) bool
	// OnJump is told before a jump motion moves the cursor.
	OnJump func(from Pos)
	// FollowLink is `gd`, CopyLink is `gy`, OpenURL is `gx`.
	FollowLink func()
	CopyLink   func()
	OpenURL    func()
	// LineRows is how many screen rows a line takes when soft-wrapped.
	LineRows func(line int) int
	// Changed is called after every committed change.
	Changed func()
}

Hooks are the host's side of the engine. Every field is optional.

type Key

type Key struct {
	Rune  rune
	Name  string
	Ctrl  bool
	Alt   bool
	Shift bool
}

Key is one keystroke, normalized. Printable keys carry a Rune; special keys carry a Name (esc, enter, tab, backspace, delete, up, down, left, right, home, end, pgup, pgdn, insert).

func Alt

func Alt(r rune) Key

Alt is an alt chord.

func Ctrl

func Ctrl(r rune) Key

Ctrl is a control chord like Ctrl+d.

func ParseKeys

func ParseKeys(s string) []Key

ParseKeys turns Vim notation into keys: `dw<Esc>ihello<CR>`, `<C-d>`. An unterminated `<` is a literal less-than.

func R

func R(r rune) Key

R is a plain rune key.

func Special

func Special(name string) Key

Special is a named key.

func (Key) Is

func (k Key) Is(name string) bool

Is is true for a special key by name (shift-insensitive unless the name is "shift+tab").

func (Key) IsCtrl

func (k Key) IsCtrl(r rune) bool

IsCtrl is true for the control chord Ctrl+r.

func (Key) IsRune

func (k Key) IsRune(r rune) bool

IsRune is true for the plain printable rune r.

func (Key) Printable

func (k Key) Printable() bool

Printable is true for a plain rune the user could type into text.

func (Key) String

func (k Key) String() string

String renders the key in Vim's notation: `a`, `<Esc>`, `<C-d>`, `<CR>`.

type Mode

type Mode int

Mode is the editor's state.

const (
	ModeNormal Mode = iota
	ModeInsert
	ModeReplace
	ModeVisual
	ModeVisualLine
	ModeVisualBlock
	ModeCmdline
)

func (Mode) Label

func (m Mode) Label() string

Label is the mode name for a status bar.

type Options

type Options struct {
	TabSize                 int
	ScrollOff               int
	IgnoreCase              bool
	SmartCase               bool
	WrapScan                bool
	InsertEscape            string
	AutoPairs               bool
	AutoPairQuotes          bool
	TextReplacements        map[string]string
	TextReplacementsEnabled bool
	MarkdownLists           bool
	YankToClipboard         bool
	// VimEnabled false runs the buffer as a plain editor: always inserting,
	// arrows and the usual editing keys only.
	VimEnabled bool
}

Options tune the engine. Zero values are filled by New.

func DefaultOptions

func DefaultOptions() Options

DefaultOptions are the shipped defaults.

type Pos

type Pos struct {
	Line, Col int
}

Pos is a position in the buffer: a zero-based line and a rune column.

func (Pos) Less

func (p Pos) Less(q Pos) bool

Less orders positions.

type Range

type Range struct {
	Start, End int
	Given      bool
}

Range is a line range for an ex command, zero-based and inclusive.

type Register

type Register struct {
	Text      string
	Linewise  bool
	Blockwise bool
}

Register is a yank or delete.

Jump to

Keyboard shortcuts

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