mirror of
https://git.savannah.gnu.org/git/emacs/org-mode.git
synced 2024-08-26 17:32:51 +00:00
Mapping: Remove inheritance penalty when scanning for tags
Running a command that would use the tag scanner could suffer a large slow-down when many entries match, because the tag list with inheritance forces each matching entry to walk the hierarchy. Now, it is possible to avoid this penalty by using the variable `org-scanner-tags', or by binding the `org-trust-scanner-tags' to t around calls to `org-get-tags-at' and `org-entry-properties' when retrieving tags and properties for the current entry in the scanner/mapper.
This commit is contained in:
parent
92de421e93
commit
d685f0fc87
|
@ -5,6 +5,11 @@
|
|||
case-sensitive.
|
||||
(org-scan-tags): Use the internal tags list instead of creating it
|
||||
from scratch.
|
||||
(org-trust-scanner-tags, org-scanner-tags): New variables.
|
||||
(org-scan-tags): Set `org-scanner-tags'.
|
||||
(org-get-tags-at): Take advantage of `org-trust-scanner-tags'.
|
||||
(org-map-entries): Document the possible speedup using scanner
|
||||
tags.
|
||||
|
||||
2009-03-03 Carsten Dominik <carsten.dominik@gmail.com>
|
||||
|
||||
|
|
88
lisp/org.el
88
lisp/org.el
|
@ -9758,6 +9758,17 @@ ACTION can be `set', `up', `down', or a character."
|
|||
;;;; Tags
|
||||
|
||||
(defvar org-agenda-archives-mode)
|
||||
(defvar org-scanner-tags nil
|
||||
"The current tag list while the tags scanner is running.")
|
||||
(defvar org-trust-scanner-tags nil
|
||||
"NEVER SET THIS VARIABLE, this is for internal dynamical scoping only.
|
||||
When this is non-nil, the function `org-get-tags-at' will return the value
|
||||
of `org-scanner-tags' instead of building the list by itself. This
|
||||
can lead to large speed-ups when the tags scanner is used in a file with
|
||||
many entries, and when the list of tags is retrieved, for example to
|
||||
obtain a list of properties. Building the tags list for each entry in such
|
||||
a file becomes an N^2 operation.")
|
||||
|
||||
(defun org-scan-tags (action matcher &optional todo-only)
|
||||
"Scan headline tags with inheritance and produce output ACTION.
|
||||
|
||||
|
@ -9820,7 +9831,8 @@ only lines with a TODO keyword are included in the output."
|
|||
(setq tags-list
|
||||
(if org-use-tag-inheritance
|
||||
(apply 'append (mapcar 'cdr (reverse tags-alist)))
|
||||
tags))
|
||||
tags)
|
||||
org-scanner-tags tags-list)
|
||||
(when org-use-tag-inheritance
|
||||
(setcdr (car tags-alist)
|
||||
(mapcar (lambda (x)
|
||||
|
@ -10157,34 +10169,39 @@ the tags of the current headline come last.
|
|||
When LOCAL is non-nil, only return tags from the current headline,
|
||||
ignore inherited ones."
|
||||
(interactive)
|
||||
(let (tags ltags lastpos parent)
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-char (or pos (point)))
|
||||
(save-match-data
|
||||
(catch 'done
|
||||
(condition-case nil
|
||||
(progn
|
||||
(org-back-to-heading t)
|
||||
(while (not (equal lastpos (point)))
|
||||
(setq lastpos (point))
|
||||
(when (looking-at (org-re "[^\r\n]+?:\\([[:alnum:]_@:]+\\):[ \t]*$"))
|
||||
(setq ltags (org-split-string
|
||||
(org-match-string-no-properties 1) ":"))
|
||||
(when parent
|
||||
(setq ltags (mapcar 'org-add-prop-inherited ltags)))
|
||||
(setq tags (append
|
||||
(if parent
|
||||
(org-remove-uniherited-tags ltags)
|
||||
ltags)
|
||||
tags)))
|
||||
(or org-use-tag-inheritance (throw 'done t))
|
||||
(if local (throw 'done t))
|
||||
(org-up-heading-all 1)
|
||||
(setq parent t)))
|
||||
(error nil)))))
|
||||
(append (org-remove-uniherited-tags org-file-tags) tags))))
|
||||
(if (and org-trust-scanner-tags
|
||||
(or (not pos) (equal pos (point)))
|
||||
(not local))
|
||||
org-scanner-tags
|
||||
(let (tags ltags lastpos parent)
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-char (or pos (point)))
|
||||
(save-match-data
|
||||
(catch 'done
|
||||
(condition-case nil
|
||||
(progn
|
||||
(org-back-to-heading t)
|
||||
(while (not (equal lastpos (point)))
|
||||
(setq lastpos (point))
|
||||
(when (looking-at
|
||||
(org-re "[^\r\n]+?:\\([[:alnum:]_@:]+\\):[ \t]*$"))
|
||||
(setq ltags (org-split-string
|
||||
(org-match-string-no-properties 1) ":"))
|
||||
(when parent
|
||||
(setq ltags (mapcar 'org-add-prop-inherited ltags)))
|
||||
(setq tags (append
|
||||
(if parent
|
||||
(org-remove-uniherited-tags ltags)
|
||||
ltags)
|
||||
tags)))
|
||||
(or org-use-tag-inheritance (throw 'done t))
|
||||
(if local (throw 'done t))
|
||||
(org-up-heading-all 1)
|
||||
(setq parent t)))
|
||||
(error nil)))))
|
||||
(append (org-remove-uniherited-tags org-file-tags) tags)))))
|
||||
|
||||
(defun org-add-prop-inherited (s)
|
||||
(add-text-properties 0 (length s) '(inherited t) s)
|
||||
|
@ -10673,7 +10690,16 @@ the scanner. The following items can be given here:
|
|||
will be used as value for `org-agenda-skip-function', so whenever
|
||||
the the function returns t, FUNC will not be called for that
|
||||
entry and search will continue from the point where the
|
||||
function leaves it."
|
||||
function leaves it.
|
||||
|
||||
If your function needs to retrieve the tags including inherited tags
|
||||
at the *current* entry, you can use the value of the variable
|
||||
`org-scanner-tags' which will be much faster than getting the value
|
||||
with `org-get-tags-at'. If your function gets properties with
|
||||
`org-entry-properties' at the *current* entry, bind `org-trust-scanner-tags'
|
||||
to t around the call to `org-entry-properties' to get the same speedup.
|
||||
Note that if your function moves around to retrieve tags and properties at
|
||||
a *different* entry, you cannot use these techniques."
|
||||
(let* ((org-agenda-archives-mode nil) ; just to make sure
|
||||
(org-agenda-skip-archived-trees (memq 'archive skip))
|
||||
(org-agenda-skip-comment-trees (memq 'comment skip))
|
||||
|
@ -10878,7 +10904,7 @@ If WHICH is nil or `all', get all properties. If WHICH is
|
|||
)
|
||||
|
||||
(when (memq which '(all standard))
|
||||
;; Get the standard properties, like :PORP: ...
|
||||
;; Get the standard properties, like :PROP: ...
|
||||
(setq range (org-get-property-block beg end))
|
||||
(when range
|
||||
(goto-char (car range))
|
||||
|
|
Loading…
Reference in a new issue