From 7b3b7b92e784c86c4ada1150d6e17a510b5ea3d0 Mon Sep 17 00:00:00 2001 From: Ihor Radchenko Date: Thu, 15 Jun 2023 12:19:52 +0300 Subject: [PATCH] org-fold-core: Try harder to reduce overheads * lisp/org-fold-core.el (org-fold-core-cycle-over-indirect-buffers): Clear folds from killed indirect buffers once only. Avoid calling `remove-text-properties' when there is nothing to remove. * lisp/org-fold-core.el (org-fold-core--fix-folded-region): Ignore deletions more aggressively, avoiding the calls to `org-fold-core-cycle-over-indirect-buffers'. --- lisp/org-fold-core.el | 58 ++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/lisp/org-fold-core.el b/lisp/org-fold-core.el index 027ff9215..6c17b00fa 100644 --- a/lisp/org-fold-core.el +++ b/lisp/org-fold-core.el @@ -502,26 +502,34 @@ hanging around." ;; different buffer. This can happen, for example, when ;; org-capture copies local variables into *Capture* buffer. (setq buffers (list (current-buffer))) - (dolist (buf (cons (or (buffer-base-buffer) (current-buffer)) - (buffer-local-value 'org-fold-core--indirect-buffers (or (buffer-base-buffer) (current-buffer))))) - (if (buffer-live-p buf) - (push buf buffers) - (dolist (spec (org-fold-core-folding-spec-list)) - (when (and (not (org-fold-core-get-folding-spec-property spec :global)) - (gethash (cons buf spec) org-fold-core--property-symbol-cache)) - ;; Make sure that dead-properties variable can be passed - ;; as argument to `remove-text-properties'. - (push t dead-properties) - (push (gethash (cons buf spec) org-fold-core--property-symbol-cache) - dead-properties)))))) + (let ((all-buffers (buffer-local-value + 'org-fold-core--indirect-buffers + (or (buffer-base-buffer) (current-buffer))))) + (dolist (buf (cons (or (buffer-base-buffer) (current-buffer)) + (buffer-local-value 'org-fold-core--indirect-buffers (or (buffer-base-buffer) (current-buffer))))) + (if (buffer-live-p buf) + (push buf buffers) + (dolist (spec (org-fold-core-folding-spec-list)) + (when (and (not (org-fold-core-get-folding-spec-property spec :global)) + (gethash (cons buf spec) org-fold-core--property-symbol-cache)) + ;; Make sure that dead-properties variable can be passed + ;; as argument to `remove-text-properties'. + (push t dead-properties) + (push (gethash (cons buf spec) org-fold-core--property-symbol-cache) + dead-properties))))) + (when dead-properties + (with-current-buffer (or (buffer-base-buffer) (current-buffer)) + (setq-local org-fold-core--indirect-buffers + (seq-filter #'buffer-live-p all-buffers)))))) (dolist (buf buffers) (with-current-buffer buf - (with-silent-modifications - (save-restriction - (widen) - (remove-text-properties - (point-min) (point-max) - dead-properties))) + (when dead-properties + (with-silent-modifications + (save-restriction + (widen) + (remove-text-properties + (point-min) (point-max) + dead-properties)))) ,@body)))) ;; This is the core function used to fold text in buffers. We use @@ -1277,19 +1285,19 @@ to :front-sticky/:rear-sticky folding spec property. If the folded region is folded with a spec with non-nil :fragile property, unfold the region if the :fragile function returns non-nil." ;; If no insertions or deletions in buffer, skip all the checks. - (unless (or (eq org-fold-core--last-buffer-chars-modified-tick (buffer-chars-modified-tick)) - org-fold-core--ignore-modifications + (unless (or org-fold-core--ignore-modifications + (eq org-fold-core--last-buffer-chars-modified-tick (buffer-chars-modified-tick)) (memql 'ignore-modification-checks org-fold-core--optimise-for-huge-buffers)) ;; Store the new buffer modification state. (setq org-fold-core--last-buffer-chars-modified-tick (buffer-chars-modified-tick)) (save-match-data ;; Handle changes in all the indirect buffers and in the base ;; buffer. Work around Emacs bug#46982. - (when (eq org-fold-core-style 'text-properties) - (org-fold-core-cycle-over-indirect-buffers - ;; Re-hide text inserted in the middle/front/back of a folded - ;; region. - (unless (equal from to) ; Ignore deletions. + ;; Re-hide text inserted in the middle/front/back of a folded + ;; region. + (unless (equal from to) ; Ignore deletions. + (when (eq org-fold-core-style 'text-properties) + (org-fold-core-cycle-over-indirect-buffers (dolist (spec (org-fold-core-folding-spec-list)) ;; Reveal fully invisible text inserted in the middle ;; of visible portion of the buffer. This is needed,