From 3068ad814f9d354bae063c32200fb337756300cb Mon Sep 17 00:00:00 2001 From: Adam Porter Date: Mon, 18 Jul 2022 10:50:49 -0500 Subject: [PATCH] WIP: Add org-ql-sort.el --- org-ql-sort.el | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ org-ql.el | 12 ++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 org-ql-sort.el diff --git a/org-ql-sort.el b/org-ql-sort.el new file mode 100644 index 0000000..e45962d --- /dev/null +++ b/org-ql-sort.el @@ -0,0 +1,56 @@ +;;; org-ql-sort.el --- Library for sorting org-elements -*- lexical-binding: t; -*- + +;; Copyright (C) 2022 Adam Porter + +;; Author: Adam Porter +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This library provides tools for sorting `org-element' items. + +;;; Code: + +;;;; Requirements + +(require 'cl-lib) +(require 'map) + +(require 'org-element) + +;;;; Variables + +(defvar org-ql-sorters nil + "Alist of sort functions defined with `org-ql-sort-define-sorter'. +Maps sorters' short names to function symbols.") + +;;;; Macros + +(defmacro org-ql-sort-define-sorter (name docstring &rest body) + "FIXME: Docstring." + (let ((fn-symbol (intern (concat "org-ql-sort--sort-by-" (symbol-name name))))) + (map-put org-ql-sorters name fn-symbol) + `(defun ,fn-symbol (a b) + ,docstring + ,@body))) + +;;;; Functions + + + + +(provide 'org-ql-sort) +;;; org-ql-sort.el ends here diff --git a/org-ql.el b/org-ql.el index 0cf6c8a..a0e03eb 100644 --- a/org-ql.el +++ b/org-ql.el @@ -427,7 +427,10 @@ each priority the newest items would appear first." (org-ql--sort-by items (-list sort))) ;; Sort by user-given comparator. ((pred functionp) (-sort sort items)) - (_ (user-error "SORT must be either nil, one or a list of the defined sorting methods (see documentation), or a comparison function of two arguments"))))) + ;; FIXME: Test more carefully for sorters with arguments. In the meantime, just try to sort. + (_ (org-ql--sort-by items (-list sort))) + ;; (_ (user-error "SORT must be either nil, one or a list of the defined sorting methods (see documentation), or a comparison function of two arguments")) + ))) ;;;###autoload (cl-defun org-ql-query (&key (select 'element-with-markers) from where narrow order-by) @@ -2296,6 +2299,13 @@ PREDICATES is a list of one or more sorting methods, including: (= 0 (random 2)))) ;; NOTE: reverse and todo are handled below. ;; TODO: Add more. + (`(tags . ,tags) (lambda (a b) + "Return non-nil if A has certain tags and B doesn't." + (cl-flet ((test-entry + (entry) (org-with-point-at (org-element-property :org-hd-marker entry) + (apply #'org-ql--predicate-tags tags)))) + (and (test-entry a) + (not (test-entry b)))))) (_ (user-error "Invalid sorting predicate: %s" symbol)))) (sort-by-todo-keyword (items) (let* ((grouped-items (--group-by (when-let (keyword (org-element-property :todo-keyword it))