0
0
Fork 1
mirror of https://git.savannah.gnu.org/git/emacs/org-mode.git synced 2024-08-24 20:32:53 +00:00

Cache <N>-level headline regexps instead of calculating dynamically

* lisp/org-macs.el (org-headline-re): New function to retrieve cached
or get a new regexp for headline of level TRUE-LEVEL.
(org-get-limited-outline-regexp): Use `org-headline-re'.  Add new
optional argument WITH-BOL.
This commit is contained in:
Ihor Radchenko 2023-05-14 20:13:23 +02:00
parent bfa362c47d
commit 3a4f9604f1
No known key found for this signature in database
GPG key ID: 6470762A7DA11D8B
2 changed files with 28 additions and 11 deletions

View file

@ -1147,11 +1147,9 @@ Assume point is at beginning of the headline."
(time-props (org-element--get-time-properties))
(end
(save-excursion
(let ((re (rx-to-string
`(seq line-start (** 1 ,true-level "*") " "))))
(if (re-search-forward re nil t)
(line-beginning-position)
(point-max)))))
(if (re-search-forward (org-headline-re true-level) nil t)
(line-beginning-position)
(point-max))))
(contents-begin (save-excursion
(forward-line)
(skip-chars-forward " \r\t\n" end)

View file

@ -217,7 +217,7 @@ If BUFFER is nil, use base buffer for `current-buffer'."
(let* ((org-called-with-limited-levels t)
(org-outline-regexp (org-get-limited-outline-regexp))
(outline-regexp org-outline-regexp)
(org-outline-regexp-bol (concat "^" org-outline-regexp)))
(org-outline-regexp-bol (org-get-limited-outline-regexp t)))
,@body)))
(defmacro org-eval-in-environment (environment form)
@ -807,22 +807,41 @@ get an unnecessary O(N²) space complexity, so you're usually better off using
(eval form t)
(error (format "%%![Error: %s]" error))))
(defvar org--headline-re-cache (make-hash-table :test #'equal)
"Hash table holding association between headline level regexp.")
(defun org-headline-re (true-level &optional no-bol)
"Generate headline regexp for TRUE-LEVEL.
When NO-BOL is non-nil, regexp will not demand the regexp to start at
beginning of line."
(or (gethash (cons true-level no-bol) org--headline-re-cache)
(puthash
(cons true-level no-bol)
(rx-to-string
(if no-bol
`(seq (** 1 ,true-level "*") " ")
`(seq line-start (** 1 ,true-level "*") " ")))
org--headline-re-cache)))
(defvar org-outline-regexp) ; defined in org.el
(defvar org-outline-regexp-bol) ; defined in org.el
(defvar org-odd-levels-only) ; defined in org.el
(defvar org-inlinetask-min-level) ; defined in org-inlinetask.el
(defun org-get-limited-outline-regexp ()
(defun org-get-limited-outline-regexp (&optional with-bol)
"Return outline-regexp with limited number of levels.
The number of levels is controlled by `org-inlinetask-min-level'."
The number of levels is controlled by `org-inlinetask-min-level'.
Match at beginning of line when WITH-BOL is non-nil."
(cond ((not (derived-mode-p 'org-mode))
outline-regexp)
(if (string-prefix-p "^" outline-regexp)
(if with-bol outline-regexp (substring outline-regexp 1))
(if with-bol (concat "^" outline-regexp) outline-regexp)))
((not (featurep 'org-inlinetask))
org-outline-regexp)
(if with-bol org-outline-regexp-bol org-outline-regexp))
(t
(let* ((limit-level (1- org-inlinetask-min-level))
(nstars (if org-odd-levels-only
(1- (* limit-level 2))
limit-level)))
(format "\\*\\{1,%d\\} " nstars)))))
(org-headline-re nstars (not with-bol))))))
(defun org--line-empty-p (n)
"Is the Nth next line empty?