branch: externals/org
commit 534045979da96caf6635bbdfca013d91e133bb78
Author: Ihor Radchenko <[email protected]>
Commit: Ihor Radchenko <[email protected]>
org-element--current-element: Do not try to query cache
* lisp/org-element.el (org-element--current-element): Do not try to
search cache. This is rarely useful and forces an awkward
`org-element-copy' workaround what parsing buffer.
(org-element--parse-elements): Do not use `org-element-copy' for
element at point - it is now safe to assume that
`org-element--current-element' does not return cached.
(org-element--parse-to): Do not force disabled cache when calling
`org-element--current-element'. It is no longer needed.
---
lisp/org-element.el | 391 +++++++++++++++++++++++-----------------------------
1 file changed, 173 insertions(+), 218 deletions(-)
diff --git a/lisp/org-element.el b/lisp/org-element.el
index 6d0890f4b5..dd06a2a75c 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -4187,7 +4187,7 @@ Assume point is at the first equal sign marker."
(defvar org-inlinetask-min-level); Declared in org-inlinetask.el
(defvar org-element--cache-sync-requests); Declared later
-(defun org-element--current-element (limit &optional granularity mode
structure add-to-cache)
+(defun org-element--current-element (limit &optional granularity mode
structure)
"Parse the element starting at point.
Return value is a list like (TYPE PROPS) where TYPE is the type
@@ -4212,207 +4212,176 @@ Optional argument MODE, when non-nil, can be either
If STRUCTURE isn't provided but MODE is set to `item', it will be
computed.
-Optional argument ADD-TO-CACHE, when non-nil, and when cache is active,
-will also add current element to cache if it is not yet there. Use
-this argument with care, as validity of the element in parse tree is
-not checked.
-
This function assumes point is always at the beginning of the
element it has to parse."
- (let* ((element (and (not (buffer-narrowed-p))
- (org-element--cache-active-p)
- (not org-element--cache-sync-requests)
- (org-element--cache-find (point) t)))
- (element (progn (while (and element
- (not (and (eq (point)
(org-element-property :begin element))
- (eq mode (org-element-property
:mode element)))))
- (setq element (org-element-property :parent
element)))
- element))
- (old-element element)
- (element (when
- (pcase (org-element-property :granularity element)
- (`nil t)
- (`object t)
- (`element (not (memq granularity '(nil object))))
- (`greater-element (not (memq granularity '(nil object
element))))
- (`headline (eq granularity 'headline)))
- element)))
- (if element
- element
- (save-excursion
- (let ((case-fold-search t)
- ;; Determine if parsing depth allows for secondary strings
- ;; parsing. It only applies to elements referenced in
- ;; `org-element-secondary-value-alist'.
- (raw-secondary-p (and granularity (not (eq granularity 'object))))
- result)
- (setq
- result
- ;; Regexp matches below should avoid modifying match data,
- ;; if possible. Doing it unnecessarily degrades regexp
- ;; matching performance an order of magnitude, which
- ;; becomes important when parsing large buffers with huge
- ;; amount of elements to be parsed.
- ;;
- ;; In general, the checks below should be as efficient as
- ;; possible, especially early in the `cond' form. (The
- ;; early checks will contribute to al subsequent parsers as
- ;; well).
- (cond
- ;; Item.
- ((eq mode 'item) (org-element-item-parser limit structure
raw-secondary-p))
- ;; Table Row.
- ((eq mode 'table-row) (org-element-table-row-parser limit))
- ;; Node Property.
- ((eq mode 'node-property) (org-element-node-property-parser limit))
- ;; Headline.
- ((and (looking-at-p "^\\*+ ")
- (or (not (featurep 'org-inlinetask))
- (save-excursion
- (< (skip-chars-forward "*")
- (if org-odd-levels-only
- (1- (* org-inlinetask-min-level 2))
- org-inlinetask-min-level)))))
- (org-element-headline-parser limit raw-secondary-p))
- ;; Sections (must be checked after headline).
- ((memq mode '(section first-section)) (org-element-section-parser
nil))
- ;; Comments.
- ((looking-at-p "^[ \t]*#\\(?: \\|$\\)")
(org-element-comment-parser limit))
- ;; Planning.
- ((and (eq mode 'planning)
- (eq ?* (char-after (line-beginning-position 0)))
- (looking-at-p org-element-planning-line-re))
- (org-element-planning-parser limit))
- ;; Property drawer.
- ((and (pcase mode
- (`planning (eq ?* (char-after (line-beginning-position 0))))
- ((or `property-drawer `top-comment)
- (save-excursion
- (beginning-of-line 0)
- (not (looking-at-p "[[:blank:]]*$"))))
- (_ nil))
- (looking-at-p org-property-drawer-re))
- (org-element-property-drawer-parser limit))
- ;; When not at bol, point is at the beginning of an item or
- ;; a footnote definition: next item is always a paragraph.
- ((not (bolp)) (org-element-paragraph-parser limit (list (point))))
- ;; Clock.
- ((looking-at-p org-element-clock-line-re)
(org-element-clock-parser limit))
- ;; Inlinetask.
- ((looking-at-p "^\\*+ ") (org-element-inlinetask-parser limit
raw-secondary-p))
- ;; From there, elements can have affiliated keywords.
- (t (let ((affiliated (org-element--collect-affiliated-keywords
- limit (memq granularity '(nil object)))))
- (cond
- ;; Jumping over affiliated keywords put point off-limits.
- ;; Parse them as regular keywords.
- ((and (cdr affiliated) (>= (point) limit))
- (goto-char (car affiliated))
- (org-element-keyword-parser limit nil))
- ;; LaTeX Environment.
- ((looking-at-p org-element--latex-begin-environment)
- (org-element-latex-environment-parser limit affiliated))
- ;; Drawer.
- ((looking-at-p org-element-drawer-re)
- (org-element-drawer-parser limit affiliated))
- ;; Fixed Width
- ((looking-at-p "[ \t]*:\\( \\|$\\)")
- (org-element-fixed-width-parser limit affiliated))
- ;; Inline Comments, Blocks, Babel Calls, Dynamic Blocks and
- ;; Keywords.
- ((looking-at "[ \t]*#\\+")
- (goto-char (match-end 0))
- (cond
- ((looking-at "BEGIN_\\(\\S-+\\)")
- (beginning-of-line)
- (funcall (pcase (upcase (match-string 1))
- ("CENTER" #'org-element-center-block-parser)
- ("COMMENT" #'org-element-comment-block-parser)
- ("EXAMPLE" #'org-element-example-block-parser)
- ("EXPORT" #'org-element-export-block-parser)
- ("QUOTE" #'org-element-quote-block-parser)
- ("SRC" #'org-element-src-block-parser)
- ("VERSE" #'org-element-verse-block-parser)
- (_ #'org-element-special-block-parser))
- limit
- affiliated))
- ((looking-at-p "CALL:")
- (beginning-of-line)
- (org-element-babel-call-parser limit affiliated))
- ((save-excursion
- (beginning-of-line)
- (looking-at-p org-element-dynamic-block-open-re))
- (beginning-of-line)
- (org-element-dynamic-block-parser limit affiliated))
- ((looking-at-p "\\S-+:")
- (beginning-of-line)
- (org-element-keyword-parser limit affiliated))
- (t
- (beginning-of-line)
- (org-element-paragraph-parser limit affiliated))))
- ;; Footnote Definition.
- ((looking-at-p org-footnote-definition-re)
- (org-element-footnote-definition-parser limit affiliated))
- ;; Horizontal Rule.
- ((looking-at-p "[ \t]*-\\{5,\\}[ \t]*$")
- (org-element-horizontal-rule-parser limit affiliated))
- ;; Diary Sexp.
- ((looking-at-p "%%(")
- (org-element-diary-sexp-parser limit affiliated))
- ;; Table.
- ((or (looking-at-p "[ \t]*|")
- ;; There is no strict definition of a table.el
- ;; table. Try to prevent false positive while being
- ;; quick.
- (let ((rule-regexp
- (rx (zero-or-more (any " \t"))
- "+"
- (one-or-more (one-or-more "-") "+")
- (zero-or-more (any " \t"))
- eol))
- (non-table.el-line
- (rx bol
- (zero-or-more (any " \t"))
- (or eol (not (any "+| \t")))))
- (next (line-beginning-position 2)))
- ;; Start with a full rule.
- (and
- (looking-at-p rule-regexp)
- (< next limit) ;no room for a table.el table
- (save-excursion
- (end-of-line)
- (cond
- ;; Must end with a full rule.
- ((not (re-search-forward non-table.el-line limit
'move))
- (if (bolp) (forward-line -1) (beginning-of-line))
- (looking-at-p rule-regexp))
- ;; Ignore pseudo-tables with a single
- ;; rule.
- ((= next (line-beginning-position))
- nil)
- ;; Must end with a full rule.
- (t
- (forward-line -1)
- (looking-at-p rule-regexp)))))))
- (org-element-table-parser limit affiliated))
- ;; List.
- ((looking-at-p (org-item-re))
- (org-element-plain-list-parser
- limit affiliated
- (or structure (org-element--list-struct limit))))
- ;; Default element: Paragraph.
- (t (org-element-paragraph-parser limit affiliated)))))))
- (when result
- (org-element-put-property result :mode mode)
- (org-element-put-property result :granularity granularity))
- (when (and add-to-cache(not (buffer-narrowed-p))
- (not org-element--cache-sync-requests)
- (org-element--cache-active-p))
- (if (not old-element)
- (setq result (org-element--cache-put result))
- (org-element-set-element old-element result)
- (setq result old-element)))
- result)))))
+ (save-excursion
+ (let ((case-fold-search t)
+ ;; Determine if parsing depth allows for secondary strings
+ ;; parsing. It only applies to elements referenced in
+ ;; `org-element-secondary-value-alist'.
+ (raw-secondary-p (and granularity (not (eq granularity 'object))))
+ result at-task?)
+ (setq
+ result
+ ;; Regexp matches below should avoid modifying match data,
+ ;; if possible. Doing it unnecessarily degrades regexp
+ ;; matching performance an order of magnitude, which
+ ;; becomes important when parsing large buffers with huge
+ ;; amount of elements to be parsed.
+ ;;
+ ;; In general, the checks below should be as efficient as
+ ;; possible, especially early in the `cond' form. (The
+ ;; early checks will contribute to al subsequent parsers as
+ ;; well).
+ (cond
+ ;; Item.
+ ((eq mode 'item) (org-element-item-parser limit structure
raw-secondary-p))
+ ;; Table Row.
+ ((eq mode 'table-row) (org-element-table-row-parser limit))
+ ;; Node Property.
+ ((eq mode 'node-property) (org-element-node-property-parser limit))
+ ;; Headline.
+ ((and (looking-at-p "^\\*+ ")
+ (setq at-task? t)
+ (or (not (featurep 'org-inlinetask))
+ (save-excursion
+ (< (skip-chars-forward "*")
+ (if org-odd-levels-only
+ (1- (* org-inlinetask-min-level 2))
+ org-inlinetask-min-level)))))
+ (org-element-headline-parser limit raw-secondary-p))
+ ;; Sections (must be checked after headline).
+ ((memq mode '(section first-section)) (org-element-section-parser nil))
+ ;; Comments.
+ ((looking-at-p "^[ \t]*#\\(?: \\|$\\)") (org-element-comment-parser
limit))
+ ;; Planning.
+ ((and (eq mode 'planning)
+ (eq ?* (char-after (line-beginning-position 0)))
+ (looking-at-p org-element-planning-line-re))
+ (org-element-planning-parser limit))
+ ;; Property drawer.
+ ((and (pcase mode
+ (`planning (eq ?* (char-after (line-beginning-position 0))))
+ ((or `property-drawer `top-comment)
+ (save-excursion
+ (beginning-of-line 0)
+ (not (looking-at-p "[[:blank:]]*$"))))
+ (_ nil))
+ (looking-at-p org-property-drawer-re))
+ (org-element-property-drawer-parser limit))
+ ;; When not at bol, point is at the beginning of an item or
+ ;; a footnote definition: next item is always a paragraph.
+ ((not (bolp)) (org-element-paragraph-parser limit (list (point))))
+ ;; Clock.
+ ((looking-at-p org-element-clock-line-re) (org-element-clock-parser
limit))
+ ;; Inlinetask.
+ (at-task? (org-element-inlinetask-parser limit raw-secondary-p))
+ ;; From there, elements can have affiliated keywords.
+ (t (let ((affiliated (org-element--collect-affiliated-keywords
+ limit (memq granularity '(nil object)))))
+ (cond
+ ;; Jumping over affiliated keywords put point off-limits.
+ ;; Parse them as regular keywords.
+ ((and (cdr affiliated) (>= (point) limit))
+ (goto-char (car affiliated))
+ (org-element-keyword-parser limit nil))
+ ;; LaTeX Environment.
+ ((looking-at-p org-element--latex-begin-environment)
+ (org-element-latex-environment-parser limit affiliated))
+ ;; Drawer.
+ ((looking-at-p org-element-drawer-re)
+ (org-element-drawer-parser limit affiliated))
+ ;; Fixed Width
+ ((looking-at-p "[ \t]*:\\( \\|$\\)")
+ (org-element-fixed-width-parser limit affiliated))
+ ;; Inline Comments, Blocks, Babel Calls, Dynamic Blocks and
+ ;; Keywords.
+ ((looking-at "[ \t]*#\\+")
+ (goto-char (match-end 0))
+ (cond
+ ((looking-at "BEGIN_\\(\\S-+\\)")
+ (beginning-of-line)
+ (funcall (pcase (upcase (match-string 1))
+ ("CENTER" #'org-element-center-block-parser)
+ ("COMMENT" #'org-element-comment-block-parser)
+ ("EXAMPLE" #'org-element-example-block-parser)
+ ("EXPORT" #'org-element-export-block-parser)
+ ("QUOTE" #'org-element-quote-block-parser)
+ ("SRC" #'org-element-src-block-parser)
+ ("VERSE" #'org-element-verse-block-parser)
+ (_ #'org-element-special-block-parser))
+ limit
+ affiliated))
+ ((looking-at-p "CALL:")
+ (beginning-of-line)
+ (org-element-babel-call-parser limit affiliated))
+ ((save-excursion
+ (beginning-of-line)
+ (looking-at-p org-element-dynamic-block-open-re))
+ (beginning-of-line)
+ (org-element-dynamic-block-parser limit affiliated))
+ ((looking-at-p "\\S-+:")
+ (beginning-of-line)
+ (org-element-keyword-parser limit affiliated))
+ (t
+ (beginning-of-line)
+ (org-element-paragraph-parser limit affiliated))))
+ ;; Footnote Definition.
+ ((looking-at-p org-footnote-definition-re)
+ (org-element-footnote-definition-parser limit affiliated))
+ ;; Horizontal Rule.
+ ((looking-at-p "[ \t]*-\\{5,\\}[ \t]*$")
+ (org-element-horizontal-rule-parser limit affiliated))
+ ;; Diary Sexp.
+ ((looking-at-p "%%(")
+ (org-element-diary-sexp-parser limit affiliated))
+ ;; Table.
+ ((or (looking-at-p "[ \t]*|")
+ ;; There is no strict definition of a table.el
+ ;; table. Try to prevent false positive while being
+ ;; quick.
+ (let ((rule-regexp
+ (rx (zero-or-more (any " \t"))
+ "+"
+ (one-or-more (one-or-more "-") "+")
+ (zero-or-more (any " \t"))
+ eol))
+ (non-table.el-line
+ (rx bol
+ (zero-or-more (any " \t"))
+ (or eol (not (any "+| \t")))))
+ (next (line-beginning-position 2)))
+ ;; Start with a full rule.
+ (and
+ (looking-at-p rule-regexp)
+ (< next limit) ;no room for a table.el table
+ (save-excursion
+ (end-of-line)
+ (cond
+ ;; Must end with a full rule.
+ ((not (re-search-forward non-table.el-line limit
'move))
+ (if (bolp) (forward-line -1) (beginning-of-line))
+ (looking-at-p rule-regexp))
+ ;; Ignore pseudo-tables with a single
+ ;; rule.
+ ((= next (line-beginning-position))
+ nil)
+ ;; Must end with a full rule.
+ (t
+ (forward-line -1)
+ (looking-at-p rule-regexp)))))))
+ (org-element-table-parser limit affiliated))
+ ;; List.
+ ((looking-at-p (org-item-re))
+ (org-element-plain-list-parser
+ limit affiliated
+ (or structure (org-element--list-struct limit))))
+ ;; Default element: Paragraph.
+ (t (org-element-paragraph-parser limit affiliated)))))))
+ (when result
+ (org-element-put-property result :mode mode)
+ (org-element-put-property result :granularity granularity))
+ result)))
;; Most elements can have affiliated keywords. When looking for an
@@ -4824,20 +4793,7 @@ Elements are accumulated into ACC."
(when (and (eolp) (not (eobp))) (forward-char)))
;; Find current element's type and parse it accordingly to
;; its category.
- (let* ((element (org-element-copy
- ;; `org-element--current-element' may return cached
- ;; elements. Below code reassigns
- ;; `:parent' property of the element and
- ;; may interfere with cache
- ;; synchronization if parent element is not
- ;; yet in cache. Moreover, the returned
- ;; structure may be altered by caller code
- ;; arbitrarily. Hence, we return a copy of
- ;; the potentially cached element to make
- ;; potential modifications safe for element
- ;; cache.
- (org-element--current-element
- end granularity mode structure)))
+ (let* ((element (org-element--current-element end granularity mode
structure))
(type (org-element-type element))
(cbeg (org-element-property :contents-begin element)))
(goto-char (org-element-property :end element))
@@ -6577,10 +6533,9 @@ If you observe Emacs hangs frequently, please report
this to Org mode mailing li
(unless (save-excursion
(org-skip-whitespace)
(eobp))
- (org-element-with-disabled-cache
- (setq element (org-element--current-element
- end 'element mode
- (org-element-property :structure parent)))))
+ (setq element (org-element--current-element
+ end 'element mode
+ (org-element-property :structure parent))))
;; Make sure that we return referenced element in cache
;; that can be altered directly.
(if element