Function: org-element--cache-find

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

Signature

(org-element--cache-find POS &optional SIDE)

Documentation

Find element in cache starting at POS or before.

POS refers to a buffer position.

When optional argument SIDE is non-nil, the function checks for elements starting at or past POS instead. If SIDE is both, the function returns a cons cell where car is the first element starting at or before POS and cdr the first element starting after POS.

The function can only find elements in the synchronized part of the cache.

Source Code

;; Defined in /usr/src/emacs/lisp/org/org-element.el.gz
(defun org-element--cache-find (pos &optional side)
  "Find element in cache starting at POS or before.

POS refers to a buffer position.

When optional argument SIDE is non-nil, the function checks for
elements starting at or past POS instead.  If SIDE is `both', the
function returns a cons cell where car is the first element
starting at or before POS and cdr the first element starting
after POS.

The function can only find elements in the synchronized part of
the cache."
  (org-with-base-buffer nil
    (let* ((limit (and org-element--cache-sync-requests
                       (org-element--request-key (car org-element--cache-sync-requests))))
	   (node (org-element--cache-root))
           (hash-pos (unless (eq side 'both)
                       (mod (org-knuth-hash pos)
                            org-element--cache-hash-size)))
           (hashed (if (not side)
                       (aref org-element--cache-hash-left hash-pos)
                     (unless (eq side 'both)
                       (aref org-element--cache-hash-right hash-pos))))
	   lower upper)
      ;; `org-element--cache-key-less-p' does not accept markers.
      (when (markerp pos) (setq pos (marker-position pos)))
      (cl-incf (cdr org-element--cache-hash-statistics))
      (when (eq side 'both) (cl-incf org-element--cache-hash-nocache))
      (if (and hashed (not (eq side 'both))
               (or (not limit)
                   ;; Limit can be a list key.
                   (org-element--cache-key-less-p
                    (org-element--cache-key hashed)
                    limit))
               (= pos (org-element-property :begin hashed))
               ;; We cannot rely on element :begin for elements with
               ;; children starting at the same pos.
               (not (memq (org-element-type hashed)
                        '(section org-data table)))
               (org-element-property :cached hashed))
          (progn
            (cl-incf (car org-element--cache-hash-statistics))
            hashed)
        (while node
          (let* ((element (avl-tree--node-data node))
                 (begin (org-element-property :begin element)))
	    (cond
	     ((and limit
                   (not (org-element--cache-key-less-p
                       (org-element--cache-key element) limit)))
	      (setq node (avl-tree--node-left node)))
	     ((> begin pos)
	      (setq upper element
		    node (avl-tree--node-left node)))
	     ((or (< begin pos)
                  ;; If the element is section or org-data, we also need
                  ;; to check the following element.
                  (memq (org-element-type element) '(section org-data)))
	      (setq lower element
		    node (avl-tree--node-right node)))
	     ;; We found an element in cache starting at POS.  If `side'
	     ;; is `both' we also want the next one in order to generate
	     ;; a key in-between.
	     ;;
	     ;; If the element is the first row or item in a table or
	     ;; a plain list, we always return the table or the plain
	     ;; list.
	     ;;
	     ;; In any other case, we return the element found.
	     ((eq side 'both)
	      (setq lower element)
	      (setq node (avl-tree--node-right node)))
	     ((and (memq (org-element-type element) '(item table-row))
                   (let ((parent (org-element-property :parent element)))
		     (and (= (org-element-property :begin element)
			     (org-element-property :contents-begin parent))
                          (setq node nil
                                lower parent
                                upper parent)))))
	     (t
	      (setq node nil
		    lower element
		    upper element)))))
        (if (not side)
            (aset org-element--cache-hash-left hash-pos lower)
          (unless (eq side 'both)
            (aset org-element--cache-hash-right hash-pos lower)))
        (pcase side
          (`both (cons lower upper))
          (`nil lower)
          (_ upper))))))