Documentation
¶
Overview ¶
Package vim is the modal input model, as a pure state machine.
It knows nothing about editors, terminals or SQL: keys go in, commands come out. Keeping it that way is what makes the interesting part — which half-typed sequences mean what — testable without a screen.
The scope is deliberately the practical subset: normal, insert and visual modes with the common motions, operators and edits. Counts (3dd), marks, named registers and dot-repeat are out.
Search is here only as far as the key that starts it. The pattern is typed into the interface, which owns both the field it goes in and the text it is looked for in; carrying it through Feed would put every keystroke of a search term past the arrow-key and operator handling below, where it would be read as a motion. That also means "d/foo" is not supported — searching moves the cursor, it does not give an operator something to reach.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Command ¶
type Command struct {
Kind Kind
Motion Motion
// At is where an insert or a put lands.
At Place
// Linewise means whole lines: dd, yy, V.
Linewise bool
// Selection means the operator applies to the visual selection already on
// screen rather than to a motion from the cursor.
Selection bool
// Backward reverses a search: "?" rather than "/".
Backward bool
// Count is how many times the motion applies, and is never zero — an
// untyped count is one, so the caller can multiply without checking.
Count int
// Target is the character a find motion was given.
Target rune
// Object is the region an operator applies to, and Around says whether
// its delimiters go with it: "i" is inside them, "a" takes them too.
Object Object
Around bool
}
func (Command) Changes ¶ added in v0.3.0
Changes reports whether a command altered the buffer, and is therefore what "." would repeat.
The rule is vim's rather than the interface's, so it lives here: a yank copies without changing, a motion moves, and an undo is not a change to be done again. Repeating the repeat is excluded because recording it would lose the original it stands for.
type Entry ¶
type Entry struct {
// Keys is the sequence exactly as it is typed, so that the reference can
// be checked against the state machine rather than trusted.
Keys string
Description string
}
Entry is one line of the key reference.
type Group ¶
Group is a titled section of the reference.
func Reference ¶
func Reference() []Group
Reference lists the modal commands for the help screen and `dv keys`.
It lives beside the state machine on purpose. A reference kept anywhere else drifts, and a key reference that lies is worse than none — it is consulted precisely when something has already stopped working.
type Kind ¶
type Kind int
Kind is what a command does.
const ( // KindNone is the zero command, returned alongside any outcome that is // not OutcomeExecute. KindNone Kind = iota KindMove KindDelete KindChange KindYank KindPaste KindUndo KindRedo // KindInsert enters insert mode at At. KindInsert // KindVisual starts or ends a selection; Linewise says which kind. KindVisual // KindEscape returns to normal mode, collapsing any selection. KindEscape // KindSearch asks for a pattern; Backward says which way from the cursor. KindSearch // KindSearchNext repeats the last search the way it was going, and // KindSearchPrev repeats it the other way. KindSearchNext KindSearchPrev // KindCommandLine asks for the ":" prompt. // // It carries nothing typed at that prompt, for the same reason KindSearch // carries no pattern: the keys after the colon go to a widget, not to this // package. KindCommandLine // KindRepeat asks for the last change to be carried out again. // // It names no command of its own on purpose. A change that entered insert // mode includes the text that was typed, and insert-mode keys go straight // to the widget without this package seeing them — so what to replay is // known only to whoever ran the change. KindRepeat )
type Motion ¶
type Motion int
Motion is where a command reaches.
const ( MotionNone Motion = iota MotionLeft MotionRight MotionUp MotionDown MotionWordForward MotionWordBackward MotionWordEnd MotionLineStart MotionFirstNonBlank MotionLineEnd MotionFileStart MotionFileEnd // The find motions carry the character they were given in Command.Target. // MotionTill stops one short of it, which is what makes "ct," change up to // a comma and leave the comma in place. MotionFindForward MotionFindBackward MotionTillForward MotionTillBackward )
type Object ¶ added in v0.3.0
type Object int
Command is a completed instruction for the editor.
It is a comparable value with no pointers, so tests can state the whole expected command in one literal. Object is a region an operator can act on without a motion reaching it: the word under the caret, or whatever a pair of brackets or quotes encloses.
These are what a SQL editor is reached for most — ci( replaces an IN list, ci' a string literal — because the interesting region is almost always delimited rather than a number of words away.
type Outcome ¶
type Outcome int
Outcome says what the state machine did with a key.
Three outcomes rather than a bool: "the editor should type this" and "I am waiting for the rest of a sequence" are different things, and collapsing them is how a half-typed operator ends up inserting a letter.
type State ¶
type State struct {
// contains filtered or unexported fields
}
State is the modal input state: the current mode and any half-typed sequence.
It is not safe for concurrent use, which is fine — keys arrive one at a time on the interface's own goroutine.
func (*State) Feed ¶
Feed offers a key to the state machine.
The outcome says whether the editor should type the key, keep waiting, or run the returned command.
func (*State) Pending ¶
Pending renders the half-typed sequence for the status bar.
Showing it is not a nicety: an operator that silently waits for a motion is indistinguishable from a keyboard that has stopped working, and that is the single most likely way a new user concludes the application is broken.