summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Dominik <carsten.dominik@gmail.com>2008-03-21 10:34:43 +0100
committerCarsten Dominik <carsten.dominik@gmail.com>2008-03-21 10:34:43 +0100
commit37b3e9cae2e2fdc8ca683eaf04ba02bd08ed58d2 (patch)
tree86aea013b45c799e370b8d8c1518798976076110
parent99b9b746d8c5113be81c04b33e9b800b771e2220 (diff)
downloadorg-mode-37b3e9cae2e2fdc8ca683eaf04ba02bd08ed58d2.tar.gz
Selective tag inheritance.
Tags can now be selected for inheritance by using a list or a regular expression. Also for property inheritance, we now allow a regular expression (list selection existed before). The property API can now retrieve the value of a property with inheritance based on the value of `org-use-property-inheritance'. Earlier this value was ignored when querying an entry. It still is ignored by default, but by passing `selective' as the INHERIT flag, it can now be used.
-rw-r--r--ChangeLog17
-rw-r--r--ORGWEBPAGE/Changes.org22
-rw-r--r--org.el107
-rw-r--r--org.texi25
4 files changed, 138 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index af3216b..c0cffad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2008-03-21 Carsten Dominik <dominik@science.uva.nl>
+
+ * org.el (org-cached-entry-get): Allow a regexp value for
+ `org-use-property-inheritance'.
+ (org-use-property-inheritance): Allow regexp value. Fix bug in
+ customization type.
+ (org-use-tag-inheritance): Allow a list and a regexp value for
+ this variable.
+ (org-scan-tags, org-get-tags-at): Implement selective tag
+ inheritance.
+ (org-entry-get): Respect value `selective' for the INHERIT
+ argument.
+ (org-tag-inherit-p, org-property-inherit-p): New functions.
+
+ * org.texi (Property inheritance, Tag inheritance): Document
+ selective inheritance.
+
2008-03-20 Carsten Dominik <dominik@science.uva.nl>
* org.el (org-agenda-compute-time-span): Make argument N optional.
diff --git a/ORGWEBPAGE/Changes.org b/ORGWEBPAGE/Changes.org
index b1d6ac5..1eef8ee 100644
--- a/ORGWEBPAGE/Changes.org
+++ b/ORGWEBPAGE/Changes.org
@@ -9,7 +9,27 @@
** Details
-*** Suport for ISO week dates (RFC odder ISO number???)
+*** Selective tag inheritance
+
+ Inheritance of tags can now be limited to a subset of all
+ tags, using the variable =org-use-tag-inheritance=. This
+ variable may now be a regular expression or a list to select
+ the inherited tags. Thanks to Michael Ekstrand for this
+ excellent proposal.
+
+ The regexp option is also inplemented for
+ =org-use-property-inheritance=, so that you can now select
+ properties for inheritance my name.
+
+*** Changes to property API
+
+ The INHERIT flag to the function =org-entry-get= can be set
+ to the symbol =selective=. If this is the case, then the
+ value of the property will be retrived using inheritance if
+ and only if the setting in =org-use-property-inheritance=
+ selects the property for inheritance.
+
+*** Suport for ISO week dates (ISO 6801)
Dates in the agenda now show the ISO week an day
specification, in the form =W08 2=, meaning Tuesday of
diff --git a/org.el b/org.el
index 7b6acde..a1270a5 100644
--- a/org.el
+++ b/org.el
@@ -2203,9 +2203,27 @@ the tags are again aligned to `org-tags-column'."
"Non-nil means, tags in levels apply also for sublevels.
When nil, only the tags directly given in a specific line apply there.
If you turn off this option, you very likely want to turn on the
-companion option `org-tags-match-list-sublevels'."
+companion option `org-tags-match-list-sublevels'.
+
+This may also be a list of tags that should be inherited, or a regexp that
+matches tags that should be inherited."
:group 'org-tags
- :type 'boolean)
+ :type '(choice
+ (const :tag "Not" nil)
+ (const :tag "Always" t)
+ (repeat :tag "Specific tags" (string :tag "Tag"))
+ (regexp :tag "Tags matched by regexp")))
+
+(defun org-tag-inherit-p (tag)
+ "Check if TAG is one that should be inherited."
+ (cond
+ ((eq org-use-tag-inheritance t) t)
+ ((not org-use-tag-inheritance) nil)
+ ((stringp org-use-tag-inheritance)
+ (string-match org-use-tag-inheritance tag))
+ ((listp org-use-tag-inheritance)
+ (member tag org-use-tag-inheritance))
+ (t (error "Invalid setting of `org-use-tag-inheritance'"))))
(defcustom org-tags-match-list-sublevels nil
"Non-nil means list also sublevels of headlines matching tag search.
@@ -2244,23 +2262,44 @@ lined-up with respect to each other."
(defcustom org-use-property-inheritance nil
"Non-nil means, properties apply also for sublevels.
-This setting is only relevant during property searches, not when querying
-an entry with `org-entry-get'. To retrieve a property with inheritance,
-you need to call `org-entry-get' with the inheritance flag.
-Turning this on can cause significant overhead when doing a search, so
-this is turned off by default.
+
+This setting is chiefly used during property searches. Turning it on can
+cause significant overhead when doing a search, which is why it is not
+on by default.
+
When nil, only the properties directly given in the current entry count.
-The value may also be a list of properties that shouldhave inheritance.
+When t, every property is inherited. The value may also be a list of
+properties that should have inheritance, or a regular expression matching
+properties that should be inherited.
However, note that some special properties use inheritance under special
circumstances (not in searches). Examples are CATEGORY, ARCHIVE, COLUMNS,
and the properties ending in \"_ALL\" when they are used as descriptor
-for valid values of a property."
+for valid values of a property.
+
+Note for programmers:
+When querying an entry with `org-entry-get', you can control if inheritance
+should be used. By default, `org-entry-get' looks only at the local
+properties. You can request inheritance by setting the inherit argument
+to t (to force inheritance) or to `selective' (to respect the setting
+in this variable)."
:group 'org-properties
:type '(choice
(const :tag "Not" nil)
- (const :tag "Always" nil)
- (repeat :tag "Specific properties" (string :tag "Property"))))
+ (const :tag "Always" t)
+ (repeat :tag "Specific properties" (string :tag "Property"))
+ (regexp :tag "Properties matched by regexp")))
+
+(defun org-property-inherit-p (property)
+ "Check if PROPERTY is one that should be inherited."
+ (cond
+ ((eq org-use-property-inheritance t) t)
+ ((not org-use-property-inheritance) nil)
+ ((stringp org-use-property-inheritance)
+ (string-match org-use-property-inheritance property))
+ ((listp org-use-property-inheritance)
+ (member property org-use-property-inheritance))
+ (t (error "Invalid setting of `org-use-property-inheritance'"))))
(defcustom org-columns-default-format "%25ITEM %TODO %3PRIORITY %TAGS"
"The default column format, if no other format has been defined.
@@ -15253,7 +15292,7 @@ are included in the output."
(when (setq entry (assoc i tags-alist))
(setq tags-alist (delete entry tags-alist)))
(setq i (1- i)))
- ;; add the nex tags
+ ;; add the next tags
(when tags
(setq tags (mapcar 'downcase (org-split-string tags ":"))
tags-alist
@@ -15263,6 +15302,11 @@ are included in the output."
(if org-use-tag-inheritance
(apply 'append (mapcar 'cdr tags-alist))
tags))
+ (when (and tags org-use-tag-inheritance
+ (not (eq t org-use-tag-inheritance)))
+ ;; selective inheritance, remove uninherited ones
+ (setcdr (car tags-alist)
+ (org-remove-uniherited-tags (cdar tags-alist))))
(when (and (or (not todo-only) (member todo org-not-done-keywords))
(eval matcher)
(or (not org-agenda-skip-archived-trees)
@@ -15298,6 +15342,18 @@ are included in the output."
(org-hide-archived-subtrees (point-min) (point-max)))
(nreverse rtn)))
+(defun org-remove-uniherited-tags (tags)
+ "Remove all tags that are not inherited from the list TAGS."
+ (cond
+ ((eq org-use-tag-inheritance t) tags)
+ ((not org-use-tag-inheritance) nil)
+ ((stringp org-use-tag-inheritance)
+ (delq nil (mapcar
+ (lambda (x) (if (string-match org-use-tag-inheritance x) x nil))
+ tags)))
+ ((listp org-use-tag-inheritance)
+ (org-delete-all org-use-tag-inheritance tags))))
+
(defvar todo-only) ;; dynamically scoped
(defun org-tags-sparse-tree (&optional todo-only match)
@@ -15313,7 +15369,10 @@ also TODO lines."
(defvar org-cached-props nil)
(defun org-cached-entry-get (pom property)
(if (or (eq t org-use-property-inheritance)
- (member property org-use-property-inheritance))
+ (and (stringp org-use-property-inheritance)
+ (string-match org-use-property-inheritance property))
+ (and (listp org-use-property-inheritance)
+ (member property org-use-property-inheritance)))
;; Caching is not possible, check it directly
(org-entry-get pom property 'inherit)
;; Get all properties, so that we can do complicated checks easily
@@ -16011,10 +16070,14 @@ If WHICH is nil or `all', get all properties. If WHICH is
"Get value of PROPERTY for entry at point-or-marker POM.
If INHERIT is non-nil and the entry does not have the property,
then also check higher levels of the hierarchy.
+If INHERIT is the symbol `selective', use inheritance only if the setting
+in `org-use-property-inheritance' selects PROPERTY for inheritance.
If the property is present but empty, the return value is the empty string.
If the property is not present at all, nil is returned."
(org-with-point-at pom
- (if inherit
+ (if (and inherit (if (eq inherit 'selective)
+ (org-property-inherit-p property)
+ t))
(org-entry-get-with-inheritance property)
(if (member property org-special-properties)
;; We need a special property. Use brute force, get all properties.
@@ -23180,9 +23243,9 @@ the same tree node, and the headline of the tree node in the Org-mode file."
"Get a list of all headline tags applicable at POS.
POS defaults to point. If tags are inherited, the list contains
the targets in the same sequence as the headlines appear, i.e.
-the tags of the current headline come last."
+sthe tags of the current headline come last."
(interactive)
- (let (tags lastpos)
+ (let (tags ltags lastpos parent)
(save-excursion
(save-restriction
(widen)
@@ -23193,12 +23256,14 @@ the tags of the current headline come last."
(org-back-to-heading t)
(while (not (equal lastpos (point)))
(setq lastpos (point))
- (if (looking-at (org-re "[^\r\n]+?:\\([[:alnum:]_@:]+\\):[ \t]*$"))
- (setq tags (append (org-split-string
- (org-match-string-no-properties 1) ":")
- tags)))
+ (when (looking-at (org-re "[^\r\n]+?:\\([[:alnum:]_@:]+\\):[ \t]*$"))
+ (setq ltags (org-split-string
+ (org-match-string-no-properties 1) ":"))
+ (setq tags (append (org-remove-uniherited-tags ltags)
+ tags)))
(or org-use-tag-inheritance (error ""))
- (org-up-heading-all 1)))
+ (org-up-heading-all 1)
+ (setq parent t)))
(error nil))))
tags)))
diff --git a/org.texi b/org.texi
index c173fe1..a13b2e7 100644
--- a/org.texi
+++ b/org.texi
@@ -3246,8 +3246,9 @@ Org-mode finds that a certain headline matches the search criterion, it
will not check any sublevel headline, assuming that these also match and
that the list of matches could become very long because of that. If you
do want the subevels be tested and listed as well, you may set the
-variable @code{org-tags-match-list-sublevels}. To turn off tag
-inheritance entirely, use the variable @code{org-use-tag-inheritance}.
+variable @code{org-tags-match-list-sublevels}. To limit tag inheritance
+to specific tags, or to turn it off entirely, use the variable
+@code{org-use-tag-inheritance}.
@node Setting tags, Tag searches, Tag inheritance, Tags
@section Setting tags
@@ -3612,9 +3613,7 @@ CLOCKSUM @r{The sum of CLOCK intervals in the subtree. @code{org-clock-sum}
@node Property searches, Property inheritance, Special properties, Properties and columns
@section Property searches
@cindex properties, searching
-@cindex properties, inheritance
@cindex searching, of properties
-@cindex inheritance, of properties
To create sparse trees and special lists with selection based on
properties, the same commands are used as for tag searches (@pxref{Tag
@@ -3649,6 +3648,8 @@ a regular expression and matched against the property values.
@node Property inheritance, Column view, Property searches, Properties and columns
@section Property Inheritance
+@cindex properties, inheritance
+@cindex inheritance, of properties
The outline structure of Org-mode documents lends itself for an
inheritance model of properties: If the parent in a tree has a certain
@@ -3657,8 +3658,9 @@ turn this on by default, because it can slow down property searches
significantly and is often not needed. However, if you find inheritance
useful, you can turn it on by setting the variable
@code{org-use-property-inheritance}. It may be set to @code{t}, to make
-all properties inherited from the parent, or to a list of properties
-that should be inherited.
+all properties inherited from the parent, to a list of properties
+that should be inherited, or to a regular expression that matches
+inherited properties.
Org-mode has a few properties for which inheritance is hard-coded, at
least for the special applications for which they are used:
@@ -8612,11 +8614,12 @@ If WHICH is nil or `all', get all properties. If WHICH is
`special' or `standard', only get that subclass.
@end defun
@defun org-entry-get pom property &optional inherit
-Get value of PROPERTY for entry at point-or-marker POM.
-If INHERIT is non-nil and the entry does not have the property,
-then also check higher levels of the hierarchy. This function ignores
-the value of @code{org-use-property-inheritance} and requires the
-explicit INHERIT flag.
+Get value of PROPERTY for entry at point-or-marker POM. By default,
+this only looks at properties defined locally in the entry. If INHERIT
+is non-nil and the entry does not have the property, then also check
+higher levels of the hierarchy. If INHERIT is the symbol
+@code{selective}, use inheritance if and only if the setting of
+@code{org-use-property-inheritance} selects PROPERTY for inheritance.
@end defun
@defun org-entry-delete pom property