Imported from aloknigam247/qvim (
qml/AGENTS.md). Install upstream withnpx skills add aloknigam247/qvim --skill qml. Copyright stays with the author.
qml/ — agent guide (delta)
Root AGENTS.md defines the reactive-proxy and focus rules. This file is the QML-side checklist.
Conventions
- Connect QML to
NvimConnectorsignals directly (Connections { target: $connector }). No imperative pull. - Top-level scene is
Main.qml; the grid host isShell.qml. The long-lived item that owns focus is thebaseGridinsideShell.qml. - Repeater delegates that need to react to per-id field changes consume a
Q_INVOKABLE QObject*proxy (e.g.$connector.gridFor(id)), never a re-emitted whole-list. - Cursor rendering is a separate
CursorItemoverlay sibling ofbaseGridinShell.qml(z=99 — above the grid). It must NOT take focus — focus stays on the long-livedbaseGrid. Bindings flow frombaseGrid(cellWidth/cellHeight/cellBaseline/fontName/fontSize), so font/linespace changes propagate through one signal hop.
Why the reactive QObject-proxy rule exists
A QHash<id, X> re-emitted as a property nukes Repeater delegates on every nvim window event. That destroys activeFocusItem (dead cursor), per-GridItem glyph caches (flicker, FPS drop), and cursor blink phase. A proxy QObject whose fields are Q_PROPERTY with NOTIFY lets bindings re-evaluate in-place; the delegate instance is preserved.
Focus lifetime
Component.onCompleted: forceActiveFocus() fires exactly once. If the owning item is later destroyed (e.g. Repeater rebuild) focus is gone. Focus must live on an item that is never destroyed across nvim window churn — baseGrid in Shell.qml, not a Repeater delegate.
Bug patterns to avoid
model = null; model = listto "refresh" a Repeater. Destroys focus, glyph cache, blink phase. Use a proxy + NOTIFY.setContextProperty("foo", obj)for a type that is alreadyQML_ELEMENT— double-registers and shadows the QML import.- Owning focus on a Repeater delegate. It will be destroyed.
Build/test cheatsheet
cmake --build --preset release
ctest --preset release --output-on-failure -R '^test_qml$'
Templates
- Scene root +
$connectorwiring:Main.qml. - Long-lived grid host that owns focus:
Shell.qml.