Browse Source

Update custom properties handling

* lisp/org.el (org-toggle-custom-properties-visibility): Improve
correctness and speed.

* testing/lisp/test-org.el (test-org/custom-properties): New test.
Nicolas Goaziou 6 years ago
parent
commit
95c2c7f38c
2 changed files with 68 additions and 14 deletions
  1. 21 14
      lisp/org.el
  2. 47 0
      testing/lisp/test-org.el

+ 21 - 14
lisp/org.el

@@ -6405,21 +6405,28 @@ needs to be inserted at a specific position in the font-lock sequence.")
   "Display or hide properties in `org-custom-properties'."
   (interactive)
   (if org-custom-properties-overlays
-      (progn (mapc 'delete-overlay org-custom-properties-overlays)
+      (progn (mapc #'delete-overlay org-custom-properties-overlays)
 	     (setq org-custom-properties-overlays nil))
-    (unless (not org-custom-properties)
-      (save-excursion
-	(save-restriction
-	  (widen)
-	  (goto-char (point-min))
-	  (while (re-search-forward org-property-re nil t)
-	    (mapc (lambda(p)
-		    (when (equal p (substring (match-string 1) 1 -1))
-		      (let ((o (make-overlay (match-beginning 0) (1+ (match-end 0)))))
-			(overlay-put o 'invisible t)
-			(overlay-put o 'org-custom-property t)
-			(push o org-custom-properties-overlays))))
-		  org-custom-properties)))))))
+    (when org-custom-properties
+      (org-with-wide-buffer
+       (goto-char (point-min))
+       (let ((regexp (org-re-property (regexp-opt org-custom-properties) t t)))
+	 (while (re-search-forward regexp nil t)
+	   (let ((end (cdr (save-match-data (org-get-property-block)))))
+	     (when (and end (< (point) end))
+	       ;; Hide first custom property in current drawer.
+	       (let ((o (make-overlay (match-beginning 0) (1+ (match-end 0)))))
+		 (overlay-put o 'invisible t)
+		 (overlay-put o 'org-custom-property t)
+		 (push o org-custom-properties-overlays))
+	       ;; Hide additional custom properties in the same drawer.
+	       (while (re-search-forward regexp end t)
+		 (let ((o (make-overlay (match-beginning 0) (1+ (match-end 0)))))
+		   (overlay-put o 'invisible t)
+		   (overlay-put o 'org-custom-property t)
+		   (push o org-custom-properties-overlays)))))
+	   ;; Each entry is limited to a single property drawer.
+	   (outline-next-heading)))))))
 
 (defun org-fontify-entities (limit)
   "Find an entity to fontify."

+ 47 - 0
testing/lisp/test-org.el

@@ -1302,6 +1302,53 @@ drops support for Emacs 24.1 and 24.2."
     (org-babel-next-src-block)
     (should (equal '(2 1) (org-babel-execute-src-block)))))
 
+(ert-deftest test-org/custom-properties ()
+  "Test custom properties specifications."
+  ;; Standard test.
+  (should
+   (let ((org-custom-properties '("FOO")))
+     (org-test-with-temp-text "* H\n:PROPERTIES:\n<point>:FOO: val\n:END:\n"
+       (org-toggle-custom-properties-visibility)
+       (org-invisible-p2))))
+  ;; Properties are case-insensitive.
+  (should
+   (let ((org-custom-properties '("FOO")))
+     (org-test-with-temp-text "* H\n:PROPERTIES:\n<point>:foo: val\n:END:\n"
+       (org-toggle-custom-properties-visibility)
+       (org-invisible-p2))))
+  (should
+   (let ((org-custom-properties '("foo")))
+     (org-test-with-temp-text "* H\n:PROPERTIES:\n<point>:FOO: val\n:END:\n"
+       (org-toggle-custom-properties-visibility)
+       (org-invisible-p2))))
+  ;; Multiple custom properties in the same drawer.
+  (should
+   (let ((org-custom-properties '("FOO" "BAR")))
+     (org-test-with-temp-text
+	 "* H\n:PROPERTIES:\n<point>:FOO: val\n:P: 1\n:BAR: baz\n:END:\n"
+       (org-toggle-custom-properties-visibility)
+       (and (org-invisible-p2)
+	    (not (progn (forward-line) (org-invisible-p2)))
+	    (progn (forward-line) (org-invisible-p2))))))
+  ;; Hide custom properties with an empty value.
+  (should
+   (let ((org-custom-properties '("FOO")))
+     (org-test-with-temp-text "* H\n:PROPERTIES:\n<point>:FOO:\n:END:\n"
+       (org-toggle-custom-properties-visibility)
+       (org-invisible-p2))))
+  ;; Do not hide fake properties.
+  (should-not
+   (let ((org-custom-properties '("FOO")))
+     (org-test-with-temp-text ":FOO: val\n"
+       (org-toggle-custom-properties-visibility)
+       (org-invisible-p2))))
+  (should-not
+   (let ((org-custom-properties '("A")))
+     (org-test-with-temp-text
+	 "* H\n:PROPERTIES:\n:A: 1\n:END:\n\n:PROPERTIES:\n<point>:A: 2\n:END:"
+       (org-toggle-custom-properties-visibility)
+       (org-invisible-p2)))))
+
 
 
 ;;; Mark Region