Browse Source

Remove need to declare drawers before using them

* lisp/org-agenda.el (org-agenda-prepare): Remove reference to
  `org-drawers-for-agenda'.
(org-agenda-show-1): Remove reference to `org-drawers'.
* lisp/org-clock.el (org-clock-remove-empty-clock-drawer,
  org-clock-cancel): Apply signature change to
  `org-remove-empty-drawer-at'.
* lisp/org-element.el (org-element--list-struct): Use
  `org-drawer-regexp' instead of `org-drawers'.
* lisp/org-feed.el (org-feed-drawer): Update docstring according to
  change.
* lisp/org-list.el (org-in-item-p, org-list-context): Use
  `org-drawer-regexp' instead of `org-drawers'.
* lisp/org-mobile.el (org-mobile-create-index-file): Remove reference
  to `org-drawers-for-agenda'.
* lisp/org-pcomplete.el (pcomplete/org-mode/drawer): Remove function.
* lisp/org.el (org-drawer-regexp): Make variable global.
(org-drawers): Remove variable.
(org-set-regexps-and-options): Ignore DRAWER keyword.
(org-cycle): Use `org-drawer-regexp' instead of `org-drawers'.
(org-cycle-hide-drawers): Add an optional argument to ignore some
drawers.
(org-remove-empty-drawer-at): Remove second argument.  Rewrite
function.
(org-clone-subtree-with-time-shift): Apply signature change to
`org-remove-empty-drawer-at'.
(org-toggle-ordered-property): Apply `org-delete-property' signature
change.
(org-map-entries): Remove reference to `org-drawers-for-agenda'.
(org-entry-delete): Remove optional argument.  Small refactoring.
(org-insert-drawer): Remove reference to `org-drawers'.
(org-delete-property): Apply `org-entry-delete' signature change.
(org-in-drawer-p): Rewrite function.
* testing/lisp/test-org-element.el: Update tests.
* testing/lisp/test-org.el: Update tests.
* testing/lisp/test-ox.el: Update tests.
Nicolas Goaziou 5 years ago
parent
commit
6202ec7b3b

+ 4 - 11
lisp/org-agenda.el

@@ -3642,7 +3642,6 @@ generating a new one."
 	(or org-agenda-multi (org-agenda-fit-window-to-buffer))
 	(throw 'exit "Sticky Agenda buffer, use `r' to refresh"))
     (setq org-todo-keywords-for-agenda nil)
-    (setq org-drawers-for-agenda nil)
     (unless org-agenda-persistent-filter
       (setq org-agenda-tag-filter nil
 	    org-agenda-category-filter nil
@@ -3682,7 +3681,6 @@ generating a new one."
 	    (org-uniquify org-todo-keywords-for-agenda))
       (setq org-done-keywords-for-agenda
 	    (org-uniquify org-done-keywords-for-agenda))
-      (setq org-drawers-for-agenda (org-uniquify org-drawers-for-agenda))
       (setq org-agenda-last-prefix-arg current-prefix-arg)
       (setq org-agenda-this-buffer-name org-agenda-buffer-name)
       (and name (not org-agenda-name)
@@ -8627,15 +8625,10 @@ if it was hidden in the outline."
 	(run-hook-with-args 'org-cycle-hook 'subtree))
       (message "Remote: SUBTREE"))
      ((= more 4)
-      (let* ((org-drawers (delete "LOGBOOK" (copy-sequence org-drawers)))
-	     (org-drawer-regexp
-	      (concat "^[ \t]*:\\("
-		      (mapconcat 'regexp-quote org-drawers "\\|")
-		      "\\):[ \t]*$")))
-	(show-subtree)
-	(save-excursion
-	  (org-back-to-heading)
-	  (org-cycle-hide-drawers 'subtree)))
+      (show-subtree)
+      (save-excursion
+	(org-back-to-heading)
+	(org-cycle-hide-drawers 'subtree '("LOGBOOK")))
       (message "Remote: SUBTREE AND LOGBOOK"))
      ((> more 4)
       (show-subtree)

+ 3 - 3
lisp/org-clock.el

@@ -1589,7 +1589,7 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
 	(while (and (< (point) end)
 		    (search-forward clock-drawer end t))
 	  (goto-char (match-beginning 0))
-	  (org-remove-empty-drawer-at clock-drawer (point))
+	  (org-remove-empty-drawer-at (point))
 	  (forward-line 1))))))
 
 (defun org-clock-timestamps-up (&optional n)
@@ -1653,12 +1653,12 @@ Optional argument N tells to change by that many units."
     (setq frame-title-format org-frame-title-format-backup)
     (force-mode-line-update)
     (error "No active clock"))
-  (save-excursion ; Do not replace this with `with-current-buffer'.
+  (save-excursion    ; Do not replace this with `with-current-buffer'.
     (org-no-warnings (set-buffer (org-clocking-buffer)))
     (goto-char org-clock-marker)
     (if (org-looking-back (concat "^[ \t]*" org-clock-string ".*"))
 	(progn (delete-region (1- (point-at-bol)) (point-at-eol))
-	       (org-remove-empty-drawer-at "LOGBOOK" (point)))
+	       (org-remove-empty-drawer-at (point)))
       (message "Clock gone, cancel the timer anyway")
       (sit-for 2)))
   (move-marker org-clock-marker nil)

