Function: org-fold-core--fix-folded-region
org-fold-core--fix-folded-region is a byte-compiled function defined
in org-fold-core.el.gz.
Signature
(org-fold-core--fix-folded-region FROM TO _)
Documentation
Process modifications in folded elements within FROM . TO region.
This function intended to be used as one of after-change-functions.
This function does nothing if text the only modification was changing text properties (for the sake of reducing overheads).
If a text was inserted into invisible region, hide the inserted text. If a text was inserted in front/back of the region, hide it according 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.
Source Code
;; Defined in /usr/src/emacs/lisp/org/org-fold-core.el.gz
(defun org-fold-core--fix-folded-region (from to _)
"Process modifications in folded elements within FROM . TO region.
This function intended to be used as one of `after-change-functions'.
This function does nothing if text the only modification was changing
text properties (for the sake of reducing overheads).
If a text was inserted into invisible region, hide the inserted text.
If a text was inserted in front/back of the region, hide it according
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 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.
;; 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,
;; for example, when there was a deletion in a folded
;; heading, the heading was unfolded, end `undo' was
;; called. The `undo' would insert the folded text.
(when (and (or (eq from (point-min))
(not (org-fold-core-folded-p (1- from) spec)))
(or (eq to (point-max))
(not (org-fold-core-folded-p to spec)))
(org-fold-core-region-folded-p from to spec))
(org-fold-core-region from to nil spec))
;; Look around and fold the new text if the nearby folds are
;; sticky.
(unless (org-fold-core-region-folded-p from to spec)
(let ((spec-to (org-fold-core-get-folding-spec spec (min to (1- (point-max)))))
(spec-from (org-fold-core-get-folding-spec spec (max (point-min) (1- from)))))
;; Reveal folds around undone deletion.
(when undo-in-progress
(let ((lregion (org-fold-core-get-region-at-point spec (max (point-min) (1- from))))
(rregion (org-fold-core-get-region-at-point spec (min to (1- (point-max))))))
(if (and lregion rregion)
(org-fold-core-region (car lregion) (cdr rregion) nil spec)
(when lregion
(org-fold-core-region (car lregion) (cdr lregion) nil spec))
(when rregion
(org-fold-core-region (car rregion) (cdr rregion) nil spec)))))
;; Hide text inserted in the middle of a fold.
(when (and (or spec-from (eq from (point-min)))
(or spec-to (eq to (point-max)))
(or spec-from spec-to)
(eq spec-to spec-from)
(or (org-fold-core-get-folding-spec-property spec :front-sticky)
(org-fold-core-get-folding-spec-property spec :rear-sticky)))
(unless (and (eq from (point-min)) (eq to (point-max))) ; Buffer content replaced.
(org-fold-core-region from to t (or spec-from spec-to))))
;; Hide text inserted at the end of a fold.
(when (and spec-from (org-fold-core-get-folding-spec-property spec-from :rear-sticky))
(org-fold-core-region from to t spec-from))
;; Hide text inserted in front of a fold.
(when (and spec-to
(not (eq to (point-max))) ; Text inserted at the end of buffer is not prepended anywhere.
(org-fold-core-get-folding-spec-property spec-to :front-sticky))
(org-fold-core-region from to t spec-to))))))))
;; Process all the folded text between `from' and `to'. Do it
;; only in current buffer to avoid verifying semantic structure
;; multiple times in indirect buffers that have exactly same
;; text anyway.
(unless (or org-fold-core--ignore-fragility-checks
(memql 'ignore-fragility-checks org-fold-core--optimise-for-huge-buffers))
(dolist (func org-fold-core-extend-changed-region-functions)
(let ((new-region (funcall func from to)))
(setq from (car new-region))
(setq to (cdr new-region))))
(org-fold-core-cycle-over-indirect-buffers
(dolist (spec (org-fold-core-folding-spec-list))
;; No action is needed when :fragile is nil for the spec.
(when (org-fold-core-get-folding-spec-property spec :fragile)
(org-with-wide-buffer
;; Expand the considered region to include partially present fold.
;; Note: It is important to do this inside loop over all
;; specs. Otherwise, the region may be expanded to huge
;; outline fold, potentially involving majority of the
;; buffer. That would cause the below code to loop over
;; almost all the folds in buffer, which would be too slow.
(let ((local-from from)
(local-to to)
(region-from (org-fold-core-get-region-at-point spec (max (point-min) (1- from))))
(region-to (org-fold-core-get-region-at-point spec (min to (1- (point-max))))))
(when region-from (setq local-from (car region-from)))
(when region-to (setq local-to (cdr region-to)))
(let ((pos local-from))
;; Move to the first hidden region.
(unless (org-fold-core-get-folding-spec spec pos)
(setq pos (org-fold-core-next-folding-state-change spec pos local-to)))
;; Cycle over all the folds.
(while (< pos local-to)
(save-match-data ; we should not clobber match-data in after-change-functions
(let ((fold-begin (and (org-fold-core-get-folding-spec spec pos)
pos))
(fold-end (org-fold-core-next-folding-state-change spec pos local-to)))
(when (and fold-begin fold-end)
(when (save-excursion
(funcall (org-fold-core-get-folding-spec-property spec :fragile)
(cons fold-begin fold-end)
spec))
;; Reveal completely, not just from the SPEC.
(org-fold-core-region fold-begin fold-end nil)))))
;; Move to next fold.
(setq pos (org-fold-core-next-folding-state-change spec pos local-to)))))))))))))