github saberzero1/motions 0.69.0

latest releases: 0.147.0, 0.146.0, 0.145.0...
one month ago

Fixed

  • Textarea vim overlay re-activates immediately after Escape exit — pressing Escape in normal mode tore down the overlay and called originalEl.focus(), which triggered the focusin listener and re-created the overlay in insert mode after the 150ms debounce. Users saw a brief flash of the textarea before being placed back in insert mode, making it impossible to return to the modal context. Fixed by adding a recentlyExited guard (WeakRef + 250ms cooldown) that suppresses the focusin handler for the textarea that was just exited. After the cooldown, the textarea can be re-activated by clicking into it again. (#69)
    • Plugin: src/vim/textarea-vim-manager.ts (recentlyExited WeakRef guard, markRecentlyExited cooldown)
  • Lua text objects lost after reloadFeatures()vim.textobject.add() registrations from .obsidian.init.lua were silently discarded because loadLuaConfigInternal() called reloadFeatures() after Lua evaluation, destroying the VimRegistration instance that held the keybindings. Fixed by persisting text object specs in luaTextObjectSpecs[] and re-registering them via reregisterLuaTextObjects() after reloadFeatures() completes.
    • Plugin: src/main.ts (luaTextObjectSpecs, registerLuaTextObject, reregisterLuaTextObjects)

Added

  • Subword motions (spider.nvim-style)w/b/e/ge override stopping at camelCase, snake_case, and kebab-case word boundaries. Opt-in via set subword / Settings → Vim features → Subword motions. 10,000-char performance guard falls back to standard word motions on pathological lines.
    • Plugin: src/util/subword.ts (shared boundary detection), src/motions/subword.ts (4 motion variants)
  • General-purpose text objects — 6 new text objects complementing the existing 13 Markdown-specific ones: iS/aS (subword segment), in/an (numeric literal with sign/decimal), iq/aq (nearest quote pair on line), iD/aD (wikilink [[...]] with nesting), gL (forward-seeking URL), i,/a, (comma-separated argument with nesting). All work with operators (d, c, y) and visual mode.
    • Plugin: src/text-objects/{pair-util,subword,number,any-quote,double-bracket,url,argument}.ts
  • Enhanced increment/decrement (dial.nvim-style)<C-a>/<C-x> extended to cycle: markdown checkboxes ([ ][x]), booleans (truefalse, case-preserved), hex colors (component-wise R/G/B, clamped 0–255), dates (YYYY-MM-DD with rollover), CSS values (preserving unit), and integers. Priority-ordered rules (first match wins). Opt-in via set dial / Settings → Vim features → Enhanced increment/decrement. Falls back to default <C-a>/<C-x> when no rule matches.
    • Plugin: src/actions/{dial-rules,dial,register-dial}.ts
  • Custom text objects via Luavim.textobject.add(keys, spec) and vim.textobject.del(keys) API for defining custom text objects from .obsidian.init.lua. vim.gen_spec.pair(open, close, opts?) generates pair-matching specs with nesting and multi-line support. Keys must start with i (inner) or a (around). Invalid inputs produce error notices.
    • Plugin: src/lua/textobject-api.ts
  • External grep binary integration — optional native ripgrep or GNU grep binary for the picker's grep/live-grep sources. Supports rg --json (structured output) and grep -rn (file:line:content format). Desktop-only with automatic fallback to in-memory search on mobile or binary failure. Circuit breaker (3 errors in 60s → auto-disable). Process cancellation on new query.
    • Plugin: src/picker/sources/ripgrep-process.ts, settings: ripgrepEnabled, ripgrepBinaryPath, ripgrepArgs, grepMode

Tests

  • 37 unit tests in test/unit/subword.test.ts: boundary detection (13 patterns), motion logic (20 cases including cross-line, count, performance guard)
  • 45 unit tests in test/unit/text-objects-extended.test.ts: all 6 text objects with inner/around, edge cases, nesting
  • 31 unit tests in test/unit/dial.test.ts: all 6 rules individually + priority ordering + tryDial integration
  • 26 unit tests in test/unit/lua-textobject-api.test.ts: asymmetric/symmetric pair matching, nesting, multi-line, scanLimit
  • 21 unit tests in test/unit/ripgrep-process.test.ts: JSON/grep output parsing, arg building, error classification
  • 10 e2e tests in test/specs/subword-motions.e2e.ts: navigation, operators, snake/kebab, count, setting toggle
  • 11 e2e tests in test/specs/text-objects-extended.e2e.ts: all text objects with delete/change operators
  • 9 e2e tests in test/specs/dial.e2e.ts: all rule types, count prefix, no-match fallback, setting toggle
  • 5 e2e tests in test/specs/lua-textobject.e2e.ts: custom pairs (single-char, multi-char, nested), error handling
  • 3 e2e tests in test/specs/ripgrep.e2e.ts: conditional skip (binary availability)

Documentation

  • CHANGELOG.md: Added textarea re-activation prevention fix
  • KNOWN_LIMITATIONS.md: Textarea re-activation after Escape → Fixed (recentlyExited guard)

Full Changelog: 0.68.0...0.69.0

Don't miss a new motions release

NewReleases is sending notifications on new releases.