Skip to content

Instantly share code, notes, and snippets.

@xenodium
Created August 7, 2026 09:43
Show Gist options
  • Select an option

  • Save xenodium/48a218f69afbd11d6471cca5720f5f4b to your computer and use it in GitHub Desktop.

Select an option

Save xenodium/48a218f69afbd11d6471cca5720f5f4b to your computer and use it in GitHub Desktop.
;;; repro-719.el --- Minimal reproducer for agent-shell #719 -*- lexical-binding: t; -*-
;; Maybe isolates the hang reported in
;; https://github.com/xenodium/agent-shell/issues/719 down to a single
;; overlay whose `before-string'/`display' strings contain embedded
;; newlines. No agent-shell (or any package) required.
;;
;; Run in a THROWAWAY Emacs -- this may hang the session:
;;
;; emacs -Q -l repro-719.el
;;
;; Two commands are provided:
;;
;; M-x repro-719-buggy -- overlay with newline-laden display strings,
;; mirroring agent-shell's "changes" hunk box.
;; M-x repro-719-safe -- same label rendered without embedded newlines.
;;
;; In each buffer point starts on the overlay line near the top. Press
;; <up> (previous-line) a few times, or scroll up. On the affected
;; builds (seen on Emacs 31), `repro-719-buggy' hangs in
;; `move_it_vertically_backward'; `repro-719-safe' does not. Use C-x C-c
;; to quit, or kill the process if it hangs.
;;; Code:
(defun repro-719--make-buffer (name setup)
"Create buffer NAME with filler text and run SETUP on the @@ line.
SETUP receives the overlay covering the `@@' line."
(let ((buffer (get-buffer-create name)))
(with-current-buffer buffer
(erase-buffer)
;; A couple of lines above so there is somewhere to scroll up into.
(insert "top of buffer\n")
(insert "context line\n")
(let ((hunk-start (point)))
(insert "@@ -1,4 +1,4 @@\n")
(dotimes (i 400)
(insert (format " unchanged line %d\n" i)))
(goto-char hunk-start)
(let ((overlay (make-overlay (line-beginning-position)
(line-end-position))))
(funcall setup overlay)))
(setq buffer-read-only t)
(goto-char (point-min))
(forward-line 2)) ; land on the overlay line
(pop-to-buffer buffer)
(message "Press <up> a few times (or scroll up). See top of repro-719.el.")))
(defun repro-719-buggy ()
"Reproduce the hang: overlay strings with embedded newlines."
(interactive)
(repro-719--make-buffer
"*repro-719-buggy*"
(lambda (overlay)
(overlay-put overlay 'before-string
(propertize "\n╭─────────╮\n" 'face 'diff-hunk-header))
(overlay-put overlay 'display
(propertize "│ changes │\n╰─────────╯\n\n"
'face 'diff-hunk-header)))))
(defun repro-719-safe ()
"Control: same label, single line, no embedded newlines."
(interactive)
(repro-719--make-buffer
"*repro-719-safe*"
(lambda (overlay)
(overlay-put overlay 'display
(propertize " changes "
'face '(:inherit diff-hunk-header :box t))))))
(repro-719-buggy)
(provide 'repro-719)
;;; repro-719.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment