Thanks for the patch. Allen Li writes:
> Example Org file: > > * Parent :foo:bar:baz: > ** Child :foo:bar:spam: > > Invoking org-set-tags-command with point on Child prepopulates the > minibuffer prompt with only the tags :spam: > > This is because org-get-tags doesn't distinguish between inherited only > tags and inherited tags which are also explicitly set on a heading, so > org-set-tags-command treats :foo:bar: as inherited only rather than also > set locally on the heading. > > This is undesirable because having tags set directly on a heading has > different semantics even if they are also inherited (e.g., the TAGS > special property, or when headings will be refiled to a different > location later). I agree, that's undesirable and likely unintended. > Subject: [PATCH] org.el: Don't exclude local tags that are also inherited > > * lisp/org.el (org-set-tags-command): Don't exclude local tags even if > inherited. > --- > lisp/org.el | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) It'd be good to add something along the lines of your example as a case in test-org/set-tags-command. > diff --git a/lisp/org.el b/lisp/org.el > index fb95590fc..49d7d24f2 100644 > --- a/lisp/org.el > +++ b/lisp/org.el > @@ -11880,9 +11880,7 @@ in Lisp code use `org-set-tags' instead." > (org-global-tags-completion-table > (org-agenda-files))) > (or org-current-tag-alist (org-get-buffer-tags))))) > - (current-tags > - (cl-remove-if (lambda (tag) (get-text-property 0 'inherited > tag)) > - all-tags)) > + (current-tags (org-get-tags nil t)) > (inherited-tags > (cl-remove-if-not (lambda (tag) (get-text-property 0 'inherited > tag)) > all-tags)) That looks good as far as fixing the misbehavior you report. I wonder though whether there's a deeper org-get-tags issue here worth considering. Its documentation says ... the returned list of tags contains tags in this order: file tags, tags inherited from parent headlines, local tags. But it's not specified what happens when a tag is both local and inherited. The current implementation drops the local tag variant through its delete-dups call: (delete-dups (append (org-remove-uninherited-tags itags) ltags)) I would have expected the local tag to get priority here. If that were the case (e.g., something like below), that would also solve the issue you describe. Thoughts? -- >8 -- diff --git a/lisp/org.el b/lisp/org.el index fb95590fc..3dac42b7b 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -12310,8 +12310,10 @@ (defun org-get-tags (&optional pos local) (org--get-local-tags)) itags))) (setq itags (append org-file-tags itags)) - (delete-dups - (append (org-remove-uninherited-tags itags) ltags)))))))) + (nreverse + (delete-dups + (nreverse (nconc (org-remove-uninherited-tags itags) + ltags)))))))))) (defun org-get-buffer-tags () "Get a table of all tags used in the buffer, for completion."