diff options
| author | David Ponce | 2024-08-22 16:56:11 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2024-08-31 11:21:42 +0300 |
| commit | b930a698f2ba4e8b5878a4b604098e1201796b7f (patch) | |
| tree | 4273bddec57e45aed422c55930049f3ff0d54cea | |
| parent | b25da8729dd853e352a147583a7b24699283d4d9 (diff) | |
| download | emacs-b930a698f2ba4e8b5878a4b604098e1201796b7f.tar.gz emacs-b930a698f2ba4e8b5878a4b604098e1201796b7f.zip | |
New macro `with-work-buffer'.
* lisp/emacs-lisp/subr-x.el (work-buffer--list)
(work-buffer-limit): New variables.
(work-buffer--get, work-buffer--release): New function.
(with-work-buffer): New macro. (Bug#72689)
* etc/NEWS: Announce 'with-work-buffer'.
| -rw-r--r-- | etc/NEWS | 7 | ||||
| -rw-r--r-- | lisp/emacs-lisp/subr-x.el | 47 |
2 files changed, 54 insertions, 0 deletions
| @@ -321,6 +321,13 @@ language A. | |||
| 321 | If supplied, 'string-pixel-width' will use any face remappings from | 321 | If supplied, 'string-pixel-width' will use any face remappings from |
| 322 | BUFFER when computing the string's width. | 322 | BUFFER when computing the string's width. |
| 323 | 323 | ||
| 324 | --- | ||
| 325 | *** New macro 'with-work-buffer'. | ||
| 326 | This macro is similar to the already existing macro `with-temp-buffer', | ||
| 327 | except that it does not allocate a new temporary buffer on each call, | ||
| 328 | but tries to reuse those previously allocated (up to a number defined by | ||
| 329 | the new variable `work-buffer-limit', which defaults to 10). | ||
| 330 | |||
| 324 | +++ | 331 | +++ |
| 325 | ** 'date-to-time' now defaults to local time. | 332 | ** 'date-to-time' now defaults to local time. |
| 326 | The function now assumes local time instead of Universal Time when | 333 | The function now assumes local time instead of Universal Time when |
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 058c06bc5f6..3347c802f68 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el | |||
| @@ -336,6 +336,53 @@ This construct can only be used with lexical binding." | |||
| 336 | (cl-labels ((,name ,fargs . ,body)) #',name) | 336 | (cl-labels ((,name ,fargs . ,body)) #',name) |
| 337 | . ,aargs))) | 337 | . ,aargs))) |
| 338 | 338 | ||
| 339 | (defvar work-buffer--list nil) | ||
| 340 | (defvar work-buffer-limit 10 | ||
| 341 | "Maximum number of reusable work buffers. | ||
| 342 | When this limit is exceeded, newly allocated work buffers are | ||
| 343 | automatically killed, which means that in a such case | ||
| 344 | `with-work-buffer' becomes equivalent to `with-temp-buffer'.") | ||
| 345 | |||
| 346 | (defsubst work-buffer--get () | ||
| 347 | "Get a work buffer." | ||
| 348 | (let ((buffer (pop work-buffer--list))) | ||
| 349 | (if (buffer-live-p buffer) | ||
| 350 | buffer | ||
| 351 | (generate-new-buffer " *work*" t)))) | ||
| 352 | |||
| 353 | (defun work-buffer--release (buffer) | ||
| 354 | "Release work BUFFER." | ||
| 355 | (if (buffer-live-p buffer) | ||
| 356 | (with-current-buffer buffer | ||
| 357 | ;; Flush BUFFER before making it available again, i.e. clear | ||
| 358 | ;; its contents, remove all overlays and buffer-local | ||
| 359 | ;; variables. Is it enough to safely reuse the buffer? | ||
| 360 | (erase-buffer) | ||
| 361 | (delete-all-overlays) | ||
| 362 | (let (change-major-mode-hook) | ||
| 363 | (kill-all-local-variables t)) | ||
| 364 | ;; Make the buffer available again. | ||
| 365 | (push buffer work-buffer--list))) | ||
| 366 | ;; If the maximum number of reusable work buffers is exceeded, kill | ||
| 367 | ;; work buffer in excess, taking into account that the limit could | ||
| 368 | ;; have been let-bound to temporarily increase its value. | ||
| 369 | (when (> (length work-buffer--list) work-buffer-limit) | ||
| 370 | (mapc #'kill-buffer (nthcdr work-buffer-limit work-buffer--list)) | ||
| 371 | (setq work-buffer--list (ntake work-buffer-limit work-buffer--list)))) | ||
| 372 | |||
| 373 | ;;;###autoload | ||
| 374 | (defmacro with-work-buffer (&rest body) | ||
| 375 | "Create a work buffer, and evaluate BODY there like `progn'. | ||
| 376 | Like `with-temp-buffer', but reuse an already created temporary | ||
| 377 | buffer when possible, instead of creating a new one on each call." | ||
| 378 | (declare (indent 0) (debug t)) | ||
| 379 | (let ((work-buffer (make-symbol "work-buffer"))) | ||
| 380 | `(let ((,work-buffer (work-buffer--get))) | ||
| 381 | (with-current-buffer ,work-buffer | ||
| 382 | (unwind-protect | ||
| 383 | (progn ,@body) | ||
| 384 | (work-buffer--release ,work-buffer)))))) | ||
| 385 | |||
| 339 | ;;;###autoload | 386 | ;;;###autoload |
| 340 | (defun string-pixel-width (string &optional buffer) | 387 | (defun string-pixel-width (string &optional buffer) |
| 341 | "Return the width of STRING in pixels. | 388 | "Return the width of STRING in pixels. |