Tags/properties matcher: Fixed issues with todo-only matches

lisp/org.el (org-scan-tags): Require todo-only argument, and document
that it should be the same one set by make-org-tags-matcher.
Fix documentation to explain that todo-only is really
not-done-todo-only.

(org-make-tags-matcher): If todo part of matcher starts with /!,
matcher now always checks that the TODO keyword is present and
is a not-done state.  This matters e.g. for org-map-entries
which unlike org-scan-tags does not do its own separate todo-only
filtering.  Added docs to explain matcher dependencies.

(org-map-entries): Make sure todo-only is correctly passed from
org-make-tags-matcher to org-scan-tags.

* lisp/org-clock.el: (org-clock-get-table-data): Make sure todo-only
does not leak when it is set by make-org-tags-macher.

* lisp/org-crypt.el: (org-encrypt-entries, org-decrypt-entries): Make
sure todo-only is correctly passed from org-make-tags-matcher to
org-scan-tags.

* contrib/lisp/contacts.el: (org-contacts-filter) : Make sure todo-only
is correctly passed from org-make-tags-matcher to org-scan-tags.
This commit is contained in:
Ilya Shlyakhter 2012-03-21 19:49:07 -04:00 committed by Bastien Guerry
parent 6ba1d35f64
commit 532a1ac40a
4 changed files with 49 additions and 18 deletions

View File

@ -143,7 +143,8 @@ This overrides `org-email-link-description-format' if set."
(defun org-contacts-filter (&optional name-match tags-match)
"Search for a contact maching NAME-MATCH and TAGS-MATCH.
If both match values are nil, return all contacts."
(let ((tags-matcher
(let* (todo-only
(tags-matcher
(if tags-match
(cdr (org-make-tags-matcher tags-match))
t))
@ -161,7 +162,8 @@ If both match values are nil, return all contacts."
(error "File %s is no in `org-mode'" file))
(org-scan-tags
'(add-to-list 'markers (set-marker (make-marker) (point)))
`(and ,contacts-matcher ,tags-matcher ,name-matcher))))
`(and ,contacts-matcher ,tags-matcher ,name-matcher)
todo-only)))
(dolist (marker markers result)
(org-with-point-at marker
(add-to-list 'result

View File

@ -2434,6 +2434,7 @@ TIME: The sum of all time spend in this tree, in minutes. This time
(tags (plist-get params :tags))
(properties (plist-get params :properties))
(inherit-property-p (plist-get params :inherit-props))
todo-only
(matcher (if tags (cdr (org-make-tags-matcher tags))))
cc range-text st p time level hdl props tsp tbl)

View File

@ -236,16 +236,20 @@ See `org-crypt-disable-auto-save'."
(defun org-encrypt-entries ()
"Encrypt all top-level entries in the current buffer."
(interactive)
(org-scan-tags
'org-encrypt-entry
(cdr (org-make-tags-matcher org-crypt-tag-matcher))))
(let (todo-only)
(org-scan-tags
'org-encrypt-entry
(cdr (org-make-tags-matcher org-crypt-tag-matcher))
todo-only)))
(defun org-decrypt-entries ()
"Decrypt all entries in the current buffer."
(interactive)
(org-scan-tags
'org-decrypt-entry
(cdr (org-make-tags-matcher org-crypt-tag-matcher))))
(let (todo-only)
(org-scan-tags
'org-decrypt-entry
(cdr (org-make-tags-matcher org-crypt-tag-matcher))
todo-only)))
(defun org-crypt-use-before-save-magic ()
"Add a hook to automatically encrypt entries before a file is saved to disk."

View File

@ -12764,7 +12764,7 @@ obtain a list of properties. Building the tags list for each entry in such
a file becomes an N^2 operation - but with this variable set, it scales
as N.")
(defun org-scan-tags (action matcher &optional todo-only start-level)
(defun org-scan-tags (action matcher todo-only &optional start-level)
"Scan headline tags with inheritance and produce output ACTION.
ACTION can be `sparse-tree' to produce a sparse tree in the current buffer,
@ -12774,7 +12774,9 @@ this case the return value is a list of all return values from these calls.
MATCHER is a Lisp form to be evaluated, testing if a given set of tags
qualifies a headline for inclusion. When TODO-ONLY is non-nil,
only lines with a TODO keyword are included in the output.
only lines with a not-done TODO keyword are included in the output.
This should be the same variable that was scoped into
and set by `org-make-tags-matcher' when it constructed MATCHER.
START-LEVEL can be a string with asterisks, reducing the scope to
headlines matching this string."
@ -12944,8 +12946,6 @@ headlines matching this string."
(if (member x org-use-tag-inheritance) x nil))
tags)))))
(defvar todo-only) ;; dynamically scoped
(defun org-match-sparse-tree (&optional todo-only match)
"Create a sparse tree according to tags string MATCH.
MATCH can contain positive and negative selection of tags, like
@ -12992,9 +12992,29 @@ instead of the agenda files."
(org-agenda-files))))))))
(defun org-make-tags-matcher (match)
"Create the TAGS/TODO matcher form for the selection string MATCH."
;; todo-only is scoped dynamically into this function, and the function
;; may change it if the matcher asks for it.
"Create the TAGS/TODO matcher form for the selection string MATCH.
The variable `todo-only' is scoped dynamically into this function; it will be
set to t if the matcher restricts matching to TODO entries,
otherwise will not be touched.
Returns a cons of the selection string MATCH and the constructed
lisp form implementing the matcher. The matcher is to be
evaluated at an Org entry, with point on the headline,
and returns t if the entry matches the
selection string MATCH. The returned lisp form references
two variables with information about the entry, which must be
bound around the form's evaluation: todo, the TODO keyword at the
entry (or nil of none); and tags-list, the list of all tags at the
entry including inherited ones. Additionally, the category
of the entry (if any) must be specified as the text property
'org-category on the headline.
See also `org-scan-tags'.
"
(declare (special todo-only))
(unless (boundp 'todo-only)
(error "org-make-tags-matcher expects todo-only to be scoped in"))
(unless match
;; Get a new match request, with completion
(let ((org-last-tags-completion-table
@ -13111,6 +13131,9 @@ instead of the agenda files."
(setq matcher (if todomatcher
(list 'and tagsmatcher todomatcher)
tagsmatcher))
(when todo-only
(setq matcher (list 'and '(member todo org-not-done-keywords)
matcher)))
(cons match0 matcher)))
(defun org-op-to-function (op &optional stringp)
@ -13824,7 +13847,8 @@ a *different* entry, you cannot use these techniques."
org-done-keywords-for-agenda
org-todo-keyword-alist-for-agenda
org-drawers-for-agenda
org-tag-alist-for-agenda)
org-tag-alist-for-agenda
todo-only)
(cond
((eq match t) (setq matcher t))
@ -13857,7 +13881,7 @@ a *different* entry, you cannot use these techniques."
(progn
(org-prepare-agenda-buffers
(list (buffer-file-name (current-buffer))))
(setq res (org-scan-tags func matcher nil start-level)))
(setq res (org-scan-tags func matcher todo-only start-level)))
;; Get the right scope
(cond
((and scope (listp scope) (symbolp (car scope)))
@ -13878,7 +13902,7 @@ a *different* entry, you cannot use these techniques."
(save-restriction
(widen)
(goto-char (point-min))
(setq res (append res (org-scan-tags func matcher))))))))))
(setq res (append res (org-scan-tags func matcher todo-only))))))))))
res)))
;;;; Properties