With the exception of the use of `time-(up|down)` in the `agenda` agenda
view, it seems to
me that agenda views such as `todo` do not consistently sort headlines
scheduled to the same
day at different times. Instead, headlines so scheduled are listed in the
order they appear
in their file.

Steps to reproduce (emacs -Q):

/tmp/test.org:
  * TODO First in file
    SCHEDULED: <2025-03-27 Thu 12:00>
  * TODO Second in file
    SCHEDULED: <2025-03-27 Thu 18:00>
  * TODO Third in file
    SCHEDULED: <2025-03-27 Thu 14:00>

(setq org-agenda-files '("/tmp/test.org"))
(setq org-agenda-sorting-strategy '(scheduled-up))
(org-todo-list)

Expected output:
  Global list of TODO items of type: ALL
  Press ‘N r’ (e.g. ‘0 r’) to search again: (0)[ALL] (1)DONE (2)TODO
    test:       TODO First in file
    test:       TODO Third in file
    test:       TODO Second in file

Actual output:
  Global list of TODO items of type: ALL
  Press ‘N r’ (e.g. ‘0 r’) to search again: (0)[ALL] (1)DONE (2)TODO
    test:       TODO First in file
    test:       TODO Second in file
    test:       TODO Third in file

As far as I can tell part of the problem here is that the sortation
functions for agenda
views receive their headlines in the form of heavily org-propertied
strings, rather than
having access to the full entry as you might get when running #'org-sort
within the content
file itself. Of these properties, timestamp information is included with
key 'ts-date, which
is obtained from #'org-agenda-try-get-agenda-timestamp. That function, in
turn, calls
#'org-entry-get to extract the relevant timestamp from the entry text -- so
far so good --
then passes that value into #'org-time-string-to-absolute, *which drops the
time-of-day
information and simply returns the number of days since 0000-00-00 00:00*.

A quick fix is to change the body of #'org-cmp-ts as follows:

  (let* ((def (if org-agenda-sort-notime-is-late 99999999999 -1))
         (tsa (and (string-match type (or (get-text-property 1 'type a) ""))
                   (org-entry-get (get-text-property 1 'org-hd-marker a)
(upcase type))))
         (ta (if tsa (org-time-string-to-seconds tsa) def))
         (tsb (and (string-match type (or (get-text-property 1 'type b) ""))
                   (org-entry-get (get-text-property 1 'org-hd-marker b)
(upcase type))))
         (tb (if tsb (org-time-string-to-seconds tsb) def)))
    (cond ((if ta (and tb (< ta tb)) tb) -1)
          ((if tb (and ta (< tb ta)) ta) +1)))

Aside from the obvious changes to the way 'ta and 'tb are computed, note
that the default
value has been extended from 8 9's to 11 9's, since we are now comparing
epoch seconds
instead of epoch days.

I assume the text-property-based approach org-agenda uses here (in contrast
to #'org-sort)
is intended to avoid repeated calls to #'org-entry-get while sorting a
potentially very
large number of headlines across as many files. It might be worth attaching
a new
text-property during #'org-scan-tags, which is how that 'ts-date property
gets there in the
first place, and then referencing that in #'org-cmp-ts. Alternatively, one
could make a
change to #'org-agenda-try-get-agenda-timestamp or
#'org-time-string-to-absolute so that the
'ts-date value is more precise, but I don't know what other knock-on
effects that might have
for the rest of the orgmode. (#'org-cmp-ts seems to only be used for agenda
sorting, so
edits there are relatively isolated.)

That said, the change above seems to run quickly enough for me with around
50 agenda files
and 500 headlines, so perhaps one need not be so adamant about optimizing
it.

I have declined to include my Emacs state since I tested this with emacs
-Q, which should be
clean of any weird customizations. Here are the version numbers though:

GNU Emacs 29.4 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.33, cairo
version 1.16.0) of 2024-07-15
Package: Org mode version 9.7.25 (9.7.25-bdf9f94 @
/home/charlest/.emacs.d/elpa/org-9.7.25/)
Package: Org mode version 9.6.15 (release_9.6.15 @
/usr/local/share/emacs/29.4/lisp/org/)

Good luck,
Charles

Reply via email to