Guide for AI agents working in vid — a minimal vim-like text editor in Dart.
Minimal and focused. Don't add formatters/linters/tools that don't exist. Respect existing patterns.
./build.sh # Build to ~/bin/vid
dart run bin/vid.dart # Run directly
dart test # Run tests
dart analyze # Check codelib/
action/ # Action handlers (static method classes)
features/ # Feature modules (LSP, cursor position) with Feature interface
file_buffer/ # Buffer ops split by concern (io, nav, text)
grapheme/ # Unicode/grapheme utilities
highlighting/ # Syntax highlighting and themes
line_edit/ # Command-line (:) editing
motion/ # Movement operations
operator/ # Operators (delete, change, yank, case change)
popup/ # Popup UI components
text_object/ # Text objects (iw, i", a(, etc.)
bindings.dart # All keybindings - DON'T MODIFY unless requested
editor.dart # Main editor class
test/ # Mirrors lib/ structure, *_test.dart files
-
Text ends with
\n—FileBufferenforces this. All text must end with newline. -
Byte offsets, not char indices — Cursor, viewport, line offsets are UTF-8 byte offsets.
-
Cursor at grapheme boundaries — Never position cursor mid-grapheme cluster.
-
Lines rebuilt on change —
FileBuffer.linesrebuilds after every edit. Don't cache. -
Bindings are
const— Maps inbindings.dartare immutable.
- Single-letter vars in tests:
e= Editor,f= FileBuffer - Static action classes:
NormalActions.pasteAfter(),OperatorActions.change() - Single quotes:
'string'not"string" - Import order: dart:, packages, package:vid/, relative
test('description', () {
final e = Editor(
terminal: TestTerminal(width: 80, height: 24),
redraw: false,
);
final f = e.file;
f.text = 'test\n';
f.cursor = 0;
e.input('x');
expect(f.text, 'expected\n');
});ARCHITECTURE.md— Technical architecturedocs/LSP_FEATURE_PLAN.md— LSP roadmapconfig.example.yaml— Config options