Morgan Smith <morgan.j.sm...@outlook.com> writes: > Thank you for bring this case to my attention in such a concrete way. I > have added fixes and tests to make this work.
Thanks! > --- a/lisp/org.el > +++ b/lisp/org.el > @@ -3015,7 +3015,8 @@ org-tags-sort-function > (const :tag "Default sorting" nil) > (const :tag "Alphabetical" org-string<) > (const :tag "Reverse alphabetical" org-string>) > - (function :tag "Custom function" nil))) > + (function :tag "Custom function" nil) > + (repeat function))) We also need to describe how the new multi-function sorting is working. In particular, we should document that function can call `org-tags-sort' recursively and that it will yield sorting using functions specified _after_ current function in `org-tags-sort-function'. There is also somewhat unexpected behavior when a given sort function is the last in the list - it will implicitly call `org-tags-sort' with org-tags-sort-function = nil, which might be somewhat surprising (unless clearly warned about). > +(defun org-tags-sort (tag1 tag2) > + "Sort tags TAG1 and TAG2 according to the value of > `org-tags-sort-function'." > + (let ((org-tags-sort-function > + (cond ((functionp org-tags-sort-function) (list > org-tags-sort-function)) > + ((consp org-tags-sort-function) org-tags-sort-function) > + ((null org-tags-sort-function) (list #'org-string<))))) > + (catch :org-tags-sort-return > + (dolist (sort-fun org-tags-sort-function) > + ;; So the function can call `org-tags-sort' > + (let ((org-tags-sort-function (cdr org-tags-sort-function))) > + (cond > + ((funcall sort-fun tag1 tag2) ; tag1 < tag2 > + (throw :org-tags-sort-return t)) > + ((funcall sort-fun tag2 tag1) ; tag1 > tag2 > + (throw :org-tags-sort-return nil)) > + (t ; tag1 = tag2 > + 'continue-loop))))))) What happens when tags are completely equal, according to every function in `org-tags-sort-function'? > --- a/testing/lisp/test-org.el > +++ b/testing/lisp/test-org.el > @@ -8484,7 +8484,7 @@ test-org/toggle-tag > ;; Special case: Handle properly tag inheritance. In particular, do > ;; not set inherited tags. > (should > - (equal "* H1 :tag:\n** H2 :tag2:tag:" > + (equal "* H1 :tag:\n** H2 :tag:tag2:" > (org-test-with-temp-text "* H1 :tag:\n** <point>H2 :tag2:" > (let ((org-use-tag-inheritance t) > (org-tags-column 1)) Why did you have to change this test? -- Ihor Radchenko // yantar92, Org mode maintainer, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92>