branch: externals/denote commit ffd3bef12b6c266e1725fe5493d4bed786d25017 Author: Protesilaos Stavrou <i...@protesilaos.com> Commit: Protesilaos Stavrou <i...@protesilaos.com>
Add 'random' order for denote-sort functions This applies to the command 'denote-sort-dired' ('denote-dired'), as well as the Org dynamic blocks defined in the package denote-org. Thanks to experimental-code-86 for making the suggestion in issue 572: <https://github.com/protesilaos/denote/issues/572>. --- README.org | 31 +++++++++++++++++++------------ denote.el | 44 ++++++++++++++++++++++++++++++-------------- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/README.org b/README.org index bb6c443209..70cbafe36f 100644 --- a/README.org +++ b/README.org @@ -3535,24 +3535,31 @@ Here are some examples: :CUSTOM_ID: h:c958e087-1d23-4a25-afdd-db7bf5606b4c :END: -When sorting by =title=, =keywords=, or =signature= with the -~denote-sort-dired~ command, Denote will internally apply a sorting -function that is specific to each component ([[#h:a34228cb-484f-48fe-9cbc-8e41f313127b][Configure what extra prompts ~denote-sort-dired~ issues]]). -These are subject to user configuration: +When sorting by =title=, =keywords=, =signature=, =identifier=, or +=random= with the ~denote-dired~ command (alias ~denote-sort-dired~), +Denote will internally apply a sorting function that is specific to +each component ([[#h:a34228cb-484f-48fe-9cbc-8e41f313127b][Configure what extra prompts ~denote-sort-dired~ issues]]). + +With the exception of =random=, the sorting of file name components +is subject to user configuration: #+vindex: denote-sort-identifier-comparison-function -- ~denote-sort-identifier-comparison-function~ +- ~denote-sort-identifier-comparison-function~ :: The function to sort + by the file name identifier. #+vindex: denote-sort-title-comparison-function -- ~denote-sort-title-comparison-function~ +- ~denote-sort-title-comparison-function~ :: The function to sort by + the file name title. #+vindex: denote-sort-keywords-comparison-function -- ~denote-sort-keywords-comparison-function~ +- ~denote-sort-keywords-comparison-function~ :: The function to sort + by the file name keywords. #+vindex: denote-sort-signature-comparison-function -- ~denote-sort-signature-comparison-function~ +- ~denote-sort-signature-comparison-function~ :: The function to sort + by the file name signature. -By default, all these user options use the same sorting function, +By default, all these user options use the same comparison function, namely ~string-collate-lessp~. Users who have specific needs for any of those file name components can write their own sorting algorithms ([[#h:95345870-4ccd-484f-9adf-de4747ad5760][Sort signatures that include Luhmann-style sequences]]). @@ -6308,9 +6315,9 @@ Denote is meant to be a collective effort. Every bit of help matters. Prevos, Philip Kaludercic, Quiliro Ordóñez, Stephen R. Kifer, Stefan Monnier, Stefan Thesing, Thibaut Benjamin, Tomasz Hołubowicz, TomoeMami , Vedang Manerikar, Wesley Harvey, Zhenxu Xu, arsaber101, - bryanrinders, eum3l, ezchi, jarofromel, leinfink (Henrik), l-o-l-h - (Lincoln), mattyonweb, maxbrieiev, mentalisttraceur, pmenair, - relict007, skissue. + bryanrinders, eum3l, experimental-code-86, ezchi, jarofromel, + leinfink (Henrik), l-o-l-h (Lincoln), mattyonweb, maxbrieiev, + mentalisttraceur, pmenair, relict007, skissue. + Ideas and/or user feedback :: Abin Simon, Aditya Yadav, Alan Schmitt, Aleksandr Vityazev, Alex Griffin, Alex Hirschfeld, Alexis diff --git a/denote.el b/denote.el index 03d2c8acf9..cff0964820 100644 --- a/denote.el +++ b/denote.el @@ -1408,7 +1408,7 @@ Return the absolute path to the matching file." (defconst denote-sort-comparison-fallback-function #'string-collate-lessp "String comparison function used by `denote-sort-files' subroutines.") -(defconst denote-sort-components '(title keywords signature identifier) +(defconst denote-sort-components '(title keywords signature identifier random) "List of sorting keys applicable for `denote-sort-files' and related.") (defcustom denote-sort-identifier-comparison-function denote-sort-comparison-fallback-function @@ -1478,8 +1478,9 @@ minibuffer prompt for which file name component to sort by." (const :tag "Sort by identifier (default)" identifier) (const :tag "Sort by title" title) (const :tag "Sort by keywords" keywords) - (const :tag "Sort by signature" signature)) - :package-version '(denote . "3.1.0") + (const :tag "Sort by signature" signature) + (const :tag "Random order" random)) + :package-version '(denote . "4.1.0") :group 'denote-sort) (defcustom denote-sort-dired-default-reverse-sort nil @@ -1519,6 +1520,17 @@ The `%s' performs the comparison." (denote-sort--define-lessp keywords) (denote-sort--define-lessp signature) +(defun denote-sort-random (elements) + "Shuffle ELEMENTS of list randomly." + (let* ((elements (copy-sequence elements)) + (shuffled-list nil)) + (while elements + (let* ((list-length (length elements)) + (element (nth (random list-length) elements))) + (setq elements (delq element elements)) + (push element shuffled-list))) + shuffled-list)) + ;;;###autoload (defun denote-sort-files (files component &optional reverse) "Returned sorted list of Denote FILES. @@ -1534,17 +1546,21 @@ With COMPONENT as a nil value keep the original date-based sorting which relies on the identifier of each file name. With optional REVERSE as a non-nil value, reverse the sort order." - (let* ((files-to-sort (copy-sequence files)) - (sort-fn (pcase component - ((pred functionp) component) - ('identifier #'denote-sort-identifier-lessp) - ('title #'denote-sort-title-lessp) - ('keywords #'denote-sort-keywords-lessp) - ('signature #'denote-sort-signature-lessp))) - (sorted-files (if sort-fn (sort files sort-fn) files-to-sort))) - (if reverse - (reverse sorted-files) - sorted-files))) + (let ((files-to-sort (copy-sequence files))) + (if (eq component 'random) + (denote-sort-random files) + (let* ((sort-fn (pcase component + ((pred functionp) component) + ('identifier #'denote-sort-identifier-lessp) + ('title #'denote-sort-title-lessp) + ('keywords #'denote-sort-keywords-lessp) + ('signature #'denote-sort-signature-lessp))) + (sorted-files (if sort-fn + (sort files sort-fn) + files-to-sort))) + (if reverse + (reverse sorted-files) + sorted-files))))) (defun denote-sort-get-directory-files (files-matching-regexp sort-by-component &optional reverse omit-current exclude-regexp) "Return sorted list of files in variable `denote-directory'.