github saberzero1/motions 0.55.0

latest releases: 0.150.0, 0.149.0, 0.148.0...
2 months ago

Changed

  • Sign column migrated to dedicated gutter column — vim mark indicators (az, AZ) now render in a proper CM6 gutter() column instead of using Decoration.line() + CSS ::after overlays. Fixes marks cascading vertically into the wrong line, overlapping on multi-mark lines, and inheriting heading font sizes. The gutter layout from left to right is: sign column → line numbers → fold column → content, matching Neovim's default arrangement. Uses Compartment-based runtime reconfiguration — :set signcolumn=yes/auto/no takes effect without full feature reload. signcolumn=auto now causes layout shift when marks appear/disappear (matching Neovim behavior); signcolumn=yes always reserves gutter space. (#59)
    • Plugin: src/vim/sign-column.ts (rewritten: gutter() + GutterMarker + Compartment), src/vim/mark-gutter.ts (updated re-exports), src/main.ts (unconditional registration, reconfigureSignColumnGutter()), src/settings.ts (removed from RELOAD_KEYS, dedicated handlers in both settings panels, enableMarkGutter deprecated), src/vimrc/loader.ts (markgutter mapped to signcolumn via sideEffect), styles.css (gutter element styles replacing ::after overlay)
  • enableMarkGutter setting deprecated — the boolean enableMarkGutter property is now optional with @deprecated JSDoc. Existing settings are auto-migrated to signcolumn via settings-migration.ts. The property is kept in the interface for migration type safety only.

Added

  • Dual line number display — new linenumbermode option (hybrid/dual/dual-rel-abs) shows absolute and relative line numbers in separate side-by-side gutter columns. set number relativenumber linenumbermode=dual renders absolute on the left, relative on the right (configurable via dual-rel-abs for the reverse). The default hybrid mode is unchanged — existing configs are fully backward compatible. Auto-disabled on mobile viewports (≤600px, falls back to hybrid). Configurable via Settings UI dropdown, set linenumbermode=dual (alias lnm) in vimrc, or vim.opt.linenumbermode = "dual" in Lua.
    • Plugin: src/vim/line-number-gutter.ts (dual compartments, resolveGutters()), src/vim/options.ts (linenumbermode option), src/settings.ts (setting + UI dropdown), src/vimrc/loader.ts (linenumbermode/lnm), src/main.ts (pass linenumbermode to extension creation/reconfiguration)
  • Global vs local mark color differentiation — global marks (AZ) render in --text-muted color, local marks (az) render in --text-accent. The first character of the label determines the CSS class (.vim-motions-sign-marker-global or .vim-motions-sign-marker-local).
    • Plugin: src/vim/sign-column.ts (SignMarker.toDOM() case detection), styles.css
  • Click-to-navigate on mark labels — clicking a mark label in the sign column gutter moves the cursor to that line. Uses domEventHandlers.click on the gutter, querying the signColumnField RangeSet for markers at the clicked line.
    • Plugin: src/vim/sign-column.ts (domEventHandlers.click)
  • signcolumn width modessigncolumn now accepts auto:N and yes:N syntax (N = 1–4) to control sign column character width. set signcolumn=auto:3 reserves 3 character slots when marks exist. set signcolumn=yes:2 always reserves 2 character slots. Validation via regex; invalid values silently rejected.
    • Plugin: src/vim/sign-column.ts (parseSignColumnMode(), isValidSignColumnValue()), src/vim/options.ts (validation), src/settings.ts (type widened to string), src/vimrc/loader.ts (removed validValues)
  • statuscolumn API — Neovim-compatible statuscolumn option for user-configurable gutter layout. A format string controls which gutter segments appear and in what order: %l (line number), %r (relative number), %s (sign column marks), %C (fold indicators), %= (separator), and literal text. When set, the unified gutter replaces all individual gutter columns. When empty (default), individual signcolumn/number/relativenumber/foldcolumn settings manage gutters independently. Configurable via vim.opt.statuscolumn = "%s %l %r %C" in Lua or set statuscolumn (alias stc) in vimrc. Click handlers on sign and fold segments preserved. linenumbermode deprecated — dual maps to statuscolumn = "%l %r". (#59)
    • Plugin: src/vim/statuscolumn.ts (new: parser, composite StatusColumnMarker, unified gutter, StatusColumnSpacer), src/vim/sign-column.ts (signColumnField extracted as standalone extension, SignMarker.label public), src/vim/line-number-gutter.ts (computeLineNumber + getNumberwidth exported), src/vim/mark-gutter.ts (re-exports signColumnFieldExtension), src/vim/options.ts (statuscolumn option), src/settings.ts (statuscolumn setting), src/vimrc/loader.ts (statuscolumn/stc), src/main.ts (standalone signColumnField registration, statusColumnCompartment, reconfigureStatusColumnGutter()), styles.css (statuscolumn segment styles)

Fixed

  • Status bar vim mode duplication — the vim mode indicator and chord display were duplicated in the status bar when the plugin had a non-default clipboard or textwidth setting saved. The settings restoration loop during onload() (lines 717-739 of main.ts, added in v0.53.0 by commit 947c6a7) called applySettingOverridereloadFeatures() before onload() had created its own VimModeTracker and GlobalKeyHandler. reloadFeatures() created these resources, then onload() overwrote this.modeTracker and this.globalKeyHandler with new instances — without destroying the first ones. The orphaned VimModeTracker left duplicate addStatusBarItem() DOM elements in the status bar, and the orphaned GlobalKeyHandler left a duplicate keydown listener on the document (causing intermittent leader key failures). Fixed by adding an initializing phase guard to applySettingOverride — all 6 side-effect branches (5 gutter reconfigurations + reloadFeatures()) are suppressed during onload(), matching the existing vimrcLoading/luaLoading guard pattern. Settings mutations to this.settings still apply immediately; only premature side effects are blocked. (#63)
    • Plugin: src/main.ts (initializing flag, 6 guard site updates in applySettingOverride)
  • iterateEditorViews crash on non-editor leavesreconfigureLineNumberGutter() and other gutter reconfigure methods could throw view.dispatch is not a function on leaves where the CM6 EditorView chain resolved to a non-EditorView object. Fixed by adding a typeof cm.dispatch === 'function' guard in iterateEditorViews.
    • Plugin: src/main.ts (iterateEditorViews type guard)

Tests

  • 10 e2e tests in test/specs/marks-gutter.e2e.ts (4 new, 6 updated): mark in gutter, mark move, multiple marks, delmarks removal, no marks = empty, dedicated gutter column, no line overlays, ellipsis truncation (4+ marks), consistent font size on headings, no data-vim-marks attribute
  • 4 e2e tests in test/specs/statuscolumn.e2e.ts: no statuscolumn by default, option registered in vim engine, sign column gutter present, mark gutter functionality preserved

Documentation

  • docs/features/marks.md: rewritten gutter indicators section — dedicated gutter column, fixed font size, truncation, three-mode table, gutter layout order
  • docs/configuration/settings.md: updated sign column description, added gutter layout tip with ASCII art example
  • docs/configuration/lua-config.md: expanded hybrid line numbers tip with gutter layout example
  • KNOWN_LIMITATIONS.md: updated signcolumn section — removed zero-width overlay note, updated behavior description
  • README.md: updated marks feature description

Full Changelog: 0.54.0...0.55.0

Don't miss a new motions release

NewReleases is sending notifications on new releases.