+ 1 - 4
lisp/org-element.el

@@ -1146,9 +1146,6 @@ CONTENTS is the contents of the element."
   (let ((case-fold-search t)
 	(top-ind limit)
 	(item-re (org-item-re))
-	(drawers-re (concat ":\\("
-			    (mapconcat 'regexp-quote org-drawers "\\|")
-			    "\\):[ \t]*$"))
 	(inlinetask-re (and (featurep 'org-inlinetask) "^\\*+ "))
 	items struct)
     (save-excursion
@@ -1221,7 +1218,7 @@ CONTENTS is the contents of the element."
 		    (format "^[ \t]*#\\+END%s[ \t]*$"
 			    (org-match-string-no-properties 1))
 		    limit t)))
-	     ((and (looking-at drawers-re)
+	     ((and (looking-at org-drawer-regexp)
 		   (re-search-forward "^[ \t]*:END:[ \t]*$" limit t))))
 	    (forward-line))))))))
 

+ 1 - 4
lisp/org-feed.el

@@ -215,10 +215,7 @@ Here are the keyword-value pair allows in `org-feed-alist'.
 (defcustom org-feed-drawer "FEEDSTATUS"
   "The name of the drawer for feed status information.
 Each feed may also specify its own drawer name using the `:drawer'
-parameter in `org-feed-alist'.
-Note that in order to make these drawers behave like drawers, they must
-be added to the variable `org-drawers' or configured with a #+DRAWERS
-line."
+parameter in `org-feed-alist'."
   :group 'org-feed
   :type '(string :tag "Drawer Name"))
 

+ 6 - 19
lisp/org-list.el

@@ -88,7 +88,6 @@
 (defvar org-closed-string)
 (defvar org-deadline-string)
 (defvar org-description-max-indent)
-(defvar org-drawers)
 (defvar org-odd-levels-only)
 (defvar org-scheduled-string)
 (defvar org-ts-regexp)
@@ -430,9 +429,6 @@ group 4: description tag")
     (let* ((case-fold-search t)
 	   (context (org-list-context))
 	   (lim-up (car context))
-	   (drawers-re (concat "^[ \t]*:\\("
-			       (mapconcat 'regexp-quote org-drawers "\\|")
-			       "\\):[ \t]*$"))
 	   (inlinetask-re (and (featurep 'org-inlinetask)
 			       (org-inlinetask-outline-regexp)))
 	   (item-re (org-item-re))
@@ -476,7 +472,7 @@ group 4: description tag")
 	       ((and (looking-at "^[ \t]*#\\+end_")
 		     (re-search-backward "^[ \t]*#\\+begin_" lim-up t)))
 	       ((and (looking-at "^[ \t]*:END:")
-		     (re-search-backward drawers-re lim-up t))
+		     (re-search-backward org-drawer-regexp lim-up t))
 		(beginning-of-line))
 	       ((and inlinetask-re (looking-at inlinetask-re))
 		(org-inlinetask-goto-beginning)
@@ -547,11 +543,7 @@ Contexts `block' and `invalid' refer to `org-list-forbidden-blocks'."
 	     (lim-down (or (save-excursion (outline-next-heading)) (point-max))))
 	 ;; Is point inside a drawer?
 	 (let ((end-re "^[ \t]*:END:")
-	       ;; Can't use org-drawers-regexp as this function might
-	       ;; be called in buffers not in Org mode.
-	       (beg-re (concat "^[ \t]*:\\("
-			       (mapconcat 'regexp-quote org-drawers "\\|")
-			       "\\):[ \t]*$")))
+	       (beg-re org-drawer-regexp))
 	   (when (save-excursion
 		   (and (not (looking-at beg-re))
 			(not (looking-at end-re))
@@ -635,9 +627,6 @@ Assume point is at an item."
 	   (lim-down (nth 1 context))
 	   (text-min-ind 10000)
 	   (item-re (org-item-re))
-	   (drawers-re (concat "^[ \t]*:\\("
-			       (mapconcat 'regexp-quote org-drawers "\\|")
-			       "\\):[ \t]*$"))
 	   (inlinetask-re (and (featurep 'org-inlinetask)
 			       (org-inlinetask-outline-regexp)))
 	   (beg-cell (cons (point) (org-get-indentation)))
@@ -700,7 +689,7 @@ Assume point is at an item."
 	       ((and (looking-at "^[ \t]*#\\+end_")
 		     (re-search-backward "^[ \t]*#\\+begin_" lim-up t)))
 	       ((and (looking-at "^[ \t]*:END:")
-		     (re-search-backward drawers-re lim-up t))
+		     (re-search-backward org-drawer-regexp lim-up t))
 		(beginning-of-line))
 	       ((and inlinetask-re (looking-at inlinetask-re))
 		(org-inlinetask-goto-beginning)
@@ -766,7 +755,7 @@ Assume point is at an item."
 	      (cond
 	       ((and (looking-at "^[ \t]*#\\+begin_")
 		     (re-search-forward "^[ \t]*#\\+end_" lim-down t)))
-	       ((and (looking-at drawers-re)
+	       ((and (looking-at org-drawer-regexp)
 		     (re-search-forward "^[ \t]*:END:" lim-down t))))
 	      (forward-line 1))))))
       (setq struct (append itm-lst (cdr (nreverse itm-lst-2)))
@@ -2326,9 +2315,6 @@ in subtree, ignoring drawers."
 	   block-item
 	   lim-up
 	   lim-down
-	   (drawer-re (concat "^[ \t]*:\\("
-			      (mapconcat 'regexp-quote org-drawers "\\|")
-			      "\\):[ \t]*$"))
 	   (keyword-re (concat "^[ \t]*\\<\\(" org-scheduled-string
 			       "\\|" org-deadline-string
 			       "\\|" org-closed-string
@@ -2350,7 +2336,8 @@ in subtree, ignoring drawers."
 	      ;; time-stamps (scheduled, etc.).
 	      (let ((limit (save-excursion (outline-next-heading) (point))))
 		(forward-line 1)
-		(while (or (looking-at drawer-re) (looking-at keyword-re))
+		(while (or (looking-at org-drawer-regexp)
+			   (looking-at keyword-re))
 		  (if (looking-at keyword-re)
 		      (forward-line 1)
 		    (re-search-forward "^[ \t]*:END:" limit nil)))

+ 1 - 3
lisp/org-mobile.el

@@ -425,7 +425,7 @@ agenda view showing the flagged items."
 	(def-tags (default-value 'org-tag-alist))
 	(target-file (expand-file-name org-mobile-index-file
 				       org-mobile-directory))
-	file link-name todo-kwds done-kwds tags drawers entry kwds dwds twds)
+	file link-name todo-kwds done-kwds tags entry kwds dwds twds)
     (when (stringp (car def-todo))
       (setq def-todo (list (cons 'sequence def-todo))))
     (org-agenda-prepare-buffers (mapcar 'car files-alist))
@@ -433,7 +433,6 @@ agenda view showing the flagged items."
     (setq todo-kwds (org-delete-all
 		     done-kwds
 		     (org-uniquify org-todo-keywords-for-agenda)))
-    (setq drawers (org-uniquify org-drawers-for-agenda))
     (setq tags (mapcar 'car (org-global-tags-completion-table
 			     (mapcar 'car files-alist))))
     (with-temp-file
@@ -468,7 +467,6 @@ agenda view showing the flagged items."
       (setq tags (sort tags (lambda (a b) (string< (downcase a) (downcase b)))))
       (setq tags (append def-tags tags nil))
       (insert "#+TAGS: " (mapconcat 'identity tags " ") "\n")
-      (insert "#+DRAWERS: " (mapconcat 'identity drawers " ") "\n")
       (insert "#+ALLPRIORITIES: " org-mobile-allpriorities "\n")
       (when (file-exists-p (expand-file-name
 			    org-mobile-directory "agendas.org"))

+ 0 - 19
lisp/org-pcomplete.el

@@ -363,25 +363,6 @@ This needs more work, to handle headings with lots of spaces in them."
 	     lst))
    (substring pcomplete-stub 1)))
 
-(defvar org-drawers)
-
-(defun pcomplete/org-mode/drawer ()
-  "Complete a drawer name."
-  (let ((spc (save-excursion
-	       (move-beginning-of-line 1)
-	       (looking-at "^\\([ \t]*\\):")
-	       (match-string 1)))
-	(cpllist (mapcar (lambda (x) (concat x ": ")) org-drawers)))
-    (pcomplete-here cpllist
-		    (substring pcomplete-stub 1)
-		    (unless (or (not (delq
-				      nil
-				      (mapcar (lambda(x)
-						(string-match (substring pcomplete-stub 1) x))
-					      cpllist)))
-				(looking-at "[ \t]*\n.*:END:"))
-		      (save-excursion (insert "\n" spc ":END:"))))))
-
 (defun pcomplete/org-mode/block-option/src ()
   "Complete the arguments of a begin_src block.
 Complete a language in the first field, the header arguments and switches."

+ 49 - 92
lisp/org.el

@@ -884,6 +884,10 @@ An entry can be toggled between QUOTE and normal with
   :group 'org-keywords
   :type 'string)
 
+(defconst org-drawer-regexp "^[ \t]*:\\(\\(?:\\w\\|[-_]\\)+\\):[ \t]*$"
+  "Matches first line of a hidden block.
+Group 1 contains drawer's name.")
+
 (defconst org-repeat-re
   "<[0-9]\\{4\\}-[0-9][0-9]-[0-9][0-9] [^>\n]*?\\([.+]?\\+[0-9]+[hdwmy]\\(/[0-9]+[hdwmy]\\)?\\)"
   "Regular expression for specifying repeated events.
@@ -1072,23 +1076,6 @@ than its value."
 	  (const :tag "No limit" nil)
 	  (integer :tag "Maximum level")))
 
-(defcustom org-drawers '("PROPERTIES" "CLOCK" "LOGBOOK" "RESULTS")
-  "Names of drawers.  Drawers are not opened by cycling on the headline above.
-Drawers only open with a TAB on the drawer line itself.  A drawer looks like
-this:
-   :DRAWERNAME:
-   .....
-   :END:
-The drawer \"PROPERTIES\" is special for capturing properties through
-the property API.
-
-Drawers can be defined on the per-file basis with a line like:
-
-#+DRAWERS: HIDDEN STATE PROPERTIES"
-  :group 'org-structure
-  :group 'org-cycle
-  :type '(repeat (string :tag "Drawer Name")))
-
 (defcustom org-hide-block-startup nil
   "Non-nil means entering Org-mode will fold all blocks.
 This can also be set in on a per-file basis with
@@ -2346,7 +2333,6 @@ taken from the (otherwise obsolete) variable `org-todo-interpretation'."
 (make-variable-buffer-local 'org-todo-keywords-1)
 (defvar org-todo-keywords-for-agenda nil)
 (defvar org-done-keywords-for-agenda nil)
-(defvar org-drawers-for-agenda nil)
 (defvar org-todo-keyword-alist-for-agenda nil)
 (defvar org-tag-alist-for-agenda nil
   "Alist of all tags from all agenda files.")
@@ -4596,9 +4582,6 @@ Otherwise, these types are allowed:
 
 ;;; Variables for pre-computed regular expressions, all buffer local
 
-(defvar org-drawer-regexp "^[ \t]*:PROPERTIES:[ \t]*$"
-  "Matches first line of a hidden block.")
-(make-variable-buffer-local 'org-drawer-regexp)
 (defvar org-todo-regexp nil
   "Matches any of the TODO state keywords.")
 (make-variable-buffer-local 'org-todo-regexp)
@@ -4977,8 +4960,6 @@ Support for group tags is controlled by the option
 		(setq props (org-update-property-plist (match-string 1 value)
 						       (match-string 2 value)
 						       props))))
-	     ((equal key "DRAWERS")
-	      (setq drawers (delete-dups (append org-drawers (org-split-string value splitre)))))
 	     ((equal key "CONSTANTS")
 	      (org-table-set-constants))
 	     ((equal key "STARTUP")
@@ -5034,7 +5015,6 @@ Support for group tags is controlled by the option
 	(org-set-local 'org-lowest-priority  (nth 1 prio))
 	(org-set-local 'org-default-priority (nth 2 prio)))
       (and props (org-set-local 'org-file-properties (nreverse props)))
-      (and drawers (org-set-local 'org-drawers drawers))
       (and arch (org-set-local 'org-archive-location arch))
       (and links (setq org-link-abbrev-alist-local (nreverse links)))
       ;; Process the TODO keywords
@@ -5094,10 +5074,6 @@ Support for group tags is controlled by the option
 					    (length org-scheduled-string)
 					    (length org-clock-string)
 					    (length org-closed-string)))
-	    org-drawer-regexp
-	    (concat "^[ \t]*:\\("
-		    (mapconcat 'regexp-quote org-drawers "\\|")
-		    "\\):[ \t]*$")
 	    org-not-done-keywords
 	    (org-delete-all org-done-keywords (copy-sequence org-todo-keywords-1))
 	    org-todo-regexp
@@ -6624,11 +6600,10 @@ in special contexts.
        ((eq arg t) (org-cycle-internal-global))
 
        ;; Drawers: delegate to `org-flag-drawer'.
-       ((and org-drawers org-drawer-regexp
-	     (save-excursion
-	       (beginning-of-line 1)
-	       (looking-at org-drawer-regexp)))
-	(org-flag-drawer ; toggle block visibility
+       ((save-excursion
+	  (beginning-of-line 1)
+	  (looking-at org-drawer-regexp))
+	(org-flag-drawer		; toggle block visibility
 	 (not (get-char-property (match-end 0) 'invisible))))
 
        ;; Show-subtree, ARG levels up from here.
@@ -7058,8 +7033,10 @@ open and agenda-wise Org files."
   "Return the end position of the current entry."
   (save-excursion (outline-next-heading) (point)))
 
-(defun org-cycle-hide-drawers (state)
-  "Re-hide all drawers after a visibility state change."
+(defun org-cycle-hide-drawers (state &optional exceptions)
+  "Re-hide all drawers after a visibility state change.
+When non-nil, optional argument EXCEPTIONS is a list of strings
+specifying which drawers should not be hidden."
   (when (and (derived-mode-p 'org-mode)
 	     (not (memq state '(overview folded contents))))
     (save-excursion
@@ -7071,7 +7048,8 @@ open and agenda-wise Org files."
 		      (org-end-of-subtree t)))))
 	(goto-char beg)
 	(while (re-search-forward org-drawer-regexp end t)
-	  (org-flag-drawer t))))))
+	  (unless (member-ignore-case (match-string 1) exceptions)
+	    (org-flag-drawer t)))))))
 
 (defun org-cycle-hide-inline-tasks (state)
   "Re-hide inline task when switching to 'contents visibility state."
@@ -8523,8 +8501,7 @@ and still retain the repeater to cover future instances of the task."
 		(kill-whole-line))
 	      (goto-char (point-min))
 	      (while (re-search-forward drawer-re nil t)
-		(mapc (lambda (d)
-			(org-remove-empty-drawer-at d (point))) org-drawers)))
+		(org-remove-empty-drawer-at (point))))
 	    (goto-char (point-min))
 	    (when doshift
 	      (while (re-search-forward org-ts-regexp-both nil t)
@@ -12454,7 +12431,7 @@ See variable `org-track-ordered-property-with-tag'."
       (org-back-to-heading)
       (if (org-entry-get nil "ORDERED")
 	  (progn
-	    (org-delete-property "ORDERED" "PROPERTIES")
+	    (org-delete-property "ORDERED")
 	    (and tag (org-toggle-tag tag 'off))
 	    (message "Subtasks can be completed in arbitrary order"))
 	(org-entry-put nil "ORDERED" "t")
@@ -13371,9 +13348,7 @@ EXTRA is additional text that will be inserted into the notes buffer."
       (push note lines))
     (when (or current-prefix-arg org-note-abort)
       (when org-log-into-drawer
-	(org-remove-empty-drawer-at
-	 (if (stringp org-log-into-drawer) org-log-into-drawer "LOGBOOK")
-	 org-log-note-marker))
+	(org-remove-empty-drawer-at org-log-note-marker))
       (setq lines nil))
     (when lines
       (with-current-buffer (marker-buffer org-log-note-marker)
@@ -13418,17 +13393,20 @@ EXTRA is additional text that will be inserted into the notes buffer."
     (move-marker org-log-note-return-to nil)
     (and org-log-post-message (message "%s" org-log-post-message))))
 
-(defun org-remove-empty-drawer-at (drawer pos)
-  "Remove an empty drawer DRAWER at position POS.
+(defun org-remove-empty-drawer-at (pos)
+  "Remove an empty drawer at position POS.
 POS may also be a marker."
   (with-current-buffer (if (markerp pos) (marker-buffer pos) (current-buffer))
-    (save-excursion
-      (save-restriction
-	(widen)
-	(goto-char pos)
-	(if (org-in-regexp
-	     (concat "^[ \t]*:" drawer ":[ \t]*\n[ \t]*:END:[ \t]*\n?") 2)
-	    (replace-match ""))))))
+    (org-with-wide-buffer
+     (goto-char pos)
+     (let ((drawer (org-element-at-point)))
+       (when (and (memq (org-element-type drawer) '(drawer property-drawer))
+		  (not (org-element-property :contents-begin drawer)))
+	 (delete-region (org-element-property :begin drawer)
+			(progn (goto-char (org-element-property :end drawer))
+			       (skip-chars-backward " \r\t\n")
+			       (forward-line)
+			       (point))))))))
 
 (defvar org-ts-type nil)
 (defun org-sparse-tree (&optional arg type)
@@ -14954,7 +14932,6 @@ a *different* entry, you cannot use these techniques."
 	   org-todo-keywords-for-agenda
 	   org-done-keywords-for-agenda
 	   org-todo-keyword-alist-for-agenda
-	   org-drawers-for-agenda
 	   org-tag-alist-for-agenda
 	   todo-only)
 
@@ -15336,13 +15313,10 @@ If yes, return this value.  If not, return the current value of the variable."
 	(read prop)
       (symbol-value var))))
 
-(defun org-entry-delete (pom property &optional delete-empty-drawer)
-  "Delete the property PROPERTY from entry at point-or-marker POM.
-When optional argument DELETE-EMPTY-DRAWER is a string, it defines
-an empty drawer to delete."
-  (org-with-point-at pom
-    (if (member property org-special-properties)
-	nil ; cannot delete these properties.
+(defun org-entry-delete (pom property)
+  "Delete the property PROPERTY from entry at point-or-marker POM."
+  (unless (member property org-special-properties)
+    (org-with-point-at pom
       (let ((range (org-get-property-block)))
 	(if (and range
 		 (goto-char (car range))
@@ -15351,9 +15325,7 @@ an empty drawer to delete."
 		  (cdr range) t))
 	    (progn
 	      (delete-region (match-beginning 0) (1+ (point-at-eol)))
-	      (and delete-empty-drawer
-		   (org-remove-empty-drawer-at
-		    delete-empty-drawer (car range)))
+	      (org-remove-empty-drawer-at (car range))
 	      t)
 	  nil)))))
 
@@ -15632,23 +15604,14 @@ instead.
 
 Point is left between drawer's boundaries."
   (interactive "P")
-  (let* ((logbook (if (stringp org-log-into-drawer) org-log-into-drawer
-		    "LOGBOOK"))
-	 ;; SYSTEM-DRAWERS is a list of drawer names that are used
-	 ;; internally by Org.  They are meant to be inserted
-	 ;; automatically.
-	 (system-drawers `("CLOCK" ,logbook "PROPERTIES"))
-	 ;; Remove system drawers from list.  Note: For some reason,
-	 ;; `org-completing-read' ignores the predicate while
-	 ;; `completing-read' handles it fine.
-	 (drawer (if arg "PROPERTIES"
-		   (or drawer
-		       (completing-read
-			"Drawer: " org-drawers
-			(lambda (d) (not (member d system-drawers))))))))
+  (let* ((drawer (if arg "PROPERTIES"
+		   (or drawer (read-from-minibuffer "Drawer: ")))))
     (cond
      ;; With C-u, fall back on `org-insert-property-drawer'
      (arg (org-insert-property-drawer))
+     ;;
+     ((not (org-string-match-p org-drawer-regexp (format ":%s:" drawer)))
+      (user-error "Invalid drawer name"))
      ;; With an active region, insert a drawer at point.
      ((not (org-region-active-p))
       (progn
@@ -15784,17 +15747,15 @@ in the current file."
     (unless (equal (org-entry-get nil property) value)
       (org-entry-put nil property value))))
 
-(defun org-delete-property (property &optional delete-empty-drawer)
-  "In the current entry, delete PROPERTY.
-When optional argument DELETE-EMPTY-DRAWER is a string, it defines
-an empty drawer to delete."
+(defun org-delete-property (property)
+  "In the current entry, delete PROPERTY."
   (interactive
    (let* ((completion-ignore-case t)
 	  (prop (org-icompleting-read "Property: "
 				      (org-entry-properties nil 'standard))))
      (list prop)))
   (message "Property %s %s" property
-	   (if (org-entry-delete nil property delete-empty-drawer)
+	   (if (org-entry-delete nil property)
 	       "deleted"
 	     "was not present in the entry")))
 
@@ -18081,8 +18042,6 @@ When a buffer is unmodified, it is just killed.  When modified, it is saved
 		  (append org-done-keywords-for-agenda org-done-keywords))
 	    (setq org-todo-keyword-alist-for-agenda
 		  (append org-todo-keyword-alist-for-agenda org-todo-key-alist))
-	    (setq org-drawers-for-agenda
-		  (append org-drawers-for-agenda org-drawers))
 	    (setq org-tag-alist-for-agenda
 		  (org-uniquify
 		   (append org-tag-alist-for-agenda
@@ -21679,15 +21638,13 @@ block from point."
       nil)))
 
 (defun org-in-drawer-p ()
-  "Is point within a drawer?"
-  (save-match-data
-    (let ((case-fold-search t)
-	  (lim-up (save-excursion (outline-previous-heading)))
-	  (lim-down (save-excursion (outline-next-heading))))
-      (org-between-regexps-p
-       (concat "^[ \t]*:" (regexp-opt org-drawers) ":")
-       "^[ \t]*:end:.*$"
-       lim-up lim-down))))
+  "Non-nil if point is within a drawer.
+If point is within a drawer, return it, as parsed data."
+  (let ((element (save-match-data (org-element-at-point))))
+    (while (and element (not (memq (org-element-type element)
+				   '(drawer property-drawer))))
+      (setq element (org-element-property :parent element)))
+    element))
 
 (defun org-occur-in-agenda-files (regexp &optional nlines)
   "Call `multi-occur' with buffers for all agenda files."

+ 22 - 35
testing/lisp/test-org-element.el

@@ -415,21 +415,18 @@ Some other text
   "Test `drawer' parser."
   ;; Standard test.
   (should
-   (let ((org-drawers '("TEST")))
-     (org-test-with-temp-text ":TEST:\nText\n:END:"
-       (org-element-map (org-element-parse-buffer) 'drawer 'identity))))
+   (org-test-with-temp-text ":TEST:\nText\n:END:"
+     (org-element-map (org-element-parse-buffer) 'drawer 'identity)))
   ;; Do not mix regular drawers and property drawers.
   (should-not
-   (let ((org-drawers '("PROPERTIES")))
-     (org-test-with-temp-text ":PROPERTIES:\n:prop: value\n:END:"
-       (org-element-map
-	(org-element-parse-buffer) 'drawer 'identity nil t))))
+   (org-test-with-temp-text ":PROPERTIES:\n:prop: value\n:END:"
+     (org-element-map
+	 (org-element-parse-buffer) 'drawer 'identity nil t)))
   ;; Ignore incomplete drawer.
   (should-not
-   (let ((org-drawers '("TEST")))
-     (org-test-with-temp-text ":TEST:"
-       (org-element-map
-	(org-element-parse-buffer) 'drawer 'identity nil t)))))
+   (org-test-with-temp-text ":TEST:"
+     (org-element-map
+	 (org-element-parse-buffer) 'drawer 'identity nil t))))
 
 
 ;;;; Dynamic Block
@@ -1403,16 +1400,10 @@ e^{i\\pi}+1=0
      (org-element-map (org-element-parse-buffer) 'paragraph 'identity)))
   ;; Include incomplete-drawers.
   (should
-   (let ((org-drawers '("TEST")))
-     (org-test-with-temp-text ":TEST:\nParagraph"
-       (let ((elem (org-element-at-point)))
-	 (and (eq (org-element-type elem) 'paragraph)
-	      (= (point-max) (org-element-property :end elem)))))))
-  ;; Include non-existent drawers.
-  (should
-   (let ((org-drawers '("TEST")))
-     (org-test-with-temp-text ":NONAME:"
-       (org-element-map (org-element-parse-buffer) 'paragraph 'identity))))
+   (org-test-with-temp-text ":TEST:\nParagraph"
+     (let ((elem (org-element-at-point)))
+       (and (eq (org-element-type elem) 'paragraph)
+	    (= (point-max) (org-element-property :end elem))))))
   ;; Include incomplete blocks.
   (should
    (org-test-with-temp-text "#+BEGIN_CENTER\nParagraph"
@@ -1505,22 +1496,19 @@ Outside list"
   "Test `property-drawer' parser."
   ;; Standard test.
   (should
-   (let ((org-drawers '("PROPERTIES")))
-     (org-test-with-temp-text ":PROPERTIES:\n:prop: value\n:END:"
-       (org-element-map
-	(org-element-parse-buffer) 'property-drawer 'identity nil t))))
+   (org-test-with-temp-text ":PROPERTIES:\n:prop: value\n:END:"
+     (org-element-map
+	 (org-element-parse-buffer) 'property-drawer 'identity nil t)))
   ;; Do not mix property drawers and regular drawers.
   (should-not
-   (let ((org-drawers '("TEST")))
-     (org-test-with-temp-text ":TEST:\n:prop: value\n:END:"
-       (org-element-map
-	(org-element-parse-buffer) 'property-drawer 'identity nil t))))
+   (org-test-with-temp-text ":TEST:\n:prop: value\n:END:"
+     (org-element-map
+	 (org-element-parse-buffer) 'property-drawer 'identity nil t)))
   ;; Ignore incomplete drawer.
   (should-not
-   (let ((org-drawers '("PROPERTIES")))
-     (org-test-with-temp-text ":PROPERTIES:\n:prop: value"
-       (org-element-map
-	(org-element-parse-buffer) 'property-drawer 'identity nil t)))))
+   (org-test-with-temp-text ":PROPERTIES:\n:prop: value"
+     (org-element-map
+	 (org-element-parse-buffer) 'property-drawer 'identity nil t))))
 
 
 ;;;; Quote Block
@@ -1965,8 +1953,7 @@ Outside list"
 (ert-deftest test-org-element/drawer-interpreter ()
   "Test drawer interpreter."
   (should
-   (equal (let ((org-drawers '("TEST")))
-	    (org-test-parse-and-interpret ":TEST:\nTest\n:END:"))
+   (equal (org-test-parse-and-interpret ":TEST:\nTest\n:END:")
 	  ":TEST:\nTest\n:END:\n")))
 
 (ert-deftest test-org-element/dynamic-block-interpreter ()

+ 10 - 12
testing/lisp/test-org.el

@@ -392,20 +392,18 @@
      (looking-at "- $")))
   ;; In a drawer and paragraph insert an empty line, in this case above.
   (should
-   (let ((org-drawers '("MYDRAWER")))
-     (org-test-with-temp-text ":MYDRAWER:\na\n:END:"
-       (forward-line)
-       (org-meta-return)
-       (forward-line -1)
-       (looking-at "$"))))
+   (org-test-with-temp-text ":MYDRAWER:\na\n:END:"
+     (forward-line)
+     (org-meta-return)
+     (forward-line -1)
+     (looking-at "$")))
   ;; In a drawer and item insert an item, in this case above.
   (should
-   (let ((org-drawers '("MYDRAWER")))
-     (org-test-with-temp-text ":MYDRAWER:\n- a\n:END:"
-       (forward-line)
-       (org-meta-return)
-       (beginning-of-line)
-       (looking-at "- $")))))
+   (org-test-with-temp-text ":MYDRAWER:\n- a\n:END:"
+     (forward-line)
+     (org-meta-return)
+     (beginning-of-line)
+     (looking-at "- $"))))
 
 (ert-deftest test-org/insert-todo-heading-respect-content ()
   "Test `org-insert-todo-heading-respect-content' specifications."

+ 12 - 16
testing/lisp/test-ox.el

@@ -414,28 +414,24 @@ Paragraph"
   ;; Drawers.
   (should
    (equal ""
-	  (let ((org-drawers '("TEST")))
-	    (org-test-with-temp-text ":TEST:\ncontents\n:END:"
-	      (org-export-as (org-test-default-backend)
-			     nil nil nil '(:with-drawers nil))))))
+	  (org-test-with-temp-text ":TEST:\ncontents\n:END:"
+	    (org-export-as (org-test-default-backend)
+			   nil nil nil '(:with-drawers nil)))))
   (should
    (equal ":TEST:\ncontents\n:END:\n"
-	  (let ((org-drawers '("TEST")))
-	    (org-test-with-temp-text ":TEST:\ncontents\n:END:"
-	      (org-export-as (org-test-default-backend)
-			     nil nil nil '(:with-drawers t))))))
+	  (org-test-with-temp-text ":TEST:\ncontents\n:END:"
+	    (org-export-as (org-test-default-backend)
+			   nil nil nil '(:with-drawers t)))))
   (should
    (equal ":FOO:\nkeep\n:END:\n"
-	  (let ((org-drawers '("FOO" "BAR")))
-	    (org-test-with-temp-text ":FOO:\nkeep\n:END:\n:BAR:\nremove\n:END:"
-	      (org-export-as (org-test-default-backend)
-			     nil nil nil '(:with-drawers ("FOO")))))))
+	  (org-test-with-temp-text ":FOO:\nkeep\n:END:\n:BAR:\nremove\n:END:"
+	    (org-export-as (org-test-default-backend)
+			   nil nil nil '(:with-drawers ("FOO"))))))
   (should
    (equal ":FOO:\nkeep\n:END:\n"
-	  (let ((org-drawers '("FOO" "BAR")))
-	    (org-test-with-temp-text ":FOO:\nkeep\n:END:\n:BAR:\nremove\n:END:"
-	      (org-export-as (org-test-default-backend)
-			     nil nil nil '(:with-drawers (not "BAR")))))))
+	  (org-test-with-temp-text ":FOO:\nkeep\n:END:\n:BAR:\nremove\n:END:"
+	    (org-export-as (org-test-default-backend)
+			   nil nil nil '(:with-drawers (not "BAR"))))))
   ;; Footnotes.
   (should
    (equal "Footnote?"