github saberzero1/motions 0.110.0

latest releases: 1.3.1, 1.3.0, 1.2.0...
one month ago

Added

  • Animated cursor: cross-cell position handoff — when navigating between table cells via h/j/k/l, a token-based handoff seeds the new cell's CursorController with the previous cell's screen position via the AnimatedCursorManager singleton. The handoff infrastructure is in place but the canvas transition animation is not visible due to CSS stacking contexts (the canvas at position: fixed on .app-container renders behind table cell content). The native vim cursor (BlockCursorPlugin) serves as the steady-state renderer inside cells. See KNOWN_LIMITATIONS.md for details.
    • Plugin: src/vim/animated-cursor/manager.ts (CellCrossingHandoff interface, createCrossingToken/storeCrossingHandoff/consumeCrossingHandoff methods, signalCellCrossing/getPendingCrossingToken/clearPendingCrossingToken module-level functions)
    • Plugin: src/vim/animated-cursor/controller.ts (cellTransitionActive flag, crossing token consumption in constructor, position handoff in destroy, cell-aware tick/update that skips canvas drawing when no transition is active)
    • Plugin: src/vim/table-cell-motions.ts (signalCellCrossing() call in scheduleCrossing)
    • Fork: ~/Repos/codemirror-vim/src/block-cursor.ts (table cell override documented in DIFFERENCES.md)
    • Styles: styles.css (animated cursor canvas z-index bumped from 5 to 15)

Changed

  • Table editing: migrated to native Obsidian table editor — the plugin no longer suppresses Obsidian's cm-table-widget or provides custom cell editors. In Live Preview, Obsidian's native table editor handles cell editing, pipe escaping, wikilinks, cursor positioning, and <br> conversion. Vim is injected into native cell editors via registerEditorExtension(). The tableWidgetMode setting is simplified from 4 values (off/cursor/always/embedded) to 2 (native/raw). Old values are automatically migrated.
    • Removed: src/vim/table-widget-suppressor.ts (RangeSetBuilder monkey-patch)
    • Removed: src/vim/table-render-widget.ts (custom widget)
    • Removed: src/vim/table-nav-controller.ts (custom nav state machine)
    • Removed: src/vim/table-cell-editor.ts (custom cell editors)
    • Removed: src/vim/table-embedded-editor.ts (configuration bridge)
    • Added: src/vim/table-nav-overlay.ts (native TableEditor API overlay)
    • Added: src/vim/native-table-adapter.ts (typed abstraction layer)
    • Added: src/types/table-editor.d.ts (runtime-discovered typings for 55 native methods)

