From: David Ponce via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 72689@debbugs.gnu.org
Subject: bug#72689: 31.0.50; Proposal to improve string-pixel-width
Date: Mon, 19 Aug 2024 10:49:05 +0200 [thread overview]
Message-ID: <fbde3e7d-a780-41cd-8108-6afa5cba57f7@orange.fr> (raw)
In-Reply-To: <8634n219b1.fsf@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 516 bytes --]
On 18/08/2024 11:15 AM, Eli Zaretskii wrote:
[...]> I think you understood the issue, and just creating a new buffer if
> the "normal" one is "taken" should be good enough. I don't expect
> this situation to be a frequent one, so creating too many buffers
> should not be a danger.
Thanks! Please, find attached a revised V01 patch that implements
your suggestion. I finally opted to keep only one function,
because setting a few buffer-local variables on each call has not a
significant impact on performance.
[-- Attachment #2: improve-string-pixel-width-V01.patch --]
[-- Type: text/x-patch, Size: 3914 bytes --]
2024-08-19 David Ponce <da_vid@orange.fr>
Tweak the implementation of string-pixel-width to run faster and
use less memory. Also cater for the case where more than one
execution thread calls the function (bug#72689).
* subr-x.el (string--pixel-width-buffer): New variable.
(string--pixel-width): Use it. Create a new working buffer when
parallel run is detected. Prefer `remove-text-properties' to
`propertize' to avoid creating a new string on each call.
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index 058c06bc5f6..b688d179da4 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -336,6 +336,8 @@ named-let
(cl-labels ((,name ,fargs . ,body)) #',name)
. ,aargs)))
+(defvar string--pixel-width-buffer nil)
+
;;;###autoload
(defun string-pixel-width (string &optional buffer)
"Return the width of STRING in pixels.
@@ -346,21 +348,45 @@ string-pixel-width
0
;; Keeping a work buffer around is more efficient than creating a
;; new temporary buffer.
- (with-current-buffer (get-buffer-create " *string-pixel-width*")
- ;; If `display-line-numbers' is enabled in internal buffers
- ;; (e.g. globally), it breaks width calculation (bug#59311)
- (setq-local display-line-numbers nil)
- (delete-region (point-min) (point-max))
- ;; Disable line-prefix and wrap-prefix, for the same reason.
- (setq line-prefix nil
- wrap-prefix nil)
- (if buffer
- (setq-local face-remapping-alist
- (with-current-buffer buffer
- face-remapping-alist))
- (kill-local-variable 'face-remapping-alist))
- (insert (propertize string 'line-prefix nil 'wrap-prefix nil))
- (car (buffer-text-pixel-size nil nil t)))))
+ (with-current-buffer
+ (or (if (buffer-live-p string--pixel-width-buffer)
+ ;; Check if work buffer is not used by
+ ;; another parallel run (bug#72689). That
+ ;; is, if `string--pixel-width-buffer' has no
+ ;; buffer-local value, in which case the function
+ ;; `buffer-local-value' returns its global value,
+ ;; equal to the work buffer. Otherwise, when the
+ ;; work buffer is "busy", the buffer-local value of
+ ;; `string--pixel-width-buffer' is nil.
+ (buffer-local-value 'string--pixel-width-buffer
+ string--pixel-width-buffer))
+ ;; Create a new work buffer if current is "busy".
+ (setq string--pixel-width-buffer
+ (generate-new-buffer " *string-pixel-width*" t)))
+ ;; Mark buffer as "busy".
+ (setq-local string--pixel-width-buffer nil)
+ (unwind-protect
+ (progn
+ ;; If `display-line-numbers' is enabled in internal
+ ;; buffers (e.g. globally), it breaks width calculation
+ ;; (bug#59311). Disable `line-prefix' and `wrap-prefix',
+ ;; for the same reason.
+ (setq display-line-numbers nil
+ line-prefix nil wrap-prefix nil)
+ (if buffer
+ (setq-local face-remapping-alist
+ (with-current-buffer buffer
+ face-remapping-alist))
+ (kill-local-variable 'face-remapping-alist))
+ (erase-buffer)
+ (insert string)
+ ;; Prefer `remove-text-properties' to `propertize' to avoid
+ ;; creating a new string on each call.
+ (remove-text-properties
+ (point-min) (point-max) '(line-prefix nil wrap-prefix nil))
+ (car (buffer-text-pixel-size nil nil t)))
+ ;; Mark buffer as free to use.
+ (kill-local-variable 'string--pixel-width-buffer)))))
;;;###autoload
(defun string-glyph-split (string)
next prev parent reply other threads:[~2024-08-19 8:49 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-17 22:03 bug#72689: 31.0.50; Proposal to improve string-pixel-width David Ponce via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 4:40 ` Eli Zaretskii
2024-08-18 6:05 ` David Ponce via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 9:15 ` Eli Zaretskii
2024-08-19 8:49 ` David Ponce via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2024-08-20 15:12 ` David Ponce via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-21 13:17 ` Eli Zaretskii
2024-08-21 20:43 ` David Ponce via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-22 3:43 ` Eli Zaretskii
2024-08-22 9:48 ` David Ponce via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-22 10:59 ` Eli Zaretskii
2024-08-22 14:56 ` David Ponce via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-23 6:20 ` Juri Linkov
2024-08-23 6:49 ` Eli Zaretskii
2024-08-23 7:23 ` David Ponce via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-31 8:26 ` Eli Zaretskii
2024-08-31 10:51 ` David Ponce via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-31 12:00 ` Eli Zaretskii
2024-08-18 6:12 ` Jim Porter
2024-08-18 7:36 ` David Ponce via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 16:35 ` Jim Porter
2024-08-18 9:23 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fbde3e7d-a780-41cd-8108-6afa5cba57f7@orange.fr \
--to=bug-gnu-emacs@gnu.org \
--cc=72689@debbugs.gnu.org \
--cc=da_vid@orange.fr \
--cc=eliz@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).