branch: externals/denote
commit 875c82c85d7fdea88d5a540dcf2d1ff454501885
Merge: 322d6d493e f984340947
Author: Protesilaos Stavrou <i...@protesilaos.com>
Commit: GitHub <nore...@github.com>

    Merge pull request #541 from frnsd/fix-sequence-prefix
    
    Add tests for false matches addressed by pull request #540 and fix related 
issues
---
 denote-sequence.el   |  57 +++++++++++------
 tests/denote-test.el | 171 +++++++++++++++++++++++++++++++--------------------
 2 files changed, 144 insertions(+), 84 deletions(-)

diff --git a/denote-sequence.el b/denote-sequence.el
index 858c311a0a..d448545972 100644
--- a/denote-sequence.el
+++ b/denote-sequence.el
@@ -340,19 +340,36 @@ With optional FILES consider only those, otherwise use 
the return value
 of `denote-directory-files'."
   (seq-filter #'denote-sequence-file-p (denote-sequence--get-files files)))
 
+(defun denote-sequence--sequence-prefix-p (prefix sequence)
+  "Return non-nil if SEQUENCE has prefix sequence PREFIX.
+
+SEQUENCE is a Denote signatures that conforms with `denote-sequence-p'.
+PREFIX is a list of strings containing the components of the prefix
+sequence, as is returned by `denote-sequence-split'.
+
+If PREFIX is nil, return non-nil as if the SEQUENCE has PREFIX."
+  (let ((value (denote-sequence-split sequence))
+        (depth (length prefix))
+        (matched 0))
+    (while (and value
+                (< matched depth)
+                (string-equal (pop value) (nth matched prefix)))
+      (setq matched (1+ matched)))
+    (= matched depth)))
+
 (defun denote-sequence-get-all-files-with-prefix (sequence &optional files)
   "Return all files in variable `denote-directory' with prefix SEQUENCE.
 A sequence is a Denote signature that conforms with `denote-sequence-p'.
 
 With optional FILES, operate on them, else use the return value of
 `denote-directory-files'."
-  (delq nil
-        (mapcar
-         (lambda (file)
-           (when-let* ((file-sequence (denote-sequence-file-p file))
-                       ((string-prefix-p sequence file-sequence)))
-             file))
-         (denote-sequence-get-all-files files))))
+  (when-let* (((not (string-empty-p sequence)))
+              (prefix (denote-sequence-split sequence)))
+    (seq-filter
+     (lambda (file)
+       (when-let* ((file-sequence (denote-sequence-file-p file)))
+         (denote-sequence--sequence-prefix-p prefix file-sequence)))
+     (denote-sequence-get-all-files files))))
 
 (defun denote-sequence-get-all-files-with-max-depth (depth &optional files)
   "Return all files with sequence depth up to DEPTH (inclusive).
@@ -380,17 +397,11 @@ With optional SEQUENCES operate on those, else use the 
return value of
 `denote-sequence-get-all-sequences'.
 
 A sequence is a Denote signature that conforms with `denote-sequence-p'."
-  (let* ((prefix (denote-sequence-split sequence))
-         (depth (length prefix)))
+  (when-let* (((not (string-empty-p sequence)))
+              (prefix (denote-sequence-split sequence)))
     (seq-filter
      (lambda (string)
-       (let ((value (denote-sequence-split string))
-             (matched 0))
-         (while (and value
-                     (< matched depth)
-                     (string-equal (pop value) (nth matched prefix)))
-           (setq matched (1+ matched)))
-         (= matched depth)))
+       (denote-sequence--sequence-prefix-p prefix string))
      (or sequences (denote-sequence-get-all-sequences)))))
 
 (defun denote-sequence-get-all-sequences-with-max-depth (depth &optional 
sequences)
@@ -612,7 +623,7 @@ returned by `denote-sequence-get-all-files'."
                   (lambda (file)
                     (= (denote-sequence-depth (denote-sequence-file-p file)) 
(+ depth 1)))
                   (funcall filter-common '> sequence)))
-      (_ (error "The type `%s' is not among the `denote-sequence-types'" 
type)))))
+      (_ (error "The type `%s' is not among the allowed types" type)))))
 
 (defvar denote-sequence-type-history nil
   "Minibuffer history of `denote-sequence-type-prompt'.")