Fixed

  • Escape in hint mode exits embedded vim editor — pressing Escape to dismiss hint mode while inside an embedded vim editor (textarea vim overlay, Oil explorer, table cell editor) also exited the embedded editor. Root cause: Obsidian's Scope keymap handlers fire independently of DOM event propagation — stopPropagation() in hint mode's capture-phase listener does not prevent the Scope handler from receiving the event. The embedded editor's Scope handler checked isVimIdle() (which returns true during hint mode, since hint mode is a plugin-level overlay, not a vim state) and called onEscape(). Fixed by adding a guard in the embedded editor's Escape handler that checks isHintModeActive(), isEasyMotionActive(), and isFlashActive() before evaluating isVimIdle(). (#126)
    • Plugin: src/editors/embeddable-editor.ts (Scope Escape handler — modal overlay active guard before isVimIdle() check)
  • Wikilinks in table cells work correctly — cursor displacement when typing [[ in table cells is fixed. The native editor handles wikilink rendering at the decoration layer, eliminating the sub-CM6 cursor displacement that affected the old custom widget.
  • Pipe character (|) no longer swallowed in table cells — the native editor automatically escapes | as \| in the document source. Previously, Obsidian's DOM-level table editor intercepted | before CM6's input pipeline.
  • <br> conversion handled natively — newlines in table cells are automatically converted to/from <br> by the native editor. The cellBrToNewline/cellNewlineToBr utilities are removed.
  • Embedded table: Obsidian shortcuts (Ctrl+P, Cmd+O) now work in cell selection mode — modifier key combos in table-nav mode now call e.stopPropagation() to prevent vim's eventObservers.keydown from consuming them as cursor movement, then manually feed the event to Obsidian's keymap system via app.keymap.onKeyEvent(e). This two-step approach blocks vim (which would process <C-p> as cursor-up) while still triggering Obsidian's hotkey bindings (command palette, file switcher, custom hotkeys). Uses the unofficial Keymap.onKeyEvent API from obsidian-typings. (#120)
    • Plugin: src/vim/table-nav-controller.ts (handleTableNavKey — stopPropagation + app.keymap.onKeyEvent for modifier combos)
  • Embedded table: ex command dialog keys no longer consumed by table-nav — when vim's ex command dialog is open (after pressing :), table-nav keys like h, j, k, l, a, i, c are no longer intercepted by the table-nav handler. The handler now checks adapter.state.dialog and returns early when a dialog is active. (#120)
    • Plugin: src/vim/table-nav-controller.ts (handleTableNavKey — adapter.state.dialog check)
  • Insert mode escape sequence and other vim engine settings not applied after restart — six vim engine settings (insertmodeescape, insertmodeescapetimeout, operatorshadowtimeout, tabstop, shiftwidth, expandtab) configured via the Settings UI were not synced to the vim engine on plugin load. Only clipboard, textwidth, and pcre were synced at startup. The remaining settings were stored in data.json but never pushed to vim.setOption() during initialization, so they silently reverted to defaults on every Obsidian restart. The vimrc/Lua code path was unaffected because it calls vim.setOption() directly. Additionally, on Obsidian 1.13+, the declarative settings system (setControlValue) did not forward any of the 9 vim engine settings to vim.setOption() — only the pre-1.13 imperative onChange handlers did. (#125)
    • Plugin: src/main.ts (added init sync for insertmodeescape, insertmodeescapetimeout, operatorshadowtimeout, tabstop, shiftwidth, expandtab after registerVimOptions())
    • Plugin: src/settings.ts (VIM_OPTION_KEYS static set; setControlValue forwards vim engine settings to vim.setOption() with setClipboardOption/setTextwidth side effects)

Tests

  • 1 regression test for hint mode Escape in test/specs/textarea-vim.e2e.ts (issue #126): Escape in hint mode dismisses hint overlay but does not exit the textarea vim overlay — verified to fail without the modal overlay guard
  • 1 regression test for modifier combo in test/specs/table-cell-vim-mode.e2e.ts: modifier combo does not move cursor during cell selection
  • 1 regression test for ex dialog in test/specs/table-cell-vim-mode.e2e.ts: keys with table-nav meaning do not change active cell when ex dialog is open (verified to fail without dialog check)

Documentation

  • CHANGELOG.md
  • KNOWN_LIMITATIONS.md: Added hint mode Escape fix to textarea vim Escape behavior section (#126)
  • AGENTS.md: Updated embeddable-editor description with modal overlay active guard
  • CONTRIBUTING.md: Updated embeddable-editor description with modal overlay active guard
  • docs/features/hint-mode.md: Added note about embedded editor Escape isolation
  • KNOWN_LIMITATIONS.md: Updated vim engine settings section — all 9 settings now synced at init (was 3); added declarative settings forwarding fix for Obsidian 1.13+ (#125)
  • KNOWN_LIMITATIONS.md: Added animated cursor cross-cell transition as known limitation in table cell vim modality section
  • CONTRIBUTING.md: Added table-cell-motions.ts and table-cell-cursor-guard.ts to codebase structure; updated manager.ts with cross-cell handoff API; updated controller.ts with cell transition architecture
  • AGENTS.md: Updated animated cursor page ownership (unchanged — features/animated-cursor.md)
  • docs/features/animated-cursor.md: Updated embeddable editors section with cross-cell transition details and known limitation
  • docs/features/tables.md: Added animated cursor note to cell editor section
  • Fork DIFFERENCES.md: Added table cell override section documenting BlockCursorPlugin's unsuppress behavior for .cm-table-widget editors

Full Changelog: 0.109.1...0.110.0

Don't miss a new motions release

NewReleases is sending notifications on new releases.