Function: org-element--cache-for-removal

org-element--cache-for-removal is a byte-compiled function defined in org-element.el.gz.

Signature

(org-element--cache-for-removal BEG END OFFSET)

Documentation

Return first element to remove from cache.

BEG and END are buffer positions delimiting buffer modifications. OFFSET is the size of the changes.

Returned element is usually the first element in cache containing any position between BEG and END. As an exception, greater elements around the changes that are robust to contents modifications are preserved and updated according to the changes. In the latter case, the returned element is the outermost non-robust element affected by the changes. Note that the returned element may end before END position in which case some cached element starting after the returned may still be affected by the changes.

Also, when there are no elements in cache before BEG, return first known element in cache (it may start after END).

Source Code

;; Defined in /usr/src/emacs/lisp/org/org-element.el.gz
(defun org-element--cache-for-removal (beg end offset)
  "Return first element to remove from cache.

BEG and END are buffer positions delimiting buffer modifications.
OFFSET is the size of the changes.

Returned element is usually the first element in cache containing
any position between BEG and END.  As an exception, greater
elements around the changes that are robust to contents
modifications are preserved and updated according to the
changes.  In the latter case, the returned element is the outermost
non-robust element affected by the changes.  Note that the returned
element may end before END position in which case some cached element
starting after the returned may still be affected by the changes.

Also, when there are no elements in cache before BEG, return first
known element in cache (it may start after END)."
  (let* ((elements (org-element--cache-find (1- beg) 'both))
	 (before (car elements))
	 (after (cdr elements)))
    (if (not before) after
      ;; If BEFORE is a keyword, it may need to be removed to become
      ;; an affiliated keyword.
      (when (eq 'keyword (org-element-type before))
        (let ((prev before))
          (while (eq 'keyword (org-element-type prev))
            (setq before prev
                  beg (org-element-property :begin prev))
            (setq prev (org-element--cache-find (1- (org-element-property :begin before)))))))
      (let ((up before)
	    (robust-flag t))
	(while up
	  (if (let ((type (org-element-type up)))
                (or (and (memq type '( center-block dynamic-block
                                       quote-block special-block
                                       drawer))
                         (or (not (eq type 'drawer))
                             (not (string= "PROPERTIES" (org-element-property :drawer-name up))))
                         ;; Sensitive change.  This is
                         ;; unconditionally non-robust change.
                         (not org-element--cache-change-warning)
                         (let ((cbeg (org-element-property :contents-begin up))
                               (cend (org-element-property :contents-end up)))
                           (and cbeg
                                (<= cbeg beg)
                                (or (> cend end)
                                    (and (= cend end)
                                         (= (+ end offset) (point-max)))))))
                    (and (memq type '(headline section org-data))
                         (let ((rbeg (org-element-property :robust-begin up))
                               (rend (org-element-property :robust-end up)))
                           (and rbeg rend
                                (<= rbeg beg)
                                (or (> rend end)
                                    (and (= rend end)
                                         (= (+ end offset) (point-max))))))
                         (pcase type
                           ;; Sensitive change in section.  Need to
                           ;; re-parse.
                           (`section (not org-element--cache-change-warning))
                           ;; Headline might be inserted.  This is non-robust
                           ;; change when `up' is a `headline' or `section'
                           ;; with `>' level compared to the inserted headline.
                           ;;
                           ;; Also, planning info/property drawer
                           ;; could have been inserted.  It is not
                           ;; robust change then.
                           (`headline
                            (and
                             (or (not (numberp org-element--cache-change-warning))
                                 (> org-element--cache-change-warning
                                    (org-element-property :level up)))
                             (org-with-point-at (org-element-property :contents-begin up)
                               (unless
                                   (save-match-data
                                     (when (looking-at-p org-element-planning-line-re)
                                       (forward-line))
                                     (when (looking-at org-property-drawer-re)
                                       (< beg (match-end 0))))
                                 'robust))))
                           (`org-data (and (not (eq org-element--cache-change-warning 'org-data))
                                           ;; Property drawer could
                                           ;; have been inserted.  It
                                           ;; is not robust change
                                           ;; then.
                                           (org-with-wide-buffer
                                            (goto-char (point-min))
                                            (while (and (org-at-comment-p) (bolp)) (forward-line))
                                            ;; Should not see property
                                            ;; drawer within changed
                                            ;; region.
                                            (save-match-data
                                              (or (not (looking-at org-property-drawer-re))
                                                  (> beg (match-end 0)))))))
                           (_ 'robust)))))
	      ;; UP is a robust greater element containing changes.
	      ;; We only need to extend its ending boundaries.
              (progn
                (org-element--cache-shift-positions
                 up offset
                 (if (and (org-element-property :robust-begin up)
                          (org-element-property :robust-end up))
                     '(:contents-end :end :robust-end)
                   '(:contents-end :end)))
                (org-element--cache-log-message
                 "Shifting end positions of robust parent: %S"
                 (org-element--format-element up)))
            (unless (or
                     ;; UP is non-robust.  Yet, if UP is headline, flagging
                     ;; everything inside for removal may be to
                     ;; costly.  Instead, we should better re-parse only the
                     ;; headline itself when possible.  If a headline is still
                     ;; starting from old :begin position, we do not care that
                     ;; its boundaries could have extended to shrunk - we
                     ;; will re-parent and shift them anyway.
                     (and (eq 'headline (org-element-type up))
                          (not org-element--cache-avoid-synchronous-headline-re-parsing)
                          ;; The change is not inside headline.  Not
                          ;; updating here.
                          (not (<= beg (org-element-property :begin up)))
                          (not (> end (org-element-property :end up)))
                          (let ((current (org-with-point-at (org-element-property :begin up)
                                           (org-element-with-disabled-cache
                                             (and (looking-at-p org-element-headline-re)
                                                  (org-element-headline-parser nil 'fast))))))
                            (when (eq 'headline (org-element-type current))
                              (org-element--cache-log-message
                               "Found non-robust headline that can be updated individually: %S"
                               (org-element--format-element current))
                              (org-element-set-element up current)
                              (org-element-put-property up :granularity 'element)
                              t)))
                     ;; If UP is org-data, the situation is similar to
                     ;; headline case.  We just need to re-parse the
                     ;; org-data itself, unless the change is made
                     ;; within blank lines at BOB (that could
                     ;; potentially alter first-section).
                     (when (and (eq 'org-data (org-element-type up))
                                (>= beg (org-element-property :contents-begin up)))
                       (org-element-set-element up (org-with-point-at 1 (org-element-org-data-parser)))
                       (org-element--cache-log-message
                        "Found non-robust change invalidating org-data. Re-parsing: %S"
                        (org-element--format-element up))
                       t))
              (org-element--cache-log-message
               "Found non-robust element: %S"
               (org-element--format-element up))
              (setq before up)
	      (when robust-flag (setq robust-flag nil))))
          (unless (or (org-element-property :parent up)
                      (eq 'org-data (org-element-type up)))
            (org-element--cache-warn "Got element without parent. Please report it to Org mode mailing list (M-x org-submit-bug-report).\n%S" up)
            (org-element-cache-reset)
            (error "org-element--cache: Emergency exit"))
	  (setq up (org-element-property :parent up)))
        ;; We're at top level element containing ELEMENT: if it's
        ;; altered by buffer modifications, it is first element in
        ;; cache to be removed.  Otherwise, that first element is the
        ;; following one.
        ;;
        ;; As a special case, do not remove BEFORE if it is a robust
        ;; container for current changes.
        (if (or (< (org-element-property :end before) beg) robust-flag) after
	  before)))))