فهرست منبع

Fix compatibility with Emacs 26

* lisp/org-compat.el (org-file-name-concat): Do not use
`string-empty-p'.
(combine-change-calls): Create a stub when `combine-change-calls' were
not yet available.
(org-replace-buffer-contents): Add compatibility function for
`replace-buffer-contents'.

* lisp/org-element.el (org-element--current-element): Do not use
`if-let'.
* lisp/org-persist.el (org-persist-gc): Do not use `when-let'.
* lisp/org-plot.el (org-plot/gnuplot): Do not use `if-let'.
* lisp/org-src.el (org-edit-src-save, org-edit-src-exit): Use
`org-replace-buffer-contents'.

* lisp/org.el (org-narrow-to-subtree, org--property-local-values,
org-entry-get-with-inheritance, org-in-commented-heading-p,
org-up-heading-safe, org-goto-first-child): Do not use
`if-let'/`when-let'.

* testing/org-test.el (org-test-at-time): Fallback to old
`decode-time' specification in older Emacs.
Ihor Radchenko 4 سال پیش
والد
کامیت
004ac14a5b
7فایلهای تغییر یافته به همراه385 افزوده شده و 360 حذف شده
  1. 12 1
      lisp/org-compat.el
  2. 183 182
      lisp/org-element.el
  3. 11 10
      lisp/org-persist.el
  4. 4 3
      lisp/org-plot.el
  5. 4 4
      lisp/org-src.el
  6. 164 158
      lisp/org.el
  7. 7 2
      testing/org-test.el

+ 12 - 1
lisp/org-compat.el

@@ -90,7 +90,7 @@ inserted before contatenating."
        (delq nil
        (delq nil
              (mapcar
              (mapcar
               (lambda (str)
               (lambda (str)
-                (when (and str (not (string-empty-p str))
+                (when (and str (not (seq-empty-p str))
                            (string-match "\\(.+\\)/?" str))
                            (string-match "\\(.+\\)/?" str))
                   (match-string 1 str)))
                   (match-string 1 str)))
               (cons directory components)))
               (cons directory components)))
@@ -106,6 +106,17 @@ inserted before contatenating."
 
 
 ;;; Emacs < 27.1 compatibility
 ;;; Emacs < 27.1 compatibility
 
 
+(unless (fboundp 'combine-change-calls)
+  ;; A stub when `combine-change-calls' was not yet there.
+  (defmacro combine-change-calls (_beg _end &rest body)
+    (declare (debug (form form def-body)) (indent 2))
+    `(progn ,@body)))
+
+(if (version< emacs-version "27.1")
+    (defsubst org-replace-buffer-contents (source &optional _max-secs _max-costs)
+      (replace-buffer-contents source))
+  (defalias 'org-replace-buffer-contents #'replace-buffer-contents))
+
 (unless (fboundp 'proper-list-p)
 (unless (fboundp 'proper-list-p)
   ;; `proper-list-p' was added in Emacs 27.1.  The function below is
   ;; `proper-list-p' was added in Emacs 27.1.  The function below is
   ;; taken from Emacs subr.el 200195e824b^.
   ;; taken from Emacs subr.el 200195e824b^.

+ 183 - 182
lisp/org-element.el

@@ -4138,189 +4138,190 @@ not checked.
 
 
 This function assumes point is always at the beginning of the
 This function assumes point is always at the beginning of the
 element it has to parse."
 element it has to parse."
-  (if-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)))
-      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
-         (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.
-          ((org-with-limited-levels (org-at-heading-p))
-           (org-element-headline-parser limit raw-secondary-p))
-          ;; Sections (must be checked after headline).
-          ((eq mode 'section) (org-element-section-parser limit))
-          ((eq mode 'first-section)
-	   (org-element-section-parser
-	    (or (save-excursion (org-with-limited-levels (outline-next-heading)))
-	        limit)))
-          ;; Comments.
-          ((looking-at "^[ \t]*#\\(?: \\|$\\)")
-	   (org-element-comment-parser limit))
-          ;; Planning.
-          ((and (eq mode 'planning)
-	        (eq ?* (char-after (line-beginning-position 0)))
-	        (looking-at org-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 "[[:blank:]]*$"))))
-	          (_ nil))
-	        (looking-at 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 org-clock-line-re) (org-element-clock-parser limit))
-          ;; Inlinetask.
-          ((looking-at "^\\*+ ")
-	   (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 org-element--latex-begin-environment)
-	         (org-element-latex-environment-parser limit affiliated))
-	        ;; Drawer.
-	        ((looking-at org-drawer-regexp)
-	         (org-element-drawer-parser limit affiliated))
-	        ;; Fixed Width
-	        ((looking-at "[ \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))
+  (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
+           (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.
+            ((org-with-limited-levels (org-at-heading-p))
+             (org-element-headline-parser limit raw-secondary-p))
+            ;; Sections (must be checked after headline).
+            ((eq mode 'section) (org-element-section-parser limit))
+            ((eq mode 'first-section)
+	     (org-element-section-parser
+	      (or (save-excursion (org-with-limited-levels (outline-next-heading)))
+	          limit)))
+            ;; Comments.
+            ((looking-at "^[ \t]*#\\(?: \\|$\\)")
+	     (org-element-comment-parser limit))
+            ;; Planning.
+            ((and (eq mode 'planning)
+	          (eq ?* (char-after (line-beginning-position 0)))
+	          (looking-at org-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 "[[:blank:]]*$"))))
+	            (_ nil))
+	          (looking-at 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 org-clock-line-re) (org-element-clock-parser limit))
+            ;; Inlinetask.
+            ((looking-at "^\\*+ ")
+	     (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
 	         (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 "CALL:")
-		   (beginning-of-line)
-		   (org-element-babel-call-parser limit affiliated))
-	          ((looking-at "BEGIN:? ")
-		   (beginning-of-line)
-		   (org-element-dynamic-block-parser limit affiliated))
-	          ((looking-at "\\S-+:")
-		   (beginning-of-line)
-		   (org-element-keyword-parser limit affiliated))
-	          (t
-		   (beginning-of-line)
-		   (org-element-paragraph-parser limit affiliated))))
-	        ;; Footnote Definition.
-	        ((looking-at org-footnote-definition-re)
-	         (org-element-footnote-definition-parser limit affiliated))
-	        ;; Horizontal Rule.
-	        ((looking-at "[ \t]*-\\{5,\\}[ \t]*$")
-	         (org-element-horizontal-rule-parser limit affiliated))
-	        ;; Diary Sexp.
-	        ((looking-at "%%(")
-	         (org-element-diary-sexp-parser limit affiliated))
-	        ;; Table.
-	        ((or (looking-at "[ \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 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 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 rule-regexp)))))))
-	         (org-element-table-parser limit affiliated))
-	        ;; List.
-	        ((looking-at (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 (not (buffer-narrowed-p))
-                   (org-element--cache-active-p)
-                   (not org-element--cache-sync-requests)
-                   add-to-cache)
-          (if (not old-element)
-              (setq result (org-element--cache-put result))
-            (org-element-set-element old-element result)
-            (setq result old-element)))
-        result))))
+	          ;; 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 org-element--latex-begin-environment)
+	           (org-element-latex-environment-parser limit affiliated))
+	          ;; Drawer.
+	          ((looking-at org-drawer-regexp)
+	           (org-element-drawer-parser limit affiliated))
+	          ;; Fixed Width
+	          ((looking-at "[ \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 "CALL:")
+		     (beginning-of-line)
+		     (org-element-babel-call-parser limit affiliated))
+	            ((looking-at "BEGIN:? ")
+		     (beginning-of-line)
+		     (org-element-dynamic-block-parser limit affiliated))
+	            ((looking-at "\\S-+:")
+		     (beginning-of-line)
+		     (org-element-keyword-parser limit affiliated))
+	            (t
+		     (beginning-of-line)
+		     (org-element-paragraph-parser limit affiliated))))
+	          ;; Footnote Definition.
+	          ((looking-at org-footnote-definition-re)
+	           (org-element-footnote-definition-parser limit affiliated))
+	          ;; Horizontal Rule.
+	          ((looking-at "[ \t]*-\\{5,\\}[ \t]*$")
+	           (org-element-horizontal-rule-parser limit affiliated))
+	          ;; Diary Sexp.
+	          ((looking-at "%%(")
+	           (org-element-diary-sexp-parser limit affiliated))
+	          ;; Table.
+	          ((or (looking-at "[ \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 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 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 rule-regexp)))))))
+	           (org-element-table-parser limit affiliated))
+	          ;; List.
+	          ((looking-at (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 (not (buffer-narrowed-p))
+                     (org-element--cache-active-p)
+                     (not org-element--cache-sync-requests)
+                     add-to-cache)
+            (if (not old-element)
+                (setq result (org-element--cache-put result))
+              (org-element-set-element old-element result)
+              (setq result old-element)))
+          result)))))
 
 
 
 
 ;; Most elements can have affiliated keywords.  When looking for an
 ;; Most elements can have affiliated keywords.  When looking for an

+ 11 - 10
lisp/org-persist.el

@@ -249,16 +249,17 @@ When BUFFER is `all', unregister VAR in all buffers."
   "Remove stored data for not existing files or unregistered variables."
   "Remove stored data for not existing files or unregistered variables."
   (let (new-index)
   (let (new-index)
     (dolist (index org-persist--index)
     (dolist (index org-persist--index)
-      (when-let ((file (plist-get index :path))
-                 (persist-file (org-file-name-concat
-                                org-persist-path
-                                (plist-get index :persist-file))))
-        (if (file-exists-p file)
-            (push index new-index)
-          (when (file-exists-p persist-file)
-            (delete-file persist-file)
-            (when (org-directory-empty-p (file-name-directory persist-file))
-              (delete-directory (file-name-directory persist-file)))))))
+      (let ((file (plist-get index :path))
+            (persist-file (org-file-name-concat
+                           org-persist-path
+                           (plist-get index :persist-file))))
+        (when (and file persist-file)
+          (if (file-exists-p file)
+              (push index new-index)
+            (when (file-exists-p persist-file)
+              (delete-file persist-file)
+              (when (org-directory-empty-p (file-name-directory persist-file))
+                (delete-directory (file-name-directory persist-file))))))))
     (setq org-persist--index (nreverse new-index))))
     (setq org-persist--index (nreverse new-index))))
 
 
 (add-hook 'kill-emacs-hook #'org-persist-gc)
 (add-hook 'kill-emacs-hook #'org-persist-gc)

