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>

Reply via email to