Morgan Smith <[email protected]> writes:
> Unless I am mistaken, performing the secondary sorting in the function is
> mandatory. I have included my reasoning below.
I agree with the reasoning.
> However, I believe I have managed to come up with a flexible solution that
> does
> involve allowing `org-tags-sort-function' to be a list of functions. The
> trick
> is to lexically bind the list each time so we don't get infinite recursion.
> ...
> +(defun org-tags-sort (tag1 tag2)
> + "Sort tags TAG1 and TAG2 according to the value of
> `org-tags-sort-function'."
> + (cond
> ...
> + ((consp org-tags-sort-function)
> + (let* ((sort-fun (car org-tags-sort-function))
> + ;; So the functions can call `org-tags-sort'
> + (org-tags-sort-function (cdr org-tags-sort-function)))
> + (funcall sort-fun tag1 tag2)))
This implies that every possible sort function will take care about
calling `org-tags-sort' recursively. I do not think that it is a good
idea. Consider (setq org-tags-sort-function '(length< org-tags-sort-hierarchy)).
There is no way `length<' know to call `org-tags-sort'! So,
`org-tags-sort-hierarchy' in the list will always be ignored. Not
expected, IMHO.
Instead, we can do the following:
(catch :org-tags-sort-return ; also allow individual sort functions to exit
early
(dolist (sort-fun 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)))
;; tag1 = tag2 for each function in the list
nil)
Then, if you need to perform custom sorting, you can return early from
`org-tags-sort-hierarchy':
(let ((org-tags-sort-function (delete #'org-tags-sort-hierarchy
org-tags-sort-function)))
(throw :org-tags-sort-return (org-tags-sort (nth n tag1-path) (nth n
tag2-path)))
WDYT?
--
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>