github saberzero1/motions 0.136.0

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

Added

  • 36 new vim.fn functions — expanded the Lua API from 29 to 65 supported vim.fn.* functions:
    • Register: setreg(regname, value [, options]), getreg(regname), getregtype(regname) — full register manipulation matching Neovim's signatures
    • Buffer: setline(lnum, text), append(lnum, text|list), indent(lnum), nextnonblank(lnum), prevnonblank(lnum) — buffer modification and line scanning
    • Position: getpos(expr), setpos(expr, list), cursor(lnum, col), getcurpos() — cursor and mark manipulation; getpos("'[") / getpos("']") enables g@ operatorfunc usage
    • Type/introspection: type(expr), len(expr), empty(expr) — fundamental type guards for Lua configs
    • Pattern matching: matchstr(s, pat), match(s, pat [, start]), matchlist(s, pat) — string pattern matching (ECMAScript regex)
    • String/list: escape(s, chars), repeat(s|list, count), reverse(s|list), range(n [, end [, stride]]), sort(list), uniq(list), max(list), min(list), abs(n), index(list, item), count(list, val)
    • List/dict sugar: add(list, item), remove(list, idx), extend(list1, list2), copy(expr), deepcopy(expr), keys(dict), values(dict), items(dict), flatten(list) — syntactic sugar over Lua builtins / vim.tbl_* equivalents
    • Plugin: src/lua/fn.ts (all implementations + VimFnCallbacks extended with setCursor, getMarkPos, setMark, setLine, insertLines)
    • Plugin: src/main.ts (wired new callbacks in executeLuaForTest)
    • Plugin: src/lua/loader.ts (wired new callbacks in main loader)
  • Neovim-compatible foldopen option — fold-aware navigation now matches Neovim's foldopen semantics. Each vim motion is tagged with a category (hor, block, jump, mark, search, percent, undo), and only motions whose category is in the configured foldopen set trigger auto-unfold when the cursor enters a folded range. Plain vertical motions (j/k) have no category and never unfold, matching Neovim's intentional exclusion of vertical movements. Configurable via set foldopen=block,hor,mark,percent,search,undo (Neovim default) or set fdo=all. (#155)
    • Fork: ~/Repos/codemirror-vim/src/cm_adapter.ts (foldopenAnnotation CM6 transaction annotation, _pendingFoldopen on adapter)
    • Fork: ~/Repos/codemirror-vim/src/vim.js (40+ motions tagged with foldopen category in defaultKeymap, annotation set in evalInput, undo/redo, jumpListWalk)
    • Fork: ~/Repos/codemirror-vim/src/types.ts (FoldopenCategory type, foldopen on MotionArgsPartial)
    • Fork: ~/Repos/codemirror-vim/src/index.ts (exported foldopenAnnotation, FoldopenCategory)
    • Plugin: src/vim/fold-sync.ts (annotation-gated foldAwareNavExtender, setFoldopen()/getFoldopen()/shouldUnfold())
    • Plugin: src/vim/bundled-vim.ts (injects fork annotation at extension creation)
    • Plugin: src/motions/register.ts (structural motions tagged block, subword motions tagged hor)
    • Plugin: src/vim/options.ts (set foldopen=… / set fdo=… vim option)
    • Plugin: src/main.ts (foldopen handler in applySettingOverride)
    • Plugin: src/settings.ts (updated fold-aware navigation descriptions in both settings tabs)
  • Range-aware fold ex commands — :{range}fold, :{range}foldopen[!], :{range}foldclose[!], :{range}folddoopen {cmd}, and :{range}folddoclosed {cmd} now support Neovim-style line ranges. Previously :foldopen/:foldclose only operated at the cursor. :{range}fold creates a manual fold; ! suffix opens/closes recursively; :folddoopen/:folddoclosed execute an ex command on lines that are not/are in a closed fold.
    • Plugin: src/fold/commands.ts (range-aware handlers: foldRangeEx, foldOpenRangeEx, foldCloseRangeEx, foldDoOpenEx, foldDoClosedEx)
    • Plugin: src/workspace/navigation.ts (removed exCommandFromAction registrations for :foldopen/:foldclose/:foldtoggle — replaced by range-aware versions in fold/commands.ts)
    • Plugin: src/main.ts (executeLuaForTest sandbox handleExCommand wired to vim.handleEx — enables golden tests to create folds via vim.cmd)
  • Neovim options registry — every Neovim option (378 total from src/nvim/options.lua) is now recognized by name in both :set (vimrc) and vim.opt (Lua). Options are classified into tiers: implemented options work normally, hardcoded options log an info note (e.g., set magic — "always on"), deferred options log that support is planned, platform-handled options are accepted silently (e.g., set mouse=a, set encoding=utf-8, set noswapfile), and truly unknown options still produce a warning — enabling typo detection (set mose=a warns, set mouse=a is silent).
    • Plugin: src/vim/neovim-options.ts (new file — comprehensive registry with tier classification)
    • Plugin: src/vimrc/loader.ts (integrated registry, replaced KNOWN_CM_VIM_OPTIONS set, tiered logging)
    • Plugin: src/lua/api.ts (integrated registry into vim.opt/vim.o getter and setter)
  • 12 configurable Neovim options — standard Neovim options previously hardcoded in the codemirror-vim fork are now user-configurable via set/vim.opt with Neovim-compatible defaults and abbreviations:
    • Search: ignorecase/ic (default on), smartcase/scs (default on), hlsearch/hls (default on), incsearch/is (default on), wrapscan/ws (default on)
    • Substitute: gdefault/gd (default off — :s g flag inverts when on)
    • Motion: startofline/sol (default on), whichwrap/ww (default b,s), virtualedit/ve (default empty — supports onemore, all, block)
    • Editing: joinspaces/js (default off — J inserts double space after .!?), shiftround/sr (default off — >>/<< round to shiftwidth), nrformats/nf (default bin,hex — <C-a>/<C-x> format support, octal now available)
    • Fork: ~/Repos/codemirror-vim/src/vim.js (12 defineOption() calls, search call sites updated, hlsearch gating, incsearch gating, wrapscan boundary messages, gdefault inversion, startofline in H/M/L/G/gg, whichwrap in moveByCharacters, virtualedit in clipCursorToContent, joinspaces in joinLines, shiftround in indent operator, nrformats with parseNumberMatch helper)
    • Plugin: src/vimrc/loader.ts (12 options registered in KNOWN_SET_OPTIONS with _fork: prefix settingsKey)

Added

  • Oil preview window (<C-p>) — toggle a side-by-side preview split showing the file under the cursor. Auto-updates on cursor movement via EditorView.updateListener. Second <C-p> closes the preview. Closes automatically when oil closes. New ex command :oilpreview (:oilpre).
    • Plugin: src/oil/manager.ts (togglePreview(), closePreview(), installPreviewCursorListener())
    • Plugin: src/oil/keybindings.ts (<C-p> mapping + oilPreview action)
    • Plugin: src/oil/oil-view.ts (<C-p> scope key registration)
  • Oil visual mode multi-select — V + select lines + <CR> opens all selected file entries. First file replaces the oil leaf, subsequent files open in new tabs. Matches oil.nvim's visual select behavior.
    • Plugin: src/oil/manager.ts (getVisualRangeEntries(), openMultipleEntries())
  • Oil hidden toggle guard — g. toggle is now blocked when the oil buffer has unsaved changes, showing a notice instead. Matches oil.nvim's toggle_hidden() behavior which warns and refuses when modified buffers exist.
    • Plugin: src/oil/manager.ts (hasUnsavedChanges() guard in toggleHidden(), return type changed to boolean)
    • Plugin: src/oil/keybindings.ts (checks return value before refreshing)

Fixed

  • Oil: unable to create files with a new directory — creating a file like newfolder/notes.md where newfolder/ doesn't exist now creates both the directory and the file, matching oil.nvim's behavior. Root cause: app.vault.create() does not auto-create intermediate directories (unlike app.vault.createFolder()). (#154)
    • Plugin: src/oil/actions.ts (ensureParentDirs() — walks path segments and creates missing directories before file creation)

Tests

  • Oil nested path creation e2e tests — 3 new e2e tests in test/specs/oil-poc.e2e.ts verifying nested file creation (newfolder/notes.md), deeply nested paths (a/b/deep.md), and nested directory creation (parent/child/). All 3 fail before the fix and pass after. (#154)
  • Oil nested path parser unit tests — 4 new unit tests in test/unit/oil-parser.test.ts for nested path parsing.
  • Oil preview toggle e2e test — 1 new e2e test verifying <C-p> opens a preview split and second <C-p> closes it.
  • Oil hidden toggle guard e2e test — 1 new e2e test verifying g. is blocked when buffer has unsaved changes.
  • Oil visual mode multi-select e2e tests — 2 new e2e tests: visual mode detection in oil editor, and multi-file open via visual select + <CR>.
  • Ex command range golden tests — 8 new golden test cases recorded against Neovim 0.12.5 verifying fork-native :{range} support for commands handled entirely by the codemirror-vim fork: :1,3y (yank range), :2,4y a (yank range to named register), :1,3j (join range), :2,4j! (join range without spaces), :put (put after current line via :1y + :put), :3put (put after addressed line via :1y + :3put), :2,4g/pattern/d (global with range prefix), :1,3v/pattern/d (vglobal with range prefix).
    • Definitions: test/neovim/test-definitions.ts (8 new cases in ex-commands-expanded and ex-global suites)
    • Golden: test/neovim/golden-data/ex-commands-expanded.json (re-recorded, 27 cases)
    • Golden: test/neovim/golden-data/ex-global.json (re-recorded, 5 cases)
  • :d count/address and :j range deviations resolved — :d3 (delete with count argument), :$d (delete with $ address), :1,3j (join with range), and :2,4j! (join bang with range) were marked as deviations. All now work correctly: :d{count} parses the count from args[0]; :$d resolves via the fork's parseLineSpec_; :j range fix changes repeat: lineEnd - line to repeat: lineEnd - line + 1; :j! now passes keepSpaces: true via params.argString bang detection. All 4 deviations removed.
    • Fork: ~/Repos/codemirror-vim/src/vim.js (exCommands.join: off-by-one fix + keepSpaces bang support)
    • Deviations: test/neovim/deviations.ts (2 upstream-unsupported entries removed: :d3, :$d)
  • Foldopen unit tests — 36 tests covering setFoldopen() parsing, shouldUnfold() for every individual category, all/empty sets, custom combinations, and backward-compatible setFoldAwareNavigation().
    • Test: test/unit/foldopen.test.ts
  • Foldopen golden tests — 8 golden cases recorded against Neovim 0.12.5 covering j/k/3j/G/gg/5G with manual folds. 7 match golden data exactly, 1 has a minor column-preservation difference (CM6 preserves visual column on fold-skip; Neovim resets to 0).
    • Test: test/specs/vim-builtin/foldopen-golden.e2e.ts
    • Golden: test/neovim/golden-data/foldopen.json
    • Definitions: test/neovim/test-definitions.ts (new foldopen suite)
    • Deviations: test/neovim/deviations.ts (1 infra-limitation entry for column difference)
  • vim.fn e2e tests — 35 tests in test/specs/lua-vim-fn.e2e.ts covering all new vim.fn functions across 6 categories: registers (setreg, getreg, getregtype), buffer modification (setline, append, indent), position/cursor (nextnonblank, prevnonblank, cursor, setpos, getpos, getcurpos), type/introspection (type ×5, len ×2, empty), pattern matching (matchstr, match, matchlist, escape), string/list utilities (repeat, reverse, range, sort, uniq, max, min, abs, index, count).
    • Test: test/specs/lua-vim-fn.e2e.ts
  • Fold-aware navigation e2e tests — expanded from 2 to 6 tests. New tests verify j/k do not auto-open folds, j from fold line skips past the fold, k navigates back to fold line, and upward k traversal preserves all folds.
    • Test: test/specs/fold-navigation.e2e.ts

Documentation

  • CHANGELOG.md
  • KNOWN_LIMITATIONS.md: updated vim.fn function count (27 → 65), added not-yet-implemented table (lower-value/niche functions), added explicitly excluded functions (map/filter/printf incompatible signatures); search options now configurable; unknown options warning behavior updated for Neovim options registry; added "Oil.nvim parity gaps" section documenting 8 unimplemented oil.nvim features; added :oilpreview to oil keybindings list; updated oil status line
  • README.md: oil explorer description updated with <C-p> preview, visual mode multi-select, nested path creation
  • docs/reference/keybindings.md: added <C-p> (:oilpreview) and g? (:oilhelp) to oil keybindings table
  • docs/features/oil-explorer.md: added preview, visual mode multi-select, nested path creation, and hidden toggle guard sections; added :oilpreview to ex commands table
  • docs/features/ex-commands.md: added :oilpreview and :oilhelp to oil ex commands table
  • docs/configuration/lua-config.md: added 36 new vim.fn functions to quick-reference and detailed tables; added 12 new Neovim options to vim.opt table
  • AGENTS.md: vim.fn count updated (27 → 65), fork API surface updated with foldopenAnnotation and 12 configurable Neovim options
  • CONTRIBUTING.md: fn.ts description updated (26 → 65 functions); added neovim-options.ts to src/vim/ file tree
  • docs/development/architecture.md: fn.ts function count updated
  • Fork: ~/Repos/codemirror-vim/DIFFERENCES.md: :join range/bang/cursor section expanded; added "Configurable Neovim options" section documenting 12 new defineOption() calls
  • README.md: folding feature description updated with foldopen semantics; quality of life section updated with 12 configurable Neovim options and Neovim option compatibility
  • docs/configuration/settings.md: fold-aware navigation description updated, foldopen row added to Workspace navigation settings
  • docs/configuration/vimrc.md: foldopen/fdo added to string options table, foldawarenavigation description updated; added 12 new Neovim options to boolean and string tables; updated unknown options warning description for Neovim options registry
  • docs/configuration/lua-config.md: foldopen added to vim.opt options table
  • docs/features/workspace-navigation.md: fold-aware navigation section rewritten for foldopen semantics
  • docs/features/ex-commands.md: added :{range}fold, :{range}foldopen[!], :{range}foldclose[!], :folddoopen, :folddoclosed; updated :foldopen/:foldclose descriptions to note range support
  • Fork: ~/Repos/codemirror-vim/DIFFERENCES.md: foldopenAnnotation API section added

Full Changelog: 0.135.0...0.136.0

Don't miss a new motions release

NewReleases is sending notifications on new releases.