Skip to content

Commit

Permalink
WIP: Add reverse sorting, and reverse sorting order
Browse files Browse the repository at this point in the history
This is a breaking change of sorts in that searches using multiple
sorting methods will have to have the order of the sorters reversed to
get the same result.  Unfortunate, but I think it's worth it in the
end, and this is pre-1.0, anyway.

See #143.
  • Loading branch information
alphapapa committed Jul 13, 2021
1 parent 88151b7 commit 5e45f7f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
14 changes: 8 additions & 6 deletions org-ql-view.el
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,13 @@ See info node `(elisp)Cyclic Window Ordering'."
(deadline auto)
(scheduled :to today)
(ts-active :on today)))
:sort '(date priority todo)
:sort '(todo priority date)
:super-groups 'org-super-agenda-groups
:title "Agenda-like"))
(cons "Overview: NEXT tasks"
(list :buffers-files #'org-agenda-files
:query '(todo "NEXT")
:sort '(priority date)
:sort '(date priority)
:super-groups 'org-super-agenda-groups
:title "Overview: NEXT tasks"))
(cons "Calendar: Today"
Expand Down Expand Up @@ -189,7 +189,7 @@ See info node `(elisp)Cyclic Window Ordering'."
(ancestors (done)))
:title (propertize "Review: Dangling tasks"
'help-echo "Tasks whose ancestor is done")
:sort '(date priority todo)
:sort '(todo priority date)
:super-groups '((:auto-parent t))))
(cons (propertize "Review: Stale tasks"
'help-echo "Tasks without a timestamp in the past 2 weeks")
Expand All @@ -198,7 +198,7 @@ See info node `(elisp)Cyclic Window Ordering'."
(not (ts :from -14)))
:title (propertize "Review: Stale tasks"
'help-echo "Tasks without a timestamp in the past 2 weeks")
:sort '(date priority todo)
:sort '(todo priority date)
:super-groups '((:auto-parent t))))
(cons (propertize "Review: Stuck projects"
'help-echo "Tasks with sub-tasks but no NEXT sub-tasks")
Expand All @@ -208,7 +208,7 @@ See info node `(elisp)Cyclic Window Ordering'."
(not (descendants (todo "NEXT"))))
:title (propertize "Review: Stuck projects"
'help-echo "Tasks with sub-tasks but no NEXT sub-tasks")
:sort '(priority date)
:sort '(date priority)
:super-groups 'org-super-agenda-groups)))
"Alist of `org-ql-view' commands."
:type
Expand All @@ -230,6 +230,7 @@ See info node `(elisp)Cyclic Window Ordering'."
(const todo)
(const priority)
(const random)
(const reverse)
(function :tag "Custom comparator"))))
((const :tag "Group-by" :super-groups)
(choice (variable-item :tag "Default org-super-agenda groups" org-super-agenda-groups)
Expand Down Expand Up @@ -282,7 +283,7 @@ TYPE may be `ts', `ts-active', `ts-inactive', `clocked', or
`(,type :from ,(- num-days) :to 0)))))
(org-ql-search files query
:title "Recent items"
:sort '(date priority todo)
:sort '(todo priority date)
:super-groups groups)))

;;;###autoload
Expand Down Expand Up @@ -1110,6 +1111,7 @@ The counterpart to `org-ql-view--contract-buffers-files'."
"deadline"
"priority"
"random"
"reverse"
"scheduled"
"todo")
nil nil (when org-ql-view-sort
Expand Down
32 changes: 22 additions & 10 deletions org-ql.el
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,17 @@ widen and search the entire buffer).
SORT is either nil, in which case items are not sorted; or one or
a list of defined `org-ql' sorting methods (`date', `deadline',
`scheduled', `todo', `priority', or `random'); or a user-defined
comparator function that accepts two items as arguments and
returns nil or non-nil."
`scheduled', `todo', `priority', `reverse', or `random'); or a
user-defined comparator function that accepts two items as
arguments and returns nil or non-nil. Sorting methods are
applied in the order given (i.e. later methods override earlier
ones), and `reverse' may be used more than once.
For example, `(date priority)' would present items with the
highest priority first, and within each priority the oldest items
would appear first. In contrast, `(date reverse priority)' would
also present items with the highest priority first, but within
each priority the newest items would appear first."
(declare (indent defun))
(-let* ((buffers (->> (cl-typecase buffers-or-files
(null (list (current-buffer)))
Expand Down Expand Up @@ -276,8 +284,7 @@ returns nil or non-nil."
;; Sort items
(pcase sort
(`nil items)
((guard (cl-loop for elem in (-list sort)
always (memq elem '(date deadline scheduled todo priority random))))
((guard (cl-subsetp (-list sort) '(date deadline scheduled todo priority random reverse)))
;; Default sorting functions
(org-ql--sort-by items (-list sort)))
;; Sort by user-given comparator.
Expand Down Expand Up @@ -1947,7 +1954,7 @@ PREDICATES is a list of one or more sorting methods, including:
('priority #'org-ql--priority<)
('random (lambda (&rest _ignore)
(= 0 (random 2))))
;; NOTE: 'todo is handled below
;; NOTE: reverse and todo are handled below.
;; TODO: Add more.
(_ (user-error "Invalid sorting predicate: %s" symbol))))
(sort-by-todo-keyword (items)
Expand All @@ -1960,10 +1967,15 @@ PREDICATES is a list of one or more sorting methods, including:
;; Put at end of list if not found
(1+ (length org-todo-keywords-1)))))))
(-flatten-n 1 (-map #'cdr sorted-groups)))))
(cl-loop for pred in (reverse predicates)
do (setq items (if (eq pred 'todo)
(sort-by-todo-keyword items)
(-sort (sorter pred) items)))
(cl-loop for pred in predicates
do (setq items (pcase pred
;; NOTE: Using `reverse' instead of `nreverse' because my gut
;; tells me that, while `nreverse' would be preferable and faster,
;; it would probably cause weird bugs, like items' order being
;; reversed every time a cached query is refreshed in a view.
('reverse (reverse items))
('todo (sort-by-todo-keyword items))
(_ (-sort (sorter pred) items))))
finally return items)))

;; TODO: Rewrite date sorters using `ts'.
Expand Down

0 comments on commit 5e45f7f

Please sign in to comment.