>From 8a2dad690caec96e6daf86097ff0cb062ac348f8 Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Sun, 20 Oct 2013 14:40:09 +0200 Subject: [PATCH] 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. --- lisp/org-agenda.el | 15 ++--- lisp/org-clock.el | 6 +- lisp/org-element.el | 5 +- lisp/org-feed.el | 5 +- lisp/org-list.el | 25 ++----- lisp/org-mobile.el | 4 +- lisp/org-pcomplete.el | 19 ------ lisp/org.el | 141 ++++++++++++++------------------------- testing/lisp/test-org-element.el | 57 ++++++---------- testing/lisp/test-org.el | 22 +++--- testing/lisp/test-ox.el | 28 ++++---- 11 files changed, 109 insertions(+), 218 deletions(-) diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index 0bfba27..fe4c2d4 100644 --- a/lisp/org-agenda.el +++ b/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) diff --git a/lisp/org-clock.el b/lisp/org-clock.el index 3195dc1..1cdbdc1 100644 --- a/lisp/org-clock.el +++ b/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) diff --git a/lisp/org-element.el b/lisp/org-element.el index ed1f515..af5f13c 100644 --- a/lisp/org-element.el +++ b/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)))))))) diff --git a/lisp/org-feed.el b/lisp/org-feed.el index 05ead8f..5a54f70 100644 --- a/lisp/org-feed.el +++ b/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")) diff --git a/lisp/org-list.el b/lisp/org-list.el index 4a3d471..3cb9b32 100644 --- a/lisp/org-list.el +++ b/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))) diff --git a/lisp/org-mobile.el b/lisp/org-mobile.el index a43896b..54b6e03 100644 --- a/lisp/org-mobile.el +++ b/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")) diff --git a/lisp/org-pcomplete.el b/lisp/org-pcomplete.el index 77f68f4..1eee779 100644 --- a/lisp/org-pcomplete.el +++ b/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." diff --git a/lisp/org.el b/lisp/org.el index 8c4b5e7..e9807f8 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -883,6 +883,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. @@ -1071,23 +1075,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 @@ -2345,7 +2332,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.") @@ -4595,9 +4581,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) @@ -4976,8 +4959,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") @@ -5033,7 +5014,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 @@ -5093,10 +5073,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 @@ -6623,11 +6599,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. @@ -7057,8 +7032,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 @@ -7070,7 +7047,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." @@ -8521,8 +8499,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) @@ -12452,7 +12429,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") @@ -13369,9 +13346,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) @@ -13416,17 +13391,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) @@ -14952,7 +14930,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) @@ -15334,13 +15311,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)) @@ -15349,9 +15323,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))))) @@ -15630,23 +15602,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 @@ -15782,17 +15745,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"))) @@ -18079,8 +18040,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 @@ -21677,15 +21636,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." diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el index d30b6bc..f9bcc6e 100644 --- a/testing/lisp/test-org-element.el +++ b/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 @@ -1418,16 +1415,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" @@ -1520,22 +1511,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 @@ -1988,8 +1976,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 () diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 32fa69e..10f6c98 100644 --- a/testing/lisp/test-org.el +++ b/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 "- $")))) diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 5a066a5..1aba00d 100644 --- a/testing/lisp/test-ox.el +++ b/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?" -- 1.8.4.1