Skip to content

Always leave read-only mode on exit; keep evil insert out of it - #716

Merged
dakra merged 1 commit into
mainfrom
fix/evil-insert-readonly
Sep 30, 2026
Merged

dakra merged 1 commit into
mainfrom
fix/evil-insert-readonly

Conversation

@dakra

@dakra dakra commented Sep 30, 2026

Copy link
Copy Markdown
Owner

Fixes #715.

Core

ghostel-readonly-exit always leaves read-only mode. Switching between copy and Emacs mode keeps the mode active before the first read-only entry, so Emacs → copy → exit lands in semi-char (or char), not back in Emacs mode. A key typed in copy mode entered from Emacs mode now reaches the terminal instead of being dropped by the fast-exit handler.

ghostel--cursor-row-input-start holds the cursor-row prompt detection (OSC 133 prop, then ghostel-prompt-regexp) previously duplicated in ghostel-input-start-point and line mode's startup check.

ghostel-prompt-navigation-input-mode accepts nil.

evil-ghostel

  • Entering insert state from copy or Emacs mode exits to the terminal. Point's column on the cursor row is kept and clamped to the input start after a detected prompt; off the row, point lands on the cursor. Emacs state (C-z) keeps copy mode.
  • In normal and motion state, ghostel-prompt-navigation-input-mode and ghostel-point-leave-input-mode are nil buffer-locally, so [[ / ]], / search, and minibuffer landings stay in semi-char, where the terminal-aware j / G / i / a work. Insert and Emacs state keep ghostel's default copy-mode switch.

Note on the issue's diagnosis: under emacs -Q the fast-exit remap still fires in insert state, so the "every key is read-only" symptom depends on the user's config (or ghostel-readonly-fast-exit nil). Insert state in a read-only buffer is wrong either way.

Testing

  • make -j8 all passes; new ERT tests run in CI's module-less test-evil job and fail without the fix.
  • New elate suites test/elate/matrix/readonly-evil-ghostel.json and readonly-ghostel.json (zsh) pass every group.
  • Existing elate matrix (shells ×4, python3, boundary ×4, tracking, word-boundaries, scrollback, kitty) shows no regressions. ~ XPASSes on every shell on main as well (it no longer signals read-only, but the edit still does not land); P on nu XPASSes on this branch.

Exiting copy or Emacs mode now returns to the last mode that was not
read-only, even after switching between the two.  A key typed in copy
mode entered from Emacs mode reaches the terminal instead of being
dropped.

evil-ghostel: entering insert state from copy or Emacs mode exits to
the terminal and keeps point's column on the cursor row, clamped to
the input start after a detected prompt.  In normal and motion state,
ghostel-prompt-navigation-input-mode and ghostel-point-leave-input-mode
are nil buffer-locally, so prompt jumps and search / minibuffer
landings stay in semi-char where the terminal-aware j / G / i / a
work.  Other states keep ghostel's switches.  The navigation option
gains a nil choice.

ghostel--cursor-row-input-start holds the cursor-row prompt detection
shared by ghostel-input-start-point, line mode's startup entry, and
the evil clamp.

New elate suites cover read-only modes with and without evil.

Fixes #715.
@dakra
dakra force-pushed the fix/evil-insert-readonly branch from 3f58fbb to f1860ff Compare September 30, 2026 07:52
@dakra
dakra merged commit f1860ff into main Sep 30, 2026
35 of 36 checks passed
@dakra
dakra deleted the fix/evil-insert-readonly branch September 30, 2026 08:11

This branch was successfully deployed

1 active deployment
github-pages — f1860ff4 Deployed Sep 30, 2026 by dakra via deploy #207
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.

evil-ghostel: insert state after a prompt jump lands in a read-only buffer

1 participant