Properly handle `org-tag-persistent-alist'

* lisp/org.el (org-current-tag-alist): New variable.
(org-set-tags):
(org-global-tags-completion-table):
(org-agenda-prepare-buffers): Use new variable.
(org-set-regexps-and-options): Use new variable.  Handle STARTUP early
so that "#+STARTUP: noptag" is taken into consideration.

* lisp/org-agenda.el (org-agenda-bulk-action): Use new variable.

* lisp/org-mobile.el (org-mobile-create-index-file): `org-tag-alist' is
  no longer buffer-local.

* testing/lisp/test-org.el (test-org/set-regexps-and-options): Add
  tests.
This commit is contained in:
Nicolas Goaziou 2016-04-17 20:42:08 +02:00
parent 74d3bd484f
commit 4743d43dd8
4 changed files with 95 additions and 53 deletions

View File

@ -86,10 +86,11 @@
(declare-function org-add-archive-files "org-archive" (files))
(declare-function org-capture "org-capture" (&optional goto keys))
(defvar calendar-mode-map) ; defined in calendar.el
(defvar org-clock-current-task nil) ; defined in org-clock.el
(defvar org-mobile-force-id-on-agenda-items) ; defined in org-mobile.el
(defvar org-habit-show-habits) ; defined in org-habit.el
(defvar calendar-mode-map)
(defvar org-clock-current-task)
(defvar org-current-tag-alist)
(defvar org-mobile-force-id-on-agenda-items)
(defvar org-habit-show-habits)
(defvar org-habit-show-habits-only-for-today)
(defvar org-habit-show-all-today)
@ -9930,8 +9931,8 @@ The prefix arg is passed through to the command if possible."
(format "Tag to %s: " (if (eq action ?+) "add" "remove"))
(with-current-buffer (marker-buffer (car entries))
(delq nil
(mapcar (lambda (x)
(if (stringp (car x)) x)) org-tag-alist)))))
(mapcar (lambda (x) (and (stringp (car x)) x))
org-current-tag-alist)))))
(setq cmd `(org-agenda-set-tags ,tag ,(if (eq action ?+) ''on ''off))))
((memq action '(?s ?d))

View File

@ -422,7 +422,7 @@ agenda view showing the flagged items."
(let ((files-alist (sort (copy-sequence org-mobile-files-alist)
(lambda (a b) (string< (cdr a) (cdr b)))))
(def-todo (default-value 'org-todo-keywords))
(def-tags (default-value 'org-tag-alist))
(def-tags org-tag-alist)
(target-file (expand-file-name org-mobile-index-file
org-mobile-directory))
file link-name todo-kwds done-kwds tags entry kwds dwds twds)

View File

@ -2581,6 +2581,10 @@ taken from the (otherwise obsolete) variable `org-todo-interpretation'."
"Alist of all groups tags from all current agenda files.")
(defvar-local org-tag-groups-alist nil)
(defvar org-agenda-contributing-files nil)
(defvar-local org-current-tag-alist nil
"Alist of all tag groups in current buffer.
This variable takes into consideration `org-tag-alist',
`org-tag-persistent-alist' and TAGS keywords in the buffer.")
(defvar-local org-not-done-keywords nil)
(defvar-local org-done-keywords nil)
(defvar-local org-todo-heads nil)
@ -4901,13 +4905,28 @@ related expressions."
'("ARCHIVE" "CATEGORY" "COLUMNS" "CONSTANTS"
"LINK" "OPTIONS" "PRIORITIES" "PROPERTY"
"SEQ_TODO" "STARTUP" "TODO" "TYP_TODO")))))))
;; Startup options. Get this early since it does change
;; behavior for other options (e.g., tags).
(let ((startup (cdr (assq 'startup alist))))
(dolist (option startup)
(let ((entry (assoc-string option org-startup-options t)))
(when entry
(let ((var (nth 1 entry))
(val (nth 2 entry)))
(if (not (nth 3 entry)) (set (make-local-variable var) val)
(unless (listp (symbol-value var))
(set (make-local-variable var) nil))
(add-to-list var val)))))))
(setq-local org-file-tags
(mapcar #'org-add-prop-inherited
(cdr (assq 'filetags alist))))
(setq-local org-tag-alist
(let ((tags (cdr (assq 'tags alist))))
(if tags (org-tag-string-to-alist tags) org-tag-alist)))
(setq-local org-tag-groups-alist (org-tag-alist-to-groups org-tag-alist))
(setq org-current-tag-alist
(append org-tag-persistent-alist
(let ((tags (cdr (assq 'tags alist))))
(if tags (org-tag-string-to-alist tags)
org-tag-alist))))
(setq org-tag-groups-alist
(org-tag-alist-to-groups org-current-tag-alist))
(unless tags-only
;; File properties.
(setq-local org-file-properties (cdr (assq 'property alist)))
@ -4939,17 +4958,6 @@ related expressions."
(let ((scripts (assq 'scripts alist)))
(when scripts
(setq-local org-use-sub-superscripts (cdr scripts))))
;; Startup options.
(let ((startup (cdr (assq 'startup alist))))
(dolist (option startup)
(let ((entry (assoc-string option org-startup-options t)))
(when entry
(let ((var (nth 1 entry))
(val (nth 2 entry)))
(if (not (nth 3 entry)) (set (make-local-variable var) val)
(unless (listp (symbol-value var))
(set (make-local-variable var) nil))
(add-to-list var val)))))))
;; TODO keywords.
(setq-local org-todo-kwd-alist nil)
(setq-local org-todo-key-alist nil)
@ -14364,16 +14372,15 @@ instead of the agenda files."
(save-excursion
(org-uniquify
(delq nil
(apply 'append
(apply #'append
(mapcar
(lambda (file)
(set-buffer (find-file-noselect file))
(append (org-get-buffer-tags)
(mapcar (lambda (x) (if (stringp (car-safe x))
(list (car-safe x)) nil))
org-tag-alist)))
(if (and files (car files))
files
(mapcar (lambda (x)
(and (stringp (car-safe x))
(list (car-safe x))))
(or org-current-tag-alist (org-get-buffer-tags))))
(if (car-safe files) files
(org-agenda-files))))))))
(defun org-make-tags-matcher (match)
@ -14937,7 +14944,7 @@ When JUST-ALIGN is non-nil, only align tags."
org-last-tags-completion-table
(append
org-tag-persistent-alist
(or org-tag-alist (org-get-buffer-tags))
(or org-current-tag-alist (org-get-buffer-tags))
(and
org-complete-tags-always-offer-all-agenda-tags
(org-global-tags-completion-table
@ -18717,8 +18724,7 @@ When a buffer is unmodified, it is just killed. When modified, it is saved
(setq org-tag-alist-for-agenda
(org-uniquify
(append org-tag-alist-for-agenda
org-tag-alist
org-tag-persistent-alist)))
org-current-tag-alist)))
;; Merge current file's tag groups into global
;; `org-tag-groups-alist-for-agenda'.
(when org-group-tags

View File

@ -1656,41 +1656,76 @@ SCHEDULED: <2014-03-04 tue.>"
(ert-deftest test-org/set-regexps-and-options ()
"Test `org-set-regexps-and-options' specifications."
;; TAGS keyword.
(should
(equal '(("A"))
(let ((org-tag-alist '(("A")))
(org-tag-persistent-alist nil))
(org-test-with-temp-text ""
(org-mode-restart)
org-current-tag-alist))))
(should
(equal '(("B"))
(let ((org-tag-alist '(("A")))
(org-tag-persistent-alist nil))
(org-test-with-temp-text "#+TAGS: B"
(org-mode-restart)
org-current-tag-alist))))
(should
(equal '(("C") ("B"))
(let ((org-tag-alist '(("A")))
(org-tag-persistent-alist '(("C"))))
(org-test-with-temp-text "#+TAGS: B"
(org-mode-restart)
org-current-tag-alist))))
(should
(equal '(("B"))
(let ((org-tag-alist '(("A")))
(org-tag-persistent-alist '(("C"))))
(org-test-with-temp-text "#+STARTUP: noptag\n#+TAGS: B"
(org-mode-restart)
org-current-tag-alist))))
(should
(equal '(("A" . ?a) ("B") ("C"))
(org-test-with-temp-text "#+TAGS: A(a) B C"
(org-mode-restart)
org-tag-alist)))
(let ((org-tag-persistant-alist nil))
(org-test-with-temp-text "#+TAGS: A(a) B C"
(org-mode-restart)
org-current-tag-alist))))
(should
(equal '(("A") (:newline) ("B"))
(org-test-with-temp-text "#+TAGS: A\n#+TAGS: B"
(org-mode-restart)
org-tag-alist)))
(let ((org-tag-persistent-alist nil))
(org-test-with-temp-text "#+TAGS: A\n#+TAGS: B"
(org-mode-restart)
org-current-tag-alist))))
(should
(equal '((:startgroup) ("A") ("B") (:endgroup) ("C"))
(org-test-with-temp-text "#+TAGS: { A B } C"
(org-mode-restart)
org-tag-alist)))
(let ((org-tag-persistent-alist nil))
(org-test-with-temp-text "#+TAGS: { A B } C"
(org-mode-restart)
org-current-tag-alist))))
(should
(equal '((:startgroup) ("A") (:grouptags) ("B") ("C") (:endgroup))
(org-test-with-temp-text "#+TAGS: { A : B C }"
(org-mode-restart)
org-tag-alist)))
(let ((org-tag-persistent-alist nil))
(org-test-with-temp-text "#+TAGS: { A : B C }"
(org-mode-restart)
org-current-tag-alist))))
(should
(equal '(("A" "B" "C"))
(org-test-with-temp-text "#+TAGS: { A : B C }"
(org-mode-restart)
org-tag-groups-alist)))
(let ((org-tag-persistent-alist nil))
(org-test-with-temp-text "#+TAGS: { A : B C }"
(org-mode-restart)
org-tag-groups-alist))))
(should
(equal '((:startgrouptag) ("A") (:grouptags) ("B") ("C") (:endgrouptag))
(org-test-with-temp-text "#+TAGS: [ A : B C ]"
(org-mode-restart)
org-tag-alist)))
(let ((org-tag-persistent-alist nil))
(org-test-with-temp-text "#+TAGS: [ A : B C ]"
(org-mode-restart)
org-current-tag-alist))))
(should
(equal '(("A" "B" "C"))
(org-test-with-temp-text "#+TAGS: [ A : B C ]"
(org-mode-restart)
org-tag-groups-alist)))
(let ((org-tag-persistent-alist nil))
(org-test-with-temp-text "#+TAGS: [ A : B C ]"
(org-mode-restart)
org-tag-groups-alist))))
;; FILETAGS keyword.
(should
(equal '("A" "B" "C")