Skip to content

Add Vim-style word boundaries to evil-ghostel - #661

Merged
dakra merged 1 commit into
mainfrom
feat/evil-vim-word-boundaries
Aug 30, 2026
Merged

dakra merged 1 commit into
mainfrom
feat/evil-vim-word-boundaries

Conversation

@dakra

@dakra dakra commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

While evil-ghostel-mode is on, install a syntax table matching Vim's default iskeyword (letters, digits, _ are word constituents) so w/b/e/ciw stop at path components (bar in ~/src/foo/bar.txt) instead of treating the whole path as one word. Disabling the mode restores the previously active table; W/ciW WORD motions are whitespace-based and unaffected.

  • New option evil-ghostel-word-boundaries (string of boundary characters; nil keeps ghostel's path-aware ghostel-mode-syntax-table). Global-only; live setopt/customize propagates to open buffers.
  • evil-ghostel-syntax-table is a child of ghostel-mode-syntax-table: printable ASCII is set explicitly to w/. (preserving the no-paren/quote-syntax invariant that keeps mouse-start-end away from forward-sexp), non-ASCII inherits from the core table, so │ and other non-ASCII boundaries keep working.
  • Core: ghostel--realize-word-boundaries (table boundary-string) extracted from ghostel--rebuild-mode-syntax-table and made stateless — non-ASCII entries are reset to inherit before each realize, so a boundary char dropped from the string reverts to its inherited syntax.
  • Realization happens at install time, so a plain setq before enabling still yields a correct table; install is guarded on ghostel-mode buffers.
  • Package-Requires floor for ghostel bumped to 0.51.0 (the helper is new there).

Tradeoff, documented in the option docstring, both READMEs, and the changelog: while the mode is on, double-click selects a path component rather than the whole path, and ghostel-word-boundary-string only governs non-ASCII characters in these buffers.

Tests

  • ERT: 10 new evil-ghostel tests (word motion stops, inner-word bounds, WORD unaffected, table shape + safety invariant, install/restore idempotence, non-ghostel-buffer guard, plain-setq realization, opt-out, live customization, non-ASCII inheritance) plus a core test for stale non-ASCII cleanup. make test-evil 142/142, core word-boundary suite 6/6.
  • elate: four new ops in test/elate/matrix/shells.json (ciw-path, b-dw-path, ciW-path, opt-out) — PASS on bash/zsh/fish/nu, and ciw-path/b-dw-path/opt-out fail on main, so they discriminate the feature. New test/elate/matrix/word-boundaries-ghostel.json pins the double-click tradeoff with real mouse events (mode on → component, off → whole path, re-enable → component). Boundary suites on all four shells stay green.

While evil-ghostel-mode is on, install a syntax table matching Vim's
default iskeyword (letters, digits, and underscore are word
constituents) so w/b/e/ciw stop at path components instead of treating
a whole path as one word.  Configurable via the new
evil-ghostel-word-boundaries option; nil keeps ghostel's path-aware
table.  Disabling the mode restores the previously active table.

The table is a child of ghostel-mode-syntax-table realized through a
ghostel--realize-word-boundaries helper extracted from the core
rebuild function, so non-ASCII boundary chars keep inheriting from the
core table and live customization propagates to open buffers.
@dakra
dakra force-pushed the feat/evil-vim-word-boundaries branch from 4f5740c to 1206070 Compare August 30, 2026 22:02
@dakra
dakra merged commit 1206070 into main Aug 30, 2026
33 checks passed
@dakra
dakra deleted the feat/evil-vim-word-boundaries branch August 30, 2026 22:09
@dakra dakra mentioned this pull request Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant