mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2026-09-10 07:46:51 -04:00
Fix 'truncate-string-pixelwise' to restore the window buffer
* lisp/emacs-lisp/subr-x.el (truncate-string-pixelwise): Safely save/restore the selected window's buffer, and not the reference or current buffers. Guard dedicated windows. Remove the work buffer from the window's buffer list. Bind 'buffer-list-update-hook' 'window-scroll-functions' 'window-configuration-change-hook' to nil around the window buffer swap. (Bug#81262; see also bug#80244.)
This commit is contained in:
parent
b684922900
commit
a3a72ae355
|
|
@ -426,42 +426,51 @@ this function using the same ELLIPSIS."
|
|||
string
|
||||
;; Keeping a work buffer around is more efficient than creating a
|
||||
;; new temporary buffer.
|
||||
(let ((original-buffer (or buffer (current-buffer))))
|
||||
(let* ((window (selected-window))
|
||||
(original-buffer (window-buffer window))
|
||||
(window-dedication (window-dedicated-p window))
|
||||
(buffer-list-update-hook)
|
||||
(window-scroll-functions)
|
||||
(window-configuration-change-hook))
|
||||
(with-work-buffer
|
||||
(work-buffer--prepare-pixelwise string buffer)
|
||||
(set-window-buffer nil (current-buffer) 'keep-margins)
|
||||
;; Use a binary search to prune the number of calls to
|
||||
;; `window-text-pixel-size'.
|
||||
;; These are 1-based buffer indexes.
|
||||
(let* ((low 1)
|
||||
(high (1+ (length string)))
|
||||
mid)
|
||||
(when (> (car (window-text-pixel-size nil 1 high)) max-pixels)
|
||||
(when (and ellipsis (not (stringp ellipsis)))
|
||||
(setq ellipsis (truncate-string-ellipsis)))
|
||||
(setq ellipsis-pixels (if ellipsis
|
||||
(if ellipsis-pixels
|
||||
ellipsis-pixels
|
||||
(string-pixel-width ellipsis buffer))
|
||||
0))
|
||||
(let ((adjusted-pixels
|
||||
(if (> max-pixels ellipsis-pixels)
|
||||
(- max-pixels ellipsis-pixels)
|
||||
max-pixels)))
|
||||
(while (<= low high)
|
||||
(setq mid (floor (+ low high) 2))
|
||||
(if (<= (car (window-text-pixel-size nil 1 mid))
|
||||
adjusted-pixels)
|
||||
(setq low (1+ mid))
|
||||
(setq high (1- mid))))))
|
||||
(set-window-buffer nil original-buffer 'keep-margins)
|
||||
(if mid
|
||||
;; Binary search ran.
|
||||
(if (and ellipsis (> max-pixels ellipsis-pixels))
|
||||
(concat (substring string 0 (1- high)) ellipsis)
|
||||
(substring string 0 (1- high)))
|
||||
;; Fast path.
|
||||
string))))))
|
||||
;; Use a binary search to prune the number of calls to
|
||||
;; `window-text-pixel-size'.
|
||||
;; These are 1-based buffer indexes.
|
||||
(unwind-protect
|
||||
(let* ((low 1)
|
||||
(high (1+ (length string)))
|
||||
mid)
|
||||
(work-buffer--prepare-pixelwise string buffer)
|
||||
(set-window-dedicated-p window nil)
|
||||
(set-window-buffer window (current-buffer) 'keep-margins)
|
||||
(when (> (car (window-text-pixel-size nil 1 high)) max-pixels)
|
||||
(when (and ellipsis (not (stringp ellipsis)))
|
||||
(setq ellipsis (truncate-string-ellipsis)))
|
||||
(setq ellipsis-pixels (if ellipsis
|
||||
(if ellipsis-pixels
|
||||
ellipsis-pixels
|
||||
(string-pixel-width ellipsis buffer))
|
||||
0))
|
||||
(let ((adjusted-pixels
|
||||
(if (> max-pixels ellipsis-pixels)
|
||||
(- max-pixels ellipsis-pixels)
|
||||
max-pixels)))
|
||||
(while (<= low high)
|
||||
(setq mid (floor (+ low high) 2))
|
||||
(if (<= (car (window-text-pixel-size nil 1 mid))
|
||||
adjusted-pixels)
|
||||
(setq low (1+ mid))
|
||||
(setq high (1- mid))))))
|
||||
(if mid
|
||||
;; Binary search ran.
|
||||
(if (and ellipsis (> max-pixels ellipsis-pixels))
|
||||
(concat (substring string 0 (1- high)) ellipsis)
|
||||
(substring string 0 (1- high)))
|
||||
;; Fast path.
|
||||
string))
|
||||
(set-window-buffer window original-buffer 'keep-margins)
|
||||
(set-window-dedicated-p window window-dedication)
|
||||
(unrecord-window-buffer window (current-buffer) t))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun string-glyph-split (string)
|
||||
|
|
|
|||
Loading…
Reference in a new issue