branch: externals/denote-sequence
commit bc60cb03b77f88ca33ef62ef43e73c305ea5220c
Author: Protesilaos Stavrou <[email protected]>
Commit: Protesilaos Stavrou <[email protected]>

    Implement command to view hierarchy.el tree (BUT I WILL CHANGE IT)
    
    I am committing this to have a record of it. But I am not happy with
    what hierarchy.el provides. The tree widget it has lacks many features
    I want to see in such an interface, plus it works with assumptions
    that are not useful for my purposes. I will either remove this command
    altogether, or implement what I need myself.
---
 denote-sequence.el | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 73 insertions(+), 3 deletions(-)

diff --git a/denote-sequence.el b/denote-sequence.el
index 799ebd56f5..5baf69be42 100644
--- a/denote-sequence.el
+++ b/denote-sequence.el
@@ -53,9 +53,6 @@
 
 ;;; Code:
 
-;; TODO 2025-01-08: Test whether the built-in hierarchy.el can be used
-;; to present the sequences in a nice way.  What do we need and how
-;; exactly do we use that library.
 (require 'denote)
 
 (defgroup denote-sequence ()
@@ -1239,5 +1236,78 @@ CHECK THE RESULTING SEQUENCES FOR DUPLICATES."
       (denote-rename-file file 'keep-current 'keep-current new-sequence 
'keep-current 'keep-current)))
   (denote-update-dired-buffers))
 
+;;;; Display a hierarchy
+
+;;;###autoload
+(defun denote-sequence-view-hierarchy (&optional prefix depth)
+  "Show a hierachy of sequences.
+With optional PREFIX string, show only files whose sequence matches it.
+When called interactively, prompt for PREFIX, which is a file whose
+sequence is used.
+
+With optional DEPTH as a number, limit the list to files whose sequence
+is that many levels deep.  For example, 1=1=2 is three levels deep.
+When called interactively, prompt for the depth.
+
+In interactive use, PREFIX is the single universal argument, while DEPTH
+is the double universal argument.  In this case, PREFIX can be an empty
+string, which means to not use a prefix as a restriction."
+  (interactive
+   (let ((arg (prefix-numeric-value current-prefix-arg)))
+     (cond
+      ((= arg 16)
+       (list
+        (denote-sequence-prompt "Limit to files that extend SEQUENCE (empty 
for all)")
+        (denote-sequence-depth-prompt)))
+      ((= arg 4)
+       (list
+        (denote-sequence-prompt "Limit to files that extend SEQUENCE (empty 
for all)")))
+      (t
+       nil))))
+  (require 'hierarchy)
+  (if-let* ((files-with-prefix (if (and prefix (not (string-blank-p prefix)))
+                                   (denote-sequence-get-all-files-with-prefix 
prefix)
+                                 (denote-sequence-get-all-files)))
+            (files-with-depth (if depth
+                                  
(denote-sequence-get-all-files-with-max-depth depth files-with-prefix)
+                                files-with-prefix))
+            ;; NOTE 2025-11-19: We need this to base all our files
+            ;; relative to it.  I was trying to work without it, but
+            ;; nothing yielded the desired results.
+            (phony-root (denote-format-file-name (car (denote-directories)) 
"00000000T000000" '("keyword") "title" ".txt" "0"))
+            (files (append (list phony-root) files-with-depth)))
+      (let* ((buffer (get-buffer-create "*denote-sequence-hierarchy*"))
+             (hierarchy (hierarchy-new))
+             (all-roots (seq-remove
+                         (lambda (file)
+                           (denote-sequence--infer-parent 
(denote-retrieve-filename-signature file)))
+                         (remove phony-root files)))
+             (children-fn (lambda (file)
+                            (condition-case data
+                                (if (string= file phony-root)
+                                    all-roots
+                                  (denote-sequence-get-relative 
(denote-retrieve-filename-signature file) 'children files))
+                              (error (message "Failed childern-fn with data: 
%s" data)))))
+             (label-button-fn (lambda (file indent)
+                                (condition-case data
+                                    (if (string= file phony-root)
+                                        (insert "")
+                                      (let* ((signature 
(denote-retrieve-filename-signature file))
+                                             (title 
(denote-retrieve-title-or-filename file (denote-filetype-heuristics file)))
+                                             (keywords 
(denote-retrieve-filename-keywords-as-list file))
+                                             (children 
(denote-sequence-get-relative signature 'children files)))
+                                        (if children
+                                            (insert (format "%s: %s (%s) [%s]" 
signature title (string-join keywords ", ") (length children)))
+                                          (insert (format "%s: %s (%s)" 
signature title (string-join keywords ", "))))))
+                                  (error (message "Failed label-button-fn with 
data: %s" data)))))
+             (label-action-fn (lambda (file &rest _)
+                                (unless (string= file phony-root)
+                                  (funcall denote-open-link-function file))))
+             (label-fn (hierarchy-labelfn-button label-button-fn 
label-action-fn)))
+        (hierarchy-add-trees hierarchy files nil children-fn nil 
:delay-children-processing)
+        (hierarchy-sort hierarchy #'denote-sequence--file-smaller-p)
+        (display-buffer (hierarchy-tree-display hierarchy label-fn buffer)))
+    (user-error "No sequences found")))
+
 (provide 'denote-sequence)
 ;;; denote-sequence.el ends here

Reply via email to