+ 4 - 3
lisp/org-plot.el

@@ -682,9 +682,10 @@ line directly before or after the table."
 				  (looking-at "[[:space:]]*#\\+"))
 				  (looking-at "[[:space:]]*#\\+"))
 			(setf params (org-plot/collect-options params))))
 			(setf params (org-plot/collect-options params))))
       ;; Dump table to datafile
       ;; Dump table to datafile
-      (if-let ((dump-func (plist-get type :data-dump)))
-	  (funcall dump-func table data-file num-cols params)
-	(org-plot/gnuplot-to-data table data-file params))
+      (let ((dump-func (plist-get type :data-dump)))
+        (if dump-func
+	    (funcall dump-func table data-file num-cols params)
+	  (org-plot/gnuplot-to-data table data-file params)))
       ;; Check type of ind column (timestamp? text?)
       ;; Check type of ind column (timestamp? text?)
       (when (plist-get params :check-ind-type)
       (when (plist-get params :check-ind-type)
 	(let* ((ind (1- (plist-get params :ind)))
 	(let* ((ind (1- (plist-get params :ind)))

+ 4 - 4
lisp/org-src.el

@@ -1241,7 +1241,7 @@ EVENT is passed to `mouse-set-point'."
 		   (insert (with-current-buffer write-back-buf (buffer-string))))
 		   (insert (with-current-buffer write-back-buf (buffer-string))))
 	  (save-restriction
 	  (save-restriction
 	    (narrow-to-region beg end)
 	    (narrow-to-region beg end)
-	    (replace-buffer-contents write-back-buf 0.1 nil)
+	    (org-replace-buffer-contents write-back-buf 0.1 nil)
 	    (goto-char (point-max))))
 	    (goto-char (point-max))))
 	(when (and expecting-bol (not (bolp))) (insert "\n")))
 	(when (and expecting-bol (not (bolp))) (insert "\n")))
       (kill-buffer write-back-buf)
       (kill-buffer write-back-buf)
@@ -1278,8 +1278,8 @@ EVENT is passed to `mouse-set-point'."
     (org-with-wide-buffer
     (org-with-wide-buffer
      (when (and write-back
      (when (and write-back
                 (not (equal (buffer-substring beg end)
                 (not (equal (buffer-substring beg end)
-			    (with-current-buffer write-back-buf
-                              (buffer-string)))))
+			  (with-current-buffer write-back-buf
+                            (buffer-string)))))
        (undo-boundary)
        (undo-boundary)
        (goto-char beg)
        (goto-char beg)
        (let ((expecting-bol (bolp)))
        (let ((expecting-bol (bolp)))
@@ -1289,7 +1289,7 @@ EVENT is passed to `mouse-set-point'."
                               (buffer-string))))
                               (buffer-string))))
 	   (save-restriction
 	   (save-restriction
 	     (narrow-to-region beg end)
 	     (narrow-to-region beg end)
-	     (replace-buffer-contents write-back-buf 0.1 nil)
+	     (org-replace-buffer-contents write-back-buf 0.1 nil)
 	     (goto-char (point-max))))
 	     (goto-char (point-max))))
 	 (when (and expecting-bol (not (bolp))) (insert "\n")))))
 	 (when (and expecting-bol (not (bolp))) (insert "\n")))))
     (when write-back-buf (kill-buffer write-back-buf))
     (when write-back-buf (kill-buffer write-back-buf))

+ 164 - 158
lisp/org.el

@@ -7918,14 +7918,15 @@ If yes, remember the marker and the distance to BEG."
   "Narrow buffer to the current subtree."
   "Narrow buffer to the current subtree."
   (interactive)
   (interactive)
   (if (org-element--cache-active-p)
   (if (org-element--cache-active-p)
-      (if-let* ((heading (org-element-lineage
-                          (or element (org-element-at-point))
-                          '(headline) t))
-                (end (org-element-property :end heading)))
-          (narrow-to-region (org-element-property :begin heading)
-                            (if (= end (point-max))
-                                end (1- end)))
-        (signal 'outline-before-first-heading nil))
+      (let* ((heading (org-element-lineage
+                       (or element (org-element-at-point))
+                       '(headline) t))
+             (end (org-element-property :end heading)))
+        (if (and heading end)
+            (narrow-to-region (org-element-property :begin heading)
+                              (if (= end (point-max))
+                                  end (1- end)))
+          (signal 'outline-before-first-heading nil)))
     (save-excursion
     (save-excursion
       (save-match-data
       (save-match-data
         (org-with-limited-levels
         (org-with-limited-levels
@@ -13153,34 +13154,35 @@ Value is a list whose car is the base value for PROPERTY and cdr
 a list of accumulated values.  Return nil if neither is found in
 a list of accumulated values.  Return nil if neither is found in
 the entry.  Also return nil when PROPERTY is set to \"nil\",
 the entry.  Also return nil when PROPERTY is set to \"nil\",
 unless LITERAL-NIL is non-nil."
 unless LITERAL-NIL is non-nil."
-  (if-let ((element (or element
-                        (and (org-element--cache-active-p)
-                             (org-element-at-point nil 'cached)))))
-      (let* ((element (org-element-lineage element '(headline org-data inlinetask) 'with-self))
-             (base-value (org-element-property (intern (concat ":" (upcase property))) element))
-             (base-value (if literal-nil base-value (org-not-nil base-value)))
-             (extra-value (org-element-property (intern (concat ":" (upcase property) "+")) element))
-             (extra-value (if (listp extra-value) extra-value (list extra-value)))
-             (value (cons base-value extra-value)))
-        (and (not (equal value '(nil))) value))
-    (let ((range (org-get-property-block)))
-      (when range
-        (goto-char (car range))
-        (let* ((case-fold-search t)
-	       (end (cdr range))
-	       (value
-	        ;; Base value.
-	        (save-excursion
-		  (let ((v (and (re-search-forward
-			         (org-re-property property nil t) end t)
-			        (match-string-no-properties 3))))
-		    (list (if literal-nil v (org-not-nil v)))))))
-	  ;; Find additional values.
-	  (let* ((property+ (org-re-property (concat property "+") nil t)))
-	    (while (re-search-forward property+ end t)
-	      (push (match-string-no-properties 3) value)))
-	  ;; Return final values.
-	  (and (not (equal value '(nil))) (nreverse value)))))))
+  (let ((element (or element
+                     (and (org-element--cache-active-p)
+                          (org-element-at-point nil 'cached)))))
+    (if element
+        (let* ((element (org-element-lineage element '(headline org-data inlinetask) 'with-self))
+               (base-value (org-element-property (intern (concat ":" (upcase property))) element))
+               (base-value (if literal-nil base-value (org-not-nil base-value)))
+               (extra-value (org-element-property (intern (concat ":" (upcase property) "+")) element))
+               (extra-value (if (listp extra-value) extra-value (list extra-value)))
+               (value (cons base-value extra-value)))
+          (and (not (equal value '(nil))) value))
+      (let ((range (org-get-property-block)))
+        (when range
+          (goto-char (car range))
+          (let* ((case-fold-search t)
+	         (end (cdr range))
+	         (value
+	          ;; Base value.
+	          (save-excursion
+		    (let ((v (and (re-search-forward
+			           (org-re-property property nil t) end t)
+			          (match-string-no-properties 3))))
+		      (list (if literal-nil v (org-not-nil v)))))))
+	    ;; Find additional values.
+	    (let* ((property+ (org-re-property (concat property "+") nil t)))
+	      (while (re-search-forward property+ end t)
+	        (push (match-string-no-properties 3) value)))
+	    ;; Return final values.
+	    (and (not (equal value '(nil))) (nreverse value))))))))
 
 
 (defun org--property-global-or-keyword-value (property literal-nil)
 (defun org--property-global-or-keyword-value (property literal-nil)
   "Return value for PROPERTY as defined by global properties or by keyword.
   "Return value for PROPERTY as defined by global properties or by keyword.
@@ -13328,59 +13330,60 @@ However, if LITERAL-NIL is set, return the string value \"nil\" instead."
   (org-with-wide-buffer
   (org-with-wide-buffer
    (let (value at-bob-no-heading)
    (let (value at-bob-no-heading)
      (catch 'exit
      (catch 'exit
-       (if-let ((element (or element
-                             (and (org-element--cache-active-p)
-                                  (org-element-at-point nil 'cached)))))
-           (let ((element (org-element-lineage element '(headline org-data inlinetask) 'with-self)))
-             (while t
-               (let* ((v (org--property-local-values property literal-nil element))
-                      (v (if (listp v) v (list v))))
-                 (when v
-                   (setq value
-                         (concat (mapconcat #'identity (delq nil v) " ")
-                                 (and value " ")
-                                 value)))
-                 (cond
-	          ((car v)
-	           (move-marker org-entry-property-inherited-from (org-element-property :begin element))
-	           (throw 'exit nil))
-	          ((org-element-property :parent element)
-                   (setq element (org-element-property :parent element)))
-	          (t
-	           (let ((global (org--property-global-or-keyword-value property literal-nil)))
-	             (cond ((not global))
-		           (value (setq value (concat global " " value)))
-		           (t (setq value global))))
-	           (throw 'exit nil))))))
-         (while t
-	   (let ((v (org--property-local-values property literal-nil)))
-	     (when v
-	       (setq value
-		     (concat (mapconcat #'identity (delq nil v) " ")
-			     (and value " ")
-			     value)))
-	     (cond
-	      ((car v)
-	       (org-back-to-heading-or-point-min t)
-	       (move-marker org-entry-property-inherited-from (point))
-	       (throw 'exit nil))
-	      ((or (org-up-heading-safe)
-                   (and (not (bobp))
-                        (goto-char (point-min))
-                        nil)
-                   ;; `org-up-heading-safe' returned nil.  We are at low
-                   ;; level heading or bob.  If there is headline
-                   ;; there, do not try to fetch its properties.
-                   (and (bobp)
-                        (not at-bob-no-heading)
-                        (not (org-at-heading-p))
-                        (setq at-bob-no-heading t))))
-	      (t
-	       (let ((global (org--property-global-or-keyword-value property literal-nil)))
-	         (cond ((not global))
-		       (value (setq value (concat global " " value)))
-		       (t (setq value global))))
-	       (throw 'exit nil)))))))
+       (let ((element (or element
+                          (and (org-element--cache-active-p)
+                               (org-element-at-point nil 'cached)))))
+         (if element
+             (let ((element (org-element-lineage element '(headline org-data inlinetask) 'with-self)))
+               (while t
+                 (let* ((v (org--property-local-values property literal-nil element))
+                        (v (if (listp v) v (list v))))
+                   (when v
+                     (setq value
+                           (concat (mapconcat #'identity (delq nil v) " ")
+                                   (and value " ")
+                                   value)))
+                   (cond
+	            ((car v)
+	             (move-marker org-entry-property-inherited-from (org-element-property :begin element))
+	             (throw 'exit nil))
+	            ((org-element-property :parent element)
+                     (setq element (org-element-property :parent element)))
+	            (t
+	             (let ((global (org--property-global-or-keyword-value property literal-nil)))
+	               (cond ((not global))
+		             (value (setq value (concat global " " value)))
+		             (t (setq value global))))
+	             (throw 'exit nil))))))
+           (while t
+	     (let ((v (org--property-local-values property literal-nil)))
+	       (when v
+	         (setq value
+		       (concat (mapconcat #'identity (delq nil v) " ")
+			       (and value " ")
+			       value)))
+	       (cond
+	        ((car v)
+	         (org-back-to-heading-or-point-min t)
+	         (move-marker org-entry-property-inherited-from (point))
+	         (throw 'exit nil))
+	        ((or (org-up-heading-safe)
+                     (and (not (bobp))
+                          (goto-char (point-min))
+                          nil)
+                     ;; `org-up-heading-safe' returned nil.  We are at low
+                     ;; level heading or bob.  If there is headline
+                     ;; there, do not try to fetch its properties.
+                     (and (bobp)
+                          (not at-bob-no-heading)
+                          (not (org-at-heading-p))
+                          (setq at-bob-no-heading t))))
+	        (t
+	         (let ((global (org--property-global-or-keyword-value property literal-nil)))
+	           (cond ((not global))
+		         (value (setq value (concat global " " value)))
+		         (t (setq value global))))
+	         (throw 'exit nil))))))))
      (if literal-nil value (org-not-nil value)))))
      (if literal-nil value (org-not-nil value)))))
 
 
 (defvar org-property-changed-functions nil
 (defvar org-property-changed-functions nil
@@ -20711,25 +20714,26 @@ unless optional argument NO-INHERITANCE is non-nil.
 
 
 Optional argument ELEMENT contains element at point."
 Optional argument ELEMENT contains element at point."
   (save-match-data
   (save-match-data
-    (if-let ((el (or element (org-element-at-point nil 'cached))))
-        (catch :found
-          (setq el (org-element-lineage el '(headline) 'include-self))
-          (if no-inheritance
-              (org-element-property :commentedp el)
-            (while el
-              (when (org-element-property :commentedp el)
-                (throw :found t))
-              (setq el (org-element-property :parent el)))))
-      (cond
-       ((org-before-first-heading-p) nil)
-       ((let ((headline (nth 4 (org-heading-components))))
-          (and headline
-	       (let ((case-fold-search nil))
-	         (string-match-p (concat "^" org-comment-string "\\(?: \\|$\\)")
-			         headline)))))
-       (no-inheritance nil)
-       (t
-        (save-excursion (and (org-up-heading-safe) (org-in-commented-heading-p))))))))
+    (let ((el (or element (org-element-at-point nil 'cached))))
+      (if el
+          (catch :found
+            (setq el (org-element-lineage el '(headline) 'include-self))
+            (if no-inheritance
+                (org-element-property :commentedp el)
+              (while el
+                (when (org-element-property :commentedp el)
+                  (throw :found t))
+                (setq el (org-element-property :parent el)))))
+        (cond
+         ((org-before-first-heading-p) nil)
+         ((let ((headline (nth 4 (org-heading-components))))
+            (and headline
+	         (let ((case-fold-search nil))
+	           (string-match-p (concat "^" org-comment-string "\\(?: \\|$\\)")
+			           headline)))))
+         (no-inheritance nil)
+         (t
+          (save-excursion (and (org-up-heading-safe) (org-in-commented-heading-p)))))))))
 
 
 (defun org-in-archived-heading-p (&optional no-inheritance element)
 (defun org-in-archived-heading-p (&optional no-inheritance element)
   "Non-nil if point is under an archived heading.
   "Non-nil if point is under an archived heading.
@@ -20809,42 +20813,43 @@ headline found, or nil if no higher level is found.
 Also, this function will be a lot faster than `outline-up-heading',
 Also, this function will be a lot faster than `outline-up-heading',
 because it relies on stars being the outline starters.  This can really
 because it relies on stars being the outline starters.  This can really
 make a significant difference in outlines with very many siblings."
 make a significant difference in outlines with very many siblings."
-  (if-let ((element (and (org-element--cache-active-p)
-                         (org-element-at-point nil t))))
-      (let* ((current-heading (org-element-lineage element '(headline) 'with-self))
-             (parent (org-element-lineage current-heading '(headline))))
-        (if (and parent
-                 (<= (point-min) (org-element-property :begin parent)))
-            (progn
-              (goto-char (org-element-property :begin parent))
-              (org-element-property :level parent))
-          (when (and current-heading
-                     (<= (point-min) (org-element-property :begin current-heading)))
-            (goto-char (org-element-property :begin current-heading))
-            nil)))
-    (when (ignore-errors (org-back-to-heading t))
-      (let (level-cache)
-        (unless org--up-heading-cache
-          (setq org--up-heading-cache (make-hash-table)))
-        (if (and (eq (buffer-chars-modified-tick) org--up-heading-cache-tick)
-                 (setq level-cache (gethash (point) org--up-heading-cache)))
-            (when (<= (point-min) (car level-cache) (point-max))
-              ;; Parent is inside accessible part of the buffer.
-              (progn (goto-char (car level-cache))
-                     (cdr level-cache)))
-          ;; Buffer modified.  Invalidate cache.
-          (unless (eq (buffer-chars-modified-tick) org--up-heading-cache-tick)
-            (setq-local org--up-heading-cache-tick
-                        (buffer-chars-modified-tick))
-            (clrhash org--up-heading-cache))
-          (let* ((level-up (1- (funcall outline-level)))
-                 (pos (point))
-                 (result (and (> level-up 0)
-	                      (re-search-backward
-                               (format "^\\*\\{1,%d\\} " level-up) nil t)
-	                      (funcall outline-level))))
-            (when result (puthash pos (cons (point) result) org--up-heading-cache))
-            result))))))
+  (let ((element (and (org-element--cache-active-p)
+                      (org-element-at-point nil t))))
+    (if element
+        (let* ((current-heading (org-element-lineage element '(headline) 'with-self))
+               (parent (org-element-lineage current-heading '(headline))))
+          (if (and parent
+                   (<= (point-min) (org-element-property :begin parent)))
+              (progn
+                (goto-char (org-element-property :begin parent))
+                (org-element-property :level parent))
+            (when (and current-heading
+                       (<= (point-min) (org-element-property :begin current-heading)))
+              (goto-char (org-element-property :begin current-heading))
+              nil)))
+      (when (ignore-errors (org-back-to-heading t))
+        (let (level-cache)
+          (unless org--up-heading-cache
+            (setq org--up-heading-cache (make-hash-table)))
+          (if (and (eq (buffer-chars-modified-tick) org--up-heading-cache-tick)
+                   (setq level-cache (gethash (point) org--up-heading-cache)))
+              (when (<= (point-min) (car level-cache) (point-max))
+                ;; Parent is inside accessible part of the buffer.
+                (progn (goto-char (car level-cache))
+                       (cdr level-cache)))
+            ;; Buffer modified.  Invalidate cache.
+            (unless (eq (buffer-chars-modified-tick) org--up-heading-cache-tick)
+              (setq-local org--up-heading-cache-tick
+                          (buffer-chars-modified-tick))
+              (clrhash org--up-heading-cache))
+            (let* ((level-up (1- (funcall outline-level)))
+                   (pos (point))
+                   (result (and (> level-up 0)
+	                        (re-search-backward
+                                 (format "^\\*\\{1,%d\\} " level-up) nil t)
+	                        (funcall outline-level))))
+              (when result (puthash pos (cons (point) result) org--up-heading-cache))
+              result)))))))
 
 
 (defun org-up-heading-or-point-min ()
 (defun org-up-heading-or-point-min ()
   "Move to the heading line of which the present is a subheading, or point-min.
   "Move to the heading line of which the present is a subheading, or point-min.
@@ -20906,20 +20911,21 @@ move point."
 Return t when a child was found.  Otherwise don't move point and
 Return t when a child was found.  Otherwise don't move point and
 return nil."
 return nil."
   (if (org-element--cache-active-p)
   (if (org-element--cache-active-p)
-      (when-let ((heading (org-element-lineage
-                           (or element (org-element-at-point))
-                           '(headline inlinetask org-data)
-                           t)))
-        (unless (or (eq 'inlinetask (org-element-type heading))
-                    (not (org-element-property :contents-begin heading)))
-          (let ((pos (point)))
-            (goto-char (org-element-property :contents-begin heading))
-            (if (re-search-forward
-                 org-outline-regexp-bol
-                 (org-element-property :end heading)
-                 t)
-                (progn (goto-char (match-beginning 0)) t)
-              (goto-char pos) nil))))
+      (let ((heading (org-element-lineage
+                      (or element (org-element-at-point))
+                      '(headline inlinetask org-data)
+                      t)))
+        (when heading
+          (unless (or (eq 'inlinetask (org-element-type heading))
+                      (not (org-element-property :contents-begin heading)))
+            (let ((pos (point)))
+              (goto-char (org-element-property :contents-begin heading))
+              (if (re-search-forward
+                   org-outline-regexp-bol
+                   (org-element-property :end heading)
+                   t)
+                  (progn (goto-char (match-beginning 0)) t)
+                (goto-char pos) nil)))))
     (let (level (pos (point)) (re org-outline-regexp-bol))
     (let (level (pos (point)) (re org-outline-regexp-bol))
       (when (org-back-to-heading-or-point-min t)
       (when (org-back-to-heading-or-point-min t)
         (setq level (org-outline-level))
         (setq level (org-outline-level))

+ 7 - 2
testing/org-test.el

@@ -466,8 +466,13 @@ TIME can be a non-nil Lisp time value, or a string specifying a date and time."
 	       (apply ,(symbol-function 'current-time-zone)
 	       (apply ,(symbol-function 'current-time-zone)
 		      (or time ,at) args)))
 		      (or time ,at) args)))
 	    ((symbol-function 'decode-time)
 	    ((symbol-function 'decode-time)
-	     (lambda (&optional time zone form) (funcall ,(symbol-function 'decode-time)
-					            (or time ,at) zone form)))
+	     (lambda (&optional time zone form)
+               (condition-case err
+                   (funcall ,(symbol-function 'decode-time)
+			    (or time ,at) zone form)
+                 ;; Fallback for Emacs <27.1.
+                 (error (funcall ,(symbol-function 'decode-time)
+			         (or time ,at) zone)))))
 	    ((symbol-function 'encode-time)
 	    ((symbol-function 'encode-time)
 	     (lambda (time &rest args)
 	     (lambda (time &rest args)
 	       (apply ,(symbol-function 'encode-time) (or time ,at) args)))
 	       (apply ,(symbol-function 'encode-time) (or time ,at) args)))