Skip to content

Stop adjustWidth from claiming cursor cells and styled spaces - #678

Merged
emil-e merged 1 commit into
dakra:mainfrom
marcuslannister:fix/adjust-width-protected-spaces
Sep 27, 2026
Merged

emil-e merged 1 commit into
dakra:mainfrom
marcuslannister:fix/adjust-width-protected-spaces

Conversation

@marcuslannister

Copy link
Copy Markdown
Contributor

Problem

adjustWidth hides a following space so a standalone glyph can use two cells.

The function does not check the role of that space. It hides the space when the space is the cursor cell. It also hides the space when the space has visible style.

A reverse-video caret after a box-drawing glyph then loses its cell. The caret and the glyph overlap.

Change

Add followingCellProtected. This function returns true in two cases:

  • The following cell is the cursor cell.
  • The following cell belongs to a styled run.

adjustWidth returns width 1 when followingCellProtected returns true. It does not hide that space. It still claims a following unused space.

The trailing-cell test moves the cursor to the next row. That keeps the trailing cell unused.

Tests

Native glyph tests cover these cases:

  • A standalone icon does not hide the following cursor cell.
  • A standalone icon does not hide a reverse-video space.
  • A standalone icon still claims an unused following space.
  • A standalone icon still claims an unused trailing cell.

marcuslannister added a commit to marcuslannister/emacs.d that referenced this pull request Sep 12, 2026
adjustWidth hides a following space so a standalone glyph can occupy
two cells, but never checked what that space was for. A box-drawing
border before an empty caret therefore stole the caret's cell and the
two rendered on top of each other.

followingCellProtected returns true when the following cell is the
cursor cell or belongs to a styled run; adjustWidth returns width 1 in
that case and leaves the space alone. An unused following space is
still claimed, so the original behaviour is intact everywhere else.

The fix is in Zig and MELPA ships only the Lisp, so it is carried as
patches/ghostel-v0.53.0-protect-cursor-spaces.patch against a
self-built module. init-local-shell.el points ghostel-module-directory
at ghostel-module/ only when a module is actually built there, and
otherwise leaves the variable unset so the stock module is used --
deleting the build is a complete rollback.

docs/ghostel-module.md records the exact Lisp/module pair, the Zig
0.16.0 build, the test command, and the removal criteria.

Submitted upstream as dakra/ghostel#678.
marcuslannister added a commit to marcuslannister/emacs.d that referenced this pull request Sep 12, 2026
"Remove when upstream replaces it" named no ticket, so there was
nothing to watch and the patch would have become permanent by default.
Record dakra/ghostel#678 in the Pair list, beside the Lisp/module/patch
it belongs to, and in the removal criteria.

The criteria stay broader than the PR: upstream may close it in favour
of a different fix, and the patch should still come out in that case.
marcuslannister added a commit to marcuslannister/emacs.d that referenced this pull request Sep 12, 2026
The docs change in 8003518 went in without a changelog line on the
grounds that be01168's entry already cited dakra/ghostel#678. Record
it explicitly instead, so the changelog carries the watch target rather
than leaving it implied by a neighbouring entry.
@dakra
dakra requested a review from emil-e September 18, 2026 22:12
@emil-e
emil-e merged commit eb53ff3 into dakra:main Sep 27, 2026
30 checks passed
@emil-e

emil-e commented Sep 27, 2026

Copy link
Copy Markdown
Collaborator

Thanks!

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.

2 participants