Fixed
- Cursor disappears when entering a table in source mode or raw mode — when the cursor entered a table range in source mode or with
tableWidgetMode='raw', the vim cursor became invisible while editing still worked. Root cause:mainEditorTableCursorGuardsuppressed the vim cursor whenever the cursor was in a text range matching table syntax (findTableRanges()), without checking whether a native table widget was actually visible. In source mode there are no.cm-table-widgetelements; in raw mode they exist but are hidden viadisplay: none. In both cases, the cursor was suppressed with no alternative cursor shown. Fixed by adding ahasVisibleTableWidget()check that requires at least one.cm-table-widgetelement with a non-nulloffsetParentbefore suppressing. The check also short-circuits thefindTableRanges()document scan when no visible widgets exist. (#132)- Plugin:
src/vim/table-cell-cursor-guard.ts(hasVisibleTableWidget()function;mainEditorTableCursorGuard.update()— gates cursor suppression on visible widget presence)
- Plugin:
- Cell-edit
h/j/k/lunconditionally exits to table-nav in normal mode — when editing a table cell with table-nav enabled, pressingh/j/k/lin normal mode (after Escape from insert mode) immediately exited to table-nav and navigated to the adjacent cell, even when the cursor had room to move within the cell. Root cause: thecellEditScopehjkl handlers only checkedisVimIdle()— if idle, they unconditionally calledexitCellEditToNav()+navigate()without checking whether the cursor was at a cell boundary. Fixed by adding acursorAtCellBoundary()method that checks cursor position against cell content bounds:hexits only atch <= 0,latch >= lineLen - 1,jat last line,kat first line. When the cursor is not at the boundary, the handler returnsundefinedto let vim process the key as normal in-cell movement. (#131)- Plugin:
src/vim/table-nav-controller.ts(cursorAtCellBoundarymethod;installCellEditScopehjkl handlers — boundary check beforeexitCellEditToNav)
- Plugin:
Tests
- 5 regression tests for cursor visibility in source mode and raw table mode in
test/specs/table-cursor-source-mode.e2e.ts(issue #132): 3 source mode tests (cursor layer state unchanged on table line, after traversal, on data row) + 2 raw mode tests (widget hidden, cursor layer stable during repeated traversal) - 5 regression tests for cell-edit hjkl boundary behavior in
test/specs/table-nav-mode.e2e.ts(issue #131):lmid-cell stays in cell,hmid-cell stays in cell,lat end exits to nav,hat start exits to nav, insert→Escape→lstays in cell - Systematic e2e test audit — audited all 126 non-spike e2e test files across 8 parallel analysis passes. Fixed ~60 individual test assertions across 40 files: replaced vacuous
toContain(already-present-substring)assertions with exact buffer equality, added register preservation checks, converted conditional early-returns to mandatory assertions or visiblethis.skip()calls, removed 2 exact duplicate tests, and fixed 10 test name/behavior mismatches. - Test infrastructure hardening — 6 structural improvements to the test infrastructure:
- Global
afterTesthook inwdio.conf.mts: cleans up overlays (hint, easymotion, which-key, ex-suggest), picker modals (via Escape dispatch), generic modals (via close-button click), notices, and Vim state (double<Esc>) between every test. Includes verification pass that force-removes surviving elements. - Strict helpers in
test/helpers.ts:setupEditor,sendVimEscape,getEditorValue,getCursorPos,getCursorLine,getSelection,focusEditor,ensureLivePreview,ensureSourceModenow throw with context (e.g.,"setupEditor: no MarkdownView (active leaf type: graph)") instead of silently returning defaults. waitUntil-based synchronization:setupEditorwaits for content match,loadSingleFileWorkspacewaits for MarkdownView,ensureLivePreview/ensureSourceModewait for mode change — replacing fixedbrowser.pause()delays.- Settings mutation reliability:
setPluginSettingnow awaitssaveSettings(). NewsetPluginSettingAndReloadhelper sets + saves + callsreloadFeatures()+ waits for settle. - Golden enforcement:
testWithNeovimnow throws"Missing golden case"when no golden data exists (unless the test is a known deviation), preventing silent passes. - Hint-mode link navigation:
findHintLabelForLinkupdated to usegetBoundingClientRect()with CSS var fallback, wider CM6 selectors (.cm-link,.cm-url,[data-href]), and active-leaf scoping (.workspace-leaf.mod-active .cm-editor).
- Global
- Hint-mode-links fully unblocked — 15 previously-skipped hint-mode link navigation tests now pass. Root causes fixed: (1) vault fixture files created under
test-vault/fixtures/hint-mode/to trigger Obsidian's full rendering pipeline (CM6 link decorations, metadata cache), (2)before()hook warms link cache by opening all fixtures, (3)findHintLabelForLinkscoped to active leaf's.cm-editor. - New unit tests — 6 new unit test files (96 tests total):
oil-parser.test.ts(15 tests): buffer line parsing, id/type/name extraction,.mdauto-append, Windows line endings, names with spacesoil-diff.test.ts(11 tests): rename/delete/create detection, foreign ids, move resolution across multi-buffer diffsvimrc-parser.test.ts(35 tests): all 13 command types, noremap detection, context inference, icon/color extraction, comments, multi-line parsingflash-labeler.test.ts(10 tests): label assignment, distance sorting, 2-char labels, reuse, skipCharsfold-persistence.test.ts(7 tests): load/save round-trip, removePath, renamePath, TTL eviction, max entries evictionpair-util.test.ts(12 tests): symmetric/asymmetric delimiters, nesting, multiline, scan limits, empty pairs
- New e2e tests — 3 new e2e test files (11 tests total):
insert-escape.e2e.ts(6 tests):jk/jjescape sequences, character cleanup, timeout behavior, non-matching sequences, empty configscrolloff-cursorline-smoke.e2e.ts(4 tests): scrolloff setting persistence + cursor positioning, cursorline enable/disable cyclecontext-actions-smoke.e2e.ts(1 test)::contextactionscommand opens a modal
Documentation
CHANGELOG.mdKNOWN_LIMITATIONS.md: Added cursor disappears in source/raw mode as fixed (#132); updated cross-cell navigation description —h/j/k/lnow move within cell when cursor is not at boundary (#131)CONTRIBUTING.md: Updatedtable-cell-cursor-guard.tsdescription withhasVisibleTableWidget()check; updatedtable-nav-controller.tsdescription withcursorAtCellBoundaryboundary checkdocs/features/tables.md: Added note about cursor visibility fix in source/raw mode; updated cell-edit behavior description —h/j/k/lmove within cell before boundary exitAGENTS.md: Updated test helpers description (strict behavior,waitUntilsynchronization,setPluginSettingAndReload); addedafterTesthook and vault fixtures documentation; added golden enforcement description; updated unit test listCONTRIBUTING.md: Updated test infrastructure tree (vault fixtures, snippets subdirs,test-wrapper.tsgolden enforcement); updated shared helper descriptions (strict behavior,waitUntil); added vault fixture and afterTest cleanup guidance to key testing rules
Full Changelog: 0.112.0...0.113.0