branch: externals/denote commit b43149df38920d2bf1d766a34cb755c2221f191e Author: Jean-Philippe Gagné Guay <jeanphilippe...@gmail.com> Commit: Jean-Philippe Gagné Guay <jeanphilippe...@gmail.com>
Add denote-retrieve-xref-alist-for-backlinks Also add denote--get-files-by-file-type and denote--get-all-backlinks --- denote.el | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/denote.el b/denote.el index db8470b6ec..ae52ef47cc 100644 --- a/denote.el +++ b/denote.el @@ -2743,6 +2743,66 @@ If FILES is not given, use all text files as returned by (mapcar (lambda (x) (assoc x data)) files-sorted) data))) +(defun denote--get-files-by-file-type (files) + "Return hash table of FILES by file type." + (let ((file-type-hash-table (make-hash-table)) + (file-types (denote--file-type-keys))) + (dolist (file-type file-types) + (puthash file-type '() file-type-hash-table)) + (dolist (file files) + (when-let* ((file-type (denote-file-type file))) + (push file (gethash file-type file-type-hash-table)))) + file-type-hash-table)) + +(defun denote--get-all-backlinks (files) + "Return hash table of all backlinks in FILES by identifier." + (let ((links-hash-table (make-hash-table :test 'equal)) + (file-types (denote--file-type-keys)) + (files-by-file-type (denote--get-files-by-file-type files))) + (dolist (file-type file-types) + (let* ((file-type-files (gethash file-type files-by-file-type)) + (regexp (denote--link-in-context-regexp file-type))) + (dolist (file file-type-files) + (let* ((file-identifiers + (with-temp-buffer + (insert-file-contents file) + (denote-link--collect-identifiers regexp)))) + (dolist (file-identifier file-identifiers) + (if-let* ((links (gethash file-identifier links-hash-table))) + (puthash file-identifier (push file links) links-hash-table) + (puthash file-identifier (list file) links-hash-table))))))) + links-hash-table)) + +(defun denote-retrieve-xref-alist-for-backlinks (identifier) + "Return xref alist of absolute file paths of matches for IDENTIFIER." + (let* ((files (denote-directory-files)) + (file-types (denote--file-type-keys)) + (xref-file-name-display 'abs) + (xref-matches '())) + (when-let* ((backlinks (gethash identifier (denote--get-all-backlinks files)))) + (let* ((backlinks-by-file-type (denote--get-files-by-file-type backlinks))) + (dolist (file-type file-types) + (when-let* ((current-backlinks (gethash file-type backlinks-by-file-type)) + (format-parts (string-split + (denote--link-retrieval-format file-type) + "%VALUE%")) ; Should give two parts + (query-simple (concat + (regexp-quote (nth 0 format-parts)) + (regexp-quote identifier) + (regexp-quote (nth 1 format-parts)))) + (query-org-link (concat + (regexp-quote (nth 0 format-parts)) + (regexp-quote identifier) + "::"))) + (setq xref-matches (append xref-matches (xref-matches-in-files query-simple current-backlinks))) + (setq xref-matches (append xref-matches (xref-matches-in-files query-org-link current-backlinks)))))) + (let ((data (xref--analyze xref-matches))) + (if-let* ((sort denote-query-sorting) + (files-matched (mapcar #'car data)) + (files-sorted (denote-sort-files files-matched sort))) + (mapcar (lambda (x) (assoc x data)) files-sorted) + data))))) + ;;;; New note ;;;;; Common helpers for new notes