(org-fast-tag-selection): Honour tag groups when using <TAB> input

* lisp/org.el (org--add-or-remove-tag): New helper function to toggle
tags taking into account tag groups.
(org-fast-tag-selection): Factor out the tag toggling code into a new
function and re-use it in both key selection branch and in the <TAB>
completion interface.

Reported-by: sreenivas sumadithya <sumadithya@gmail.com>
Link: https://orgmode.org/list/CAHVqzFVP9KhrC5ZG_GUHbXZRBVg+PU+tR91vSfrnirLo7_T5Ug@mail.gmail.com
This commit is contained in:
Ihor Radchenko 2023-09-19 12:43:00 +03:00
parent 769c1dc64e
commit edcb8eca5f
No known key found for this signature in database
GPG Key ID: 6470762A7DA11D8B
1 changed files with 22 additions and 13 deletions

View File

@ -11899,6 +11899,26 @@ Also insert END."
(put-text-property 0 (length s) 'face '(secondary-selection org-tag) s) (put-text-property 0 (length s) 'face '(secondary-selection org-tag) s)
(org-overlay-display org-tags-overlay (concat prefix s)))) (org-overlay-display org-tags-overlay (concat prefix s))))
(defun org--add-or-remove-tag (tag current-tags &optional groups)
"Add or remove TAG entered by user to/from CURRENT-TAGS.
Return the modified CURRENT-TAGS.
When TAG is present in CURRENT-TAGS, remove it. Otherwise, add it.
When TAG is a part of a tag group from GROUPS, make sure that no
exclusive tags from the same group remain in CURRENT-TAGS.
CURRENT-TAGS may be modified by side effect."
(if (member tag current-tags)
;; Remove the tag.
(delete tag current-tags)
;; Add the tag. If the tag is from a tag
;; group, exclude selected alternative tags
;; from the group, if any.
(dolist (g groups)
(when (member tag g)
(dolist (x g) (setq current-tags (delete x current-tags)))))
(cons tag current-tags)))
(defvar org-last-tag-selection-key nil) (defvar org-last-tag-selection-key nil)
(defun org-fast-tag-selection (current-tags inherited-tags tag-table &optional todo-table) (defun org-fast-tag-selection (current-tags inherited-tags tag-table &optional todo-table)
"Fast tag selection with single keys. "Fast tag selection with single keys.
@ -12141,9 +12161,7 @@ Returns the new tags string, or nil to not change the current settings."
(setq current-tag (completing-read "Tag: " tab-tags)) (setq current-tag (completing-read "Tag: " tab-tags))
(when (string-match "\\S-" current-tag) (when (string-match "\\S-" current-tag)
(cl-pushnew (list current-tag) tab-tags :test #'equal) (cl-pushnew (list current-tag) tab-tags :test #'equal)
(if (member current-tag current-tags) (setq current-tags (org--add-or-remove-tag current-tag current-tags groups)))
(setq current-tags (delete current-tag current-tags))
(push current-tag current-tags)))
(when exit-after-next (setq exit-after-next 'now))) (when exit-after-next (setq exit-after-next 'now)))
;; INPUT-CHAR is for a todo keyword. ;; INPUT-CHAR is for a todo keyword.
((let (and todo-keyword (guard todo-keyword)) ((let (and todo-keyword (guard todo-keyword))
@ -12154,16 +12172,7 @@ Returns the new tags string, or nil to not change the current settings."
;; INPUT-CHAR is for a tag. ;; INPUT-CHAR is for a tag.
((let (and tag (guard tag)) ((let (and tag (guard tag))
(car (rassoc input-char tag-table-local))) (car (rassoc input-char tag-table-local)))
(if (member tag current-tags) (setq current-tags (org--add-or-remove-tag tag current-tags groups))
;; Remove the tag.
(setq current-tags (delete tag current-tags))
;; Add the tag. If the tag is from a tag
;; group, exclude selected alternative tags
;; from the group, if any.
(dolist (g groups)
(when (member tag g)
(dolist (x g) (setq current-tags (delete x current-tags)))))
(push tag current-tags))
(when exit-after-next (setq exit-after-next 'now)))) (when exit-after-next (setq exit-after-next 'now))))
;; Create a sorted tag list. ;; Create a sorted tag list.
(setq current-tags (setq current-tags