@@ -908,10 +919,18 @@ For a more specialised case, see 
`denote-sequence-find-relatives-dired'."
 (defun denote-sequence-find-dired (type)
   "Like `denote-sequence-find' for TYPE but put the matching files in Dired.
 Also see `denote-sequence-dired'."
-  (interactive (list (denote-sequence-type-prompt "Find relatives of TYPE")))
+  (interactive
+   (list (denote-sequence-type-prompt "Find relatives of TYPE"
+                                      '(all-parents
+                                        parent
+                                        siblings
+                                        all-children
+                                        children))))
   (if-let* ((sequence (denote-sequence-file-p buffer-file-name)))
       (if-let* ((default-directory (denote-directory))
-                (relatives (delete buffer-file-name 
(denote-sequence-get-relative sequence type)))
+                (relatives (delete buffer-file-name
+                                   (ensure-list
+                                    (denote-sequence-get-relative sequence 
type))))
                 (files-sorted (denote-sequence-sort-files relatives)))
           (dired (cons (format-message "*`%s' type relatives of `%s'" type 
sequence)
                        (mapcar #'file-relative-name files-sorted)))
diff --git a/tests/denote-test.el b/tests/denote-test.el
index bcb9a624a9..209f906c7e 100644
--- a/tests/denote-test.el
+++ b/tests/denote-test.el
@@ -616,9 +616,15 @@ function `denote-sequence-get-relative'."
              "20241230T075023==1=2--test__testing.txt"
              "20241230T075023==1=2=1--test__testing.txt"
              "20241230T075023==1=2=1=1--test__testing.txt"
-             "20241230T075023==2--test__testing.txt")))
+             "20241230T075023==2--test__testing.txt"
+             "20241230T075023==10--test__testing.txt"
+             "20241230T075023==10=1--test__testing.txt"
+             "20241230T075023==10=1=1--test__testing.txt"
+             "20241230T075023==10=2--test__testing.txt"
+             "20241230T075023==10=10--test__testing.txt"
+             "20241230T075023==10=10=1--test__testing.txt")))
          (sequences (denote-sequence-get-all-sequences files)))
-    (should (string= (denote-sequence-get-new 'parent) "3"))
+    (should (string= (denote-sequence-get-new 'parent) "11"))
 
     (should (and (string= (denote-sequence-get-new 'child "1" sequences) "1=3")
                  (string= (denote-sequence-get-new 'child "1=1" sequences) 
"1=1=3")
@@ -626,96 +632,131 @@ function `denote-sequence-get-relative'."
                  (string= (denote-sequence-get-new 'child "1=2" sequences) 
"1=2=2")
                  (string= (denote-sequence-get-new 'child "1=2=1" sequences) 
"1=2=1=2")
                  (string= (denote-sequence-get-new 'child "2" sequences) 
"2=1")))
-    (should-error (denote-sequence-get-new 'child "3" sequences))
+    (should-error (denote-sequence-get-new 'child "11" sequences))
 
-    (should (and (string= (denote-sequence-get-new 'sibling "1" sequences) "3")
+    (should (and (string= (denote-sequence-get-new 'sibling "1" sequences) 
"11")
                  (string= (denote-sequence-get-new 'sibling "1=1" sequences) 
"1=3")
                  (string= (denote-sequence-get-new 'sibling "1=1=1" sequences) 
"1=1=3")
                  (string= (denote-sequence-get-new 'sibling "1=1=2" sequences) 
"1=1=3")
                  (string= (denote-sequence-get-new 'sibling "1=2" sequences) 
"1=3")
                  (string= (denote-sequence-get-new 'sibling "1=2=1" sequences) 
"1=2=2")
-                 (string= (denote-sequence-get-new 'sibling "2" sequences) 
"3")))
-    (should-error (denote-sequence-get-new 'sibling "4" sequences))
+                 (string= (denote-sequence-get-new 'sibling "2" sequences) 
"11")))
+    (should-error (denote-sequence-get-new 'sibling "12" sequences))
 
     (should (string= (denote-sequence-get-relative "1=2=1=1" 'parent files)
                      (expand-file-name 
"20241230T075023==1=2=1--test__testing.txt" denote-directory)))
+    (should (string= (denote-sequence-get-relative "10=1=1" 'parent files)
+                     (expand-file-name 
"20241230T075023==10=1--test__testing.txt" denote-directory)))
+    (should (string= (denote-sequence-get-relative "10=10=1" 'parent files)
+                     (expand-file-name 
"20241230T075023==10=10--test__testing.txt" denote-directory)))
     (should (equal (denote-sequence-get-relative "1=2=1=1" 'all-parents files)
                    (list
                     (expand-file-name "20241230T075023==1--test__testing.txt" 
denote-directory)
                     (expand-file-name 
"20241230T075023==1=2--test__testing.txt" denote-directory)
                     (expand-file-name 
"20241230T075023==1=2=1--test__testing.txt" denote-directory))))
+    (should (equal (denote-sequence-get-relative "10=1=1" 'all-parents files)
+                   (list
+                    (expand-file-name "20241230T075023==10--test__testing.txt" 
denote-directory)
+                    (expand-file-name 
"20241230T075023==10=1--test__testing.txt" denote-directory))))
+    (should (equal (denote-sequence-get-relative "10=10=1" 'all-parents files)
+                   (list
+                    (expand-file-name "20241230T075023==10--test__testing.txt" 
denote-directory)
+                    (expand-file-name 
"20241230T075023==10=10--test__testing.txt" denote-directory))))
     (should (equal (denote-sequence-get-relative "1=1" 'siblings files)
                    (list
                     (expand-file-name 
"20241230T075023==1=1--test__testing.txt" denote-directory)
                     (expand-file-name 
"20241230T075023==1=2--test__testing.txt" denote-directory))))
+    (should (equal (denote-sequence-get-relative "10=1" 'siblings files)
+                   (list
+                    (expand-file-name 
"20241230T075023==10=1--test__testing.txt" denote-directory)
+                    (expand-file-name 
"20241230T075023==10=2--test__testing.txt" denote-directory)
+                    (expand-file-name 
"20241230T075023==10=10--test__testing.txt" denote-directory))))
     (should (equal (denote-sequence-get-relative "1" 'children files)
                    (list
                     (expand-file-name 
"20241230T075023==1=1--test__testing.txt" denote-directory)
                     (expand-file-name 
"20241230T075023==1=2--test__testing.txt" denote-directory))))
+    (should (equal (denote-sequence-get-relative "10" 'children files)
+                   (list
+                    (expand-file-name 
"20241230T075023==10=1--test__testing.txt" denote-directory)
+                    (expand-file-name 
"20241230T075023==10=2--test__testing.txt" denote-directory)
+                    (expand-file-name 
"20241230T075023==10=10--test__testing.txt" denote-directory))))
     (should (equal (denote-sequence-get-relative "1=1" 'all-children files)
                    (list
                     (expand-file-name 
"20241230T075023==1=1=1--test__testing.txt" denote-directory)
                     (expand-file-name 
"20241230T075023==1=1=2--test__testing.txt" denote-directory)))))
 
-    (let* ((denote-sequence-scheme 'alphanumeric)
-           (denote-directory (expand-file-name "denote-test" 
temporary-file-directory))
-           (files
-            (mapcar
-             (lambda (file)
-               (let ((path (expand-file-name file (denote-directory))))
-                 (if (file-exists-p path)
-                     path
-                   (with-current-buffer (find-file-noselect path)
-                     (save-buffer)
-                     (kill-buffer (current-buffer)))
-                   path)))
-             '("20241230T075023==1--test__testing.txt"
-               "20241230T075023==1a--test__testing.txt"
-               "20241230T075023==1a1--test__testing.txt"
-               "20241230T075023==1a2--test__testing.txt"
-               "20241230T075023==1b--test__testing.txt"
-               "20241230T075023==1b1--test__testing.txt"
-               "20241230T075023==1b1a--test__testing.txt"
-               "20241230T075023==2--test__testing.txt")))
-           (sequences (denote-sequence-get-all-sequences files)))
-      (should (string= (denote-sequence-get-new 'parent) "3"))
-
-      (should (and (string= (denote-sequence-get-new 'child "1" sequences) 
"1c")
-                   (string= (denote-sequence-get-new 'child "1a" sequences) 
"1a3")
-                   (string= (denote-sequence-get-new 'child "1a2" sequences) 
"1a2a")
-                   (string= (denote-sequence-get-new 'child "1b" sequences) 
"1b2")
-                   (string= (denote-sequence-get-new 'child "1b1" sequences) 
"1b1b")
-                   (string= (denote-sequence-get-new 'child "2" sequences) 
"2a")))
-      (should-error (denote-sequence-get-new 'child "3" sequences))
-
-      (should (and (string= (denote-sequence-get-new 'sibling "1" sequences) 
"3")
-                   (string= (denote-sequence-get-new 'sibling "1a" sequences) 
"1c")
-                   (string= (denote-sequence-get-new 'sibling "1a1" sequences) 
"1a3")
-                   (string= (denote-sequence-get-new 'sibling "1a2" sequences) 
"1a3")
-                   (string= (denote-sequence-get-new 'sibling "1b" sequences) 
"1c")
-                   (string= (denote-sequence-get-new 'sibling "1b1" sequences) 
"1b2")
-                   (string= (denote-sequence-get-new 'sibling "2" sequences) 
"3")))
-      (should-error (denote-sequence-get-new 'sibling "4" sequences))
-
-      (should (string= (denote-sequence-get-relative "1b1a" 'parent files)
-                       (expand-file-name 
"20241230T075023==1b1--test__testing.txt" denote-directory)))
-      (should (equal (denote-sequence-get-relative "1b1a" 'all-parents files)
-                     (list
-                      (expand-file-name 
"20241230T075023==1--test__testing.txt" denote-directory)
-                      (expand-file-name 
"20241230T075023==1b--test__testing.txt" denote-directory)
-                      (expand-file-name 
"20241230T075023==1b1--test__testing.txt" denote-directory))))
-      (should (equal (denote-sequence-get-relative "1a" 'siblings files)
-                     (list
-                      (expand-file-name 
"20241230T075023==1a--test__testing.txt" denote-directory)
-                      (expand-file-name 
"20241230T075023==1b--test__testing.txt" denote-directory))))
-      (should (equal (denote-sequence-get-relative "1" 'children files)
-                     (list
-                      (expand-file-name 
"20241230T075023==1a--test__testing.txt" denote-directory)
-                      (expand-file-name 
"20241230T075023==1b--test__testing.txt" denote-directory))))
-      (should (equal (denote-sequence-get-relative "1a" 'all-children files)
-                     (list
-                      (expand-file-name 
"20241230T075023==1a1--test__testing.txt" denote-directory)
-                      (expand-file-name 
"20241230T075023==1a2--test__testing.txt" denote-directory))))))
+  (let* ((denote-sequence-scheme 'alphanumeric)
+         (denote-directory (expand-file-name "denote-test" 
temporary-file-directory))
+         (files
+          (mapcar
+           (lambda (file)
+             (let ((path (expand-file-name file (denote-directory))))
+               (if (file-exists-p path)
+                   path
+                 (with-current-buffer (find-file-noselect path)
+                   (save-buffer)
+                   (kill-buffer (current-buffer)))
+                 path)))
+           '("20241230T075023==1--test__testing.txt"
+             "20241230T075023==1a--test__testing.txt"
+             "20241230T075023==1a1--test__testing.txt"
+             "20241230T075023==1a2--test__testing.txt"
+             "20241230T075023==1b--test__testing.txt"
+             "20241230T075023==1b1--test__testing.txt"
+             "20241230T075023==1b1a--test__testing.txt"
+             "20241230T075023==2--test__testing.txt"
+             "20241230T075023==10--test__testing.txt"
+             "20241230T075023==10a--test__testing.txt"
+             "20241230T075023==10b--test__testing.txt")))
+         (sequences (denote-sequence-get-all-sequences files)))
+    (should (string= (denote-sequence-get-new 'parent) "11"))
+
+    (should (and (string= (denote-sequence-get-new 'child "1" sequences) "1c")
+                 (string= (denote-sequence-get-new 'child "1a" sequences) 
"1a3")
+                 (string= (denote-sequence-get-new 'child "1a2" sequences) 
"1a2a")
+                 (string= (denote-sequence-get-new 'child "1b" sequences) 
"1b2")
+                 (string= (denote-sequence-get-new 'child "1b1" sequences) 
"1b1b")
+                 (string= (denote-sequence-get-new 'child "2" sequences) 
"2a")))
+    (should-error (denote-sequence-get-new 'child "11" sequences))
+
+    (should (and (string= (denote-sequence-get-new 'sibling "1" sequences) 
"11")
+                 (string= (denote-sequence-get-new 'sibling "1a" sequences) 
"1c")
+                 (string= (denote-sequence-get-new 'sibling "1a1" sequences) 
"1a3")
+                 (string= (denote-sequence-get-new 'sibling "1a2" sequences) 
"1a3")
+                 (string= (denote-sequence-get-new 'sibling "1b" sequences) 
"1c")
+                 (string= (denote-sequence-get-new 'sibling "1b1" sequences) 
"1b2")
+                 (string= (denote-sequence-get-new 'sibling "2" sequences) 
"11")))
+    (should-error (denote-sequence-get-new 'sibling "12" sequences))
+
+    (should (string= (denote-sequence-get-relative "1b1a" 'parent files)
+                     (expand-file-name 
"20241230T075023==1b1--test__testing.txt" denote-directory)))
+    (should (string= (denote-sequence-get-relative "10a" 'parent files)
+                     (expand-file-name 
"20241230T075023==10--test__testing.txt" denote-directory)))
+    (should (equal (denote-sequence-get-relative "1b1a" 'all-parents files)
+                   (list
+                    (expand-file-name "20241230T075023==1--test__testing.txt" 
denote-directory)
+                    (expand-file-name "20241230T075023==1b--test__testing.txt" 
denote-directory)
+                    (expand-file-name 
"20241230T075023==1b1--test__testing.txt" denote-directory))))
+    (should (equal (denote-sequence-get-relative "1a" 'siblings files)
+                   (list
+                    (expand-file-name "20241230T075023==1a--test__testing.txt" 
denote-directory)
+                    (expand-file-name "20241230T075023==1b--test__testing.txt" 
denote-directory))))
+    (should (equal (denote-sequence-get-relative "10a" 'siblings files)
+                   (list
+                    (expand-file-name 
"20241230T075023==10a--test__testing.txt" denote-directory)
+                    (expand-file-name 
"20241230T075023==10b--test__testing.txt" denote-directory))))
+    (should (equal (denote-sequence-get-relative "1" 'children files)
+                   (list
+                    (expand-file-name "20241230T075023==1a--test__testing.txt" 
denote-directory)
+                    (expand-file-name "20241230T075023==1b--test__testing.txt" 
denote-directory))))
+    (should (equal (denote-sequence-get-relative "10" 'children files)
+                   (list
+                    (expand-file-name 
"20241230T075023==10a--test__testing.txt" denote-directory)
+                    (expand-file-name 
"20241230T075023==10b--test__testing.txt" denote-directory))))
+    (should (equal (denote-sequence-get-relative "1a" 'all-children files)
+                   (list
+                    (expand-file-name 
"20241230T075023==1a1--test__testing.txt" denote-directory)
+                    (expand-file-name 
"20241230T075023==1a2--test__testing.txt" denote-directory))))))
 
 (ert-deftest dt-denote-sequence-split ()
   "Test that `denote-sequence-split' splits a sequence correctly."

Reply via email to