Repository navigation
Abort compile finalization when a finish hook kills the buffer - #601
Merged
Merged
Conversation
A compilation-finish-function or a mode hook of the finished major mode may kill the compile buffer mid-finalize (e.g. a popup rule that kills the buffer when its window is deleted). Emacs then quietly makes another buffer current, and the rest of ghostel-compile--finalize would switch that unrelated buffer's major mode, insert the compilation footer into it, and finally signal "No such live buffer" from get-buffer-window-list. Guard every foreign-callback point — each buffer-local finish function, the major-mode switch, and the global compilation-finish-functions run — with ghostel-compile--reenter-or-abort: abort finalization if the buffer died, and re-enter it explicitly in case a callback left another buffer current.
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reported downstream in doomemacs/core#8862: with Doom's
(ghostel +everywhere)and(popup +defaults),doom/reloadinstalled a buffer-localcompilation-finish-functionsentry that deleted the compile popup window, and the popup rule's:ttl 0then killed the compile buffer whileghostel-compile--finalizewas still running.When the current buffer is killed mid-
with-current-buffer, Emacs quietly makes another buffer current, so the rest of finalize operated on an unrelated buffer: it switched that buffer's major mode, inserted theCompilation finished at ...footer into it, and finally signaledNo such live buffer #<killed buffer>fromget-buffer-window-list. Doom no longer closes that window as of doomemacs/core@f6f0769, but any finish function or popup/shackle-style kill-on-window-delete rule can still trigger the same corruption.Fix: a new
ghostel-compile--reenter-or-abortguard runs after every foreign-callback point in finalize — each buffer-local finish function, the(funcall target-mode)mode switch (mode hooks), and the globalcompilation-finish-functionsrun. It aborts finalization if the buffer died and re-enters it explicitly in case a callback left another buffer current. Aborting is safe at all three points: the run is already marked finalized and the terminal torn down before the first callback fires.Most of the
lisp/ghostel-compile.eldiff is a mechanical reindent from the newcatchform; review with whitespace ignored to see the ~25 real lines.Regression tests (plain elisp, no native module) cover all three kill points and assert the victim buffer keeps its major mode and contents, later finish functions don't run against the dead buffer, and no error is signaled. All three fail on
mainwith exactly the reported corruption.