Avoid signaling errors from 'pixel-fill-region'

* lisp/textmodes/pixel-fill.el (pixel-fill-region): Make sure the
selected window displays the current buffer.  This is important
when this function is called inside 'with-current-buffer' or
similar forms which temporarily change the buffer displayed in the
selected window.  (Bug#67791)
This commit is contained in:
Eli Zaretskii 2024-02-03 11:09:36 +02:00
parent a398712761
commit d49124fc14

View file

@ -73,39 +73,41 @@ lines that are visually wider than PIXEL-WIDTH.
If START isn't at the start of a line, the horizontal position of If START isn't at the start of a line, the horizontal position of
START, converted to pixel units, will be used as the indentation START, converted to pixel units, will be used as the indentation
prefix on subsequent lines." prefix on subsequent lines."
(save-excursion (save-window-excursion
(goto-char start) (set-window-buffer nil (current-buffer))
(let ((indentation (save-excursion
(car (window-text-pixel-size nil (line-beginning-position) (goto-char start)
(point)))) (let ((indentation
(newline-end nil)) (car (window-text-pixel-size nil (line-beginning-position)
(when (> indentation pixel-width) (point))))
(error "The indentation (%s) is wider than the fill width (%s)" (newline-end nil))
indentation pixel-width)) (when (> indentation pixel-width)
(save-restriction (error "The indentation (%s) is wider than the fill width (%s)"
(narrow-to-region start end) indentation pixel-width))
(goto-char (point-max)) (save-restriction
(when (looking-back "\n[ \t]*" (point-min)) (narrow-to-region start end)
(setq newline-end t)) (goto-char (point-max))
(goto-char (point-min)) (when (looking-back "\n[ \t]*" (point-min))
;; First replace all whitespace with space. (setq newline-end t))
(while (re-search-forward "[ \t\n]+" nil t) (goto-char (point-min))
(cond ;; First replace all whitespace with space.
((or (= (match-beginning 0) start) (while (re-search-forward "[ \t\n]+" nil t)
(= (match-end 0) end)) (cond
(delete-region (match-beginning 0) (match-end 0))) ((or (= (match-beginning 0) start)
;; If there's just a single space here, don't replace. (= (match-end 0) end))
((not (and (= (- (match-end 0) (match-beginning 0)) 1) (delete-region (match-beginning 0) (match-end 0)))
(= (char-after (match-beginning 0)) ?\s))) ;; If there's just a single space here, don't replace.
(replace-match ((not (and (= (- (match-end 0) (match-beginning 0)) 1)
;; We need to use a space that has an appropriate width. (= (char-after (match-beginning 0)) ?\s)))
(propertize " " 'face (replace-match
(get-text-property (match-beginning 0) 'face)))))) ;; We need to use a space that has an appropriate width.
(goto-char start) (propertize " " 'face
(pixel-fill--fill-line pixel-width indentation) (get-text-property (match-beginning 0) 'face))))))
(goto-char (point-max)) (goto-char start)
(when newline-end (pixel-fill--fill-line pixel-width indentation)
(insert "\n")))))) (goto-char (point-max))
(when newline-end
(insert "\n")))))))
(defun pixel-fill--goto-pixel (width) (defun pixel-fill--goto-pixel (width)
(vertical-motion (cons (/ width (frame-char-width)) 0))) (vertical-motion (cons (/ width (frame-char-width)) 0)))