Browse Source

Implement `org-find-property'

* lisp/org.el (org-find-property): New function.
* testing/lisp/test-org.el (test-org/find-property): New test.
Nicolas Goaziou 10 years ago
parent
commit
7072dba04d
2 changed files with 68 additions and 0 deletions
  1. 20 0
      lisp/org.el
  2. 48 0
      testing/lisp/test-org.el

+ 20 - 0
lisp/org.el

@@ -16195,6 +16195,26 @@ in the current file."
     (unless (equal (org-entry-get nil property) value)
       (org-entry-put nil property value))))
 
+(defun org-find-property (property &optional value)
+  "Find first entry in buffer that sets PROPERTY.
+
+When optional argument VALUE is non-nil, only consider an entry
+if it contains PROPERTY set to this value.  If PROPERTY should be
+explicitly set to nil, use string \"nil\" for VALUE.
+
+Return position where the entry begins, or nil if there is no
+such entry.  If narrowing is in effect, only search the visible
+part of the buffer."
+  (save-excursion
+    (goto-char (point-min))
+    (let ((case-fold-search t)
+	  (re (org-re-property property nil (not value))))
+      (catch 'exit
+	(while (re-search-forward re nil t)
+	  (when (if value (equal value (org-entry-get (point) property nil t))
+		  (org-entry-get (point) property nil t))
+	    (throw 'exit (progn (org-back-to-heading t) (point)))))))))
+
 (defun org-delete-property (property)
   "In the current entry, delete PROPERTY."
   (interactive

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

@@ -2642,6 +2642,54 @@ Text.
 	  (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:A+: 2\n:END:"
 	    (org-property-values "A")))))
 
+(ert-deftest test-org/find-property ()
+  "Test `org-find-property' specifications."
+  ;; Regular test.
+  (should
+   (= 1
+      (org-test-with-temp-text "* H\n:PROPERTIES:\n:PROP: value\n:END:"
+	(org-find-property "prop"))))
+  ;; Ignore false positives.
+  (should
+   (= 27
+      (org-test-with-temp-text
+	  "* H1\n:DRAWER:\n:A: 1\n:END:\n* H2\n:PROPERTIES:\n:A: 1\n:END:"
+	(org-find-property "A"))))
+  ;; Return first entry found in buffer.
+  (should
+   (= 1
+      (org-test-with-temp-text
+	  "* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2\n:PROPERTIES:\n:<point>A: 1\n:END:"
+	(org-find-property "A"))))
+  ;; Only search visible part of the buffer.
+  (should
+   (= 31
+      (org-test-with-temp-text
+	  "* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2\n:PROPERTIES:\n:<point>A: 1\n:END:"
+	(org-narrow-to-subtree)
+	(org-find-property "A"))))
+  ;; With optional argument, only find entries with a specific value.
+  (should-not
+   (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:"
+     (org-find-property "A" "2")))
+  (should
+   (= 31
+      (org-test-with-temp-text
+	  "* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2\n:PROPERTIES:\n:A: 2\n:END:"
+	(org-find-property "A" "2"))))
+  ;; Use "nil" for explicit nil values.
+  (should
+   (= 31
+      (org-test-with-temp-text
+	  "* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2\n:PROPERTIES:\n:A: nil\n:END:"
+	(org-find-property "A" "nil"))))
+  ;; Optional argument is matched against real value, including PROP+
+  ;; syntax.
+  (should
+   (= 1
+      (org-test-with-temp-text "* H1\n:PROPERTIES:\n:A: 1\n:A+: 2\n:END:"
+	(org-find-property "A" "1 2")))))
+
 (ert-deftest test-org/entry-delete ()
   "Test `org-entry-delete' specifications."
   ;; Regular test.