emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/org 3a4f9604f1 3/7: Cache <N>-level headline regexps in


From: ELPA Syncer
Subject: [elpa] externals/org 3a4f9604f1 3/7: Cache <N>-level headline regexps instead of calculating dynamically
Date: Thu, 18 May 2023 09:59:27 -0400 (EDT)

branch: externals/org
commit 3a4f9604f1c358045930ef97745898a7391fc162
Author: Ihor Radchenko <yantar92@posteo.net>
Commit: Ihor Radchenko <yantar92@posteo.net>

    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.
---
 lisp/org-element.el |  8 +++-----
 lisp/org-macs.el    | 31 +++++++++++++++++++++++++------
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/lisp/org-element.el b/lisp/org-element.el
index a13e91f277..ed740fc0b4 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -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)
diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index 306990280a..f771c408b3 100644
--- a/lisp/org-macs.el
+++ b/lisp/org-macs.el
@@ -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?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]