Added
- Table-nav overlay mode — when the cursor enters a table in Live Preview, a navigation overlay activates, allowing cell navigation with
h/j/k/lwithout entering the cell editor. Supports structural commands (o/O,dd,dc,J/K,H/L,I/A,=) and cell editing entry viai/a/c/s/Enter. Escape exits table-nav. Fork-only feature.- Plugin:
src/vim/table-nav-controller.ts(KeyScope-based interception, freshcmTile.widgetreferences, hidden cell editor during navigation) - Plugin:
src/vim/table-nav-state.ts(overlay state tracking) - Plugin:
src/vim/table-nav-keymap.ts(navigation and structural command mappings) - Plugin:
src/vim/native-table-adapter.ts(extended with overlay support) - Styles:
styles.css(overlay and hidden editor styling)
- Plugin:
Changed
table-cell-cursor-guard.ts— now checksisTableNavActive()to avoid cursor suppression conflicts during table navigation.- Cross-cell motions decoupled from table-nav —
applyTableCellMotions()(h/j/k/l cross-cell navigation in native cell editors) is now gated ontableWidgetMode === 'native'only, independent ofenableTableNav. Previously required bothenableTableNavandtableWidgetMode === 'native'. This enables a third usage mode: native table editor with vim cell editing and cross-cell navigation, without the table-nav overlay. TheenableTableNavsetting now controls only the nav overlay and structural motions (]|/[|,]c/[c).- Plugin:
src/main.ts(bothonloadandreloadFeaturespaths — removedenableTableNavfromapplyTableCellMotionsgate) - Plugin:
src/settings.ts(updatedenableTableNavdescription in both declarative and imperative settings UI)
- Plugin:
Fixed
- Cursor snaps back to table after exiting table-nav — after navigating/editing in table-nav mode and exiting, the cursor could snap back to the last table cell position. Root cause:
exitTable()calledplaceCursorAround()beforedestroyTableCell(), and Obsidian's cell editor destruction triggers internal blur/focus/selection side-effects that overrode the cursor position. Fixed by reordering: destroy the cell editor first, then deferplaceCursorAround()torequestAnimationFrameso Obsidian's teardown handlers finish before the final cursor placement.- Plugin:
src/vim/table-nav-controller.ts(exitTable— destroy-before-place, deferred cursor placement viawindow.requestAnimationFrame)
- Plugin:
- Cell-editor normal-mode navigation bypasses table-nav — when in a cell editor in normal mode (Escape pressed once to exit insert, but not again to exit cell edit),
j/k/h/lat cell boundaries crossed to adjacent cells via the motion overrides, bypassing the table-nav controller. This left table-nav in an inconsistent state. Fixed by registeringh/j/k/lkey handlers on thecellEditScope(ObsidianScope). When vim is idle in the cell editor, these handlers exit to nav mode and navigate within the overlay. The Scope fires before vim's key observer, so the keys are intercepted before the motion overrides run.- Plugin:
src/vim/table-nav-controller.ts(installCellEditScope— addedh/j/k/lhandlers that checkisVimIdleand callexitCellEditToNav+navigate)
- Plugin:
- Cursor flashing in Normal mode after table interaction — the table cursor guard and table-nav controller used
setCursorSuppressedForView(view, false)to unsuppress the cursor when leaving a table. This sets an explicit per-view override that conflicts with the animated cursor controller's global suppression (setCursorSuppressed(true)), causing the native CM6 cursor to become visible and flash alongside the canvas cursor. Additionally,mainEditorTableCursorGuard.destroy()did not restore suppression state when the cursor was inside a table at destruction time, leaving a staletrueoverride through plugin recreation.cellEditorCursorGuard.update()force-unsuppressed the cell cursor on every update cycle (same anti-pattern removed fromCursorControllerin commit 62444df). All unsuppress paths now useclearCursorSuppressedForView()(which removes the per-view override, falling back to global state) instead ofsetCursorSuppressedForView(view, false). (#127)- Plugin:
src/vim/table-cell-cursor-guard.ts(mainEditorTableCursorGuard— added constructor to store view reference;destroy()now clears per-view override and resumes animated cursor whencursorInTableis true;update()usesclearCursorSuppressedForViewwhen leaving table;cellEditorCursorGuard— removed per-updatesetCursorSuppressedForView(cellView, false)force-unsuppress;destroy()usesclearCursorSuppressedForViewfor parent) - Plugin:
src/vim/table-nav-controller.ts(enterCellEdit,exitTable,destroy— all useclearCursorSuppressedForViewinstead ofsetCursorSuppressedForView(view, false)) - Plugin:
src/vim/bundled-vim.ts(exposedisCursorSuppressedForViewonCodeMirrorAdapterbridge for test access)
- Plugin:
Tests
- 6 regression tests for cursor suppression after table interaction in
test/specs/table-cursor-suppression.e2e.ts(issue #127) - Rewrote
test/specs/table-cell-vim-mode.e2e.ts"Native table cell navigation" suite for table-nav architecture: nav-mode highlight position checks (j/k/h/l), entry/exit tests (Escape, i→cell edit→Escape→nav), dd row deletion in nav mode, re-entry test (j back into table re-activates table-nav), cursor stability test (exit + insert mode round-trip doesn't snap cursor back). Replaced "Settings gating" suite with "Table mode combinations" covering all 3 modes: native+tablenav (overlay activates), native+notablenav (cross-cell j/k/h/l works without overlay), raw (widget hidden) - Fixed 3 spike test files (
spike-table-fresh-ref,spike-cell-introspect,spike-table-nav-overlay) by disabling table-nav inbeforehooks so cell editor introspection tests can accesseditMode.tableCelldirectly - Fixed
spike-table-nav-overlayeditorInfoField test: useobsidian.editorInfoFieldfromexecuteObsidiancallback instead ofwindow.require('obsidian')
Documentation
CHANGELOG.mdKNOWN_LIMITATIONS.md: Added cursor-snap fix; updated table widget section with 3-mode table; updated cross-cell motion decouplingAGENTS.md: Updatedtable-nav-controller.tsdescription with deferred exit flow; updated table-cell-motions gatingCONTRIBUTING.md: Updatedtable-nav-controller.tsandtable-cell-motions.tsdescriptionsREADME.md: Updated table editing feature description with 3 mode combinationsdocs/features/tables.md: Updated table widget section with 3-mode architecture; clarified enableTableNav vs cross-cell motionsdocs/configuration/settings.md: UpdatedenableTableNavdescription
Full Changelog: 0.110.0...0.111.0