branch: externals/denote
commit c2f3ca7cf49a44a50f73ba87fee17100914e32fd
Author: Protesilaos Stavrou <i...@protesilaos.com>
Commit: Protesilaos Stavrou <i...@protesilaos.com>

    Make denote-fontify-links also work with query links
    
    The technical discussion for this is in issue 561:
    <https://github.com/protesilaos/denote/issues/561>.
---
 denote.el | 128 +++++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 68 insertions(+), 60 deletions(-)

diff --git a/denote.el b/denote.el
index 8658982f0e..9bf7ed4b67 100644
--- a/denote.el
+++ b/denote.el
@@ -5109,20 +5109,16 @@ file's title.  This has the same meaning as in 
`denote-link'."
 
 ;;;;; Link buttons
 
-(defun denote-link--find-file-at-button (button)
-  "Visit file referenced by BUTTON."
-  (let* ((id (denote-extract-id-from-string
-              (buffer-substring-no-properties
-               (button-start button)
-               (button-end button))))
-         (file (denote-get-path-by-id id)))
-    (funcall denote-open-link-function file)))
+(make-obsolete 'denote-link--find-file-at-button nil "4.0.0")
 
 (make-obsolete
  'denote-link-buttonize-buffer
  'denote-fontify-links-mode
  "Use the `denote-fontify-links-mode', as it works better than buttonization. 
Since 3.0.0")
 
+;; NOTE 2025-03-24: This does not work for query links because of how
+;; `markdown-follow-link-at-point' is implemented to always check for
+;; links.
 (defun denote-link-markdown-follow (link)
   "Function to open Denote file present in LINK.
 To be assigned to `markdown-follow-link-functions'."
@@ -5146,67 +5142,78 @@ To be assigned to `markdown-follow-link-functions'."
     map)
   "Keymap for mouse actions over fontified Denote links.")
 
+(defun denote--link-open-at-point-subr ()
+  "Open link at point."
+  (let* ((query (get-text-property (point) 'denote-link-query-part))
+         (path (denote-get-path-by-id query)))
+    (if path
+        (funcall denote-open-link-function path)
+      (funcall denote-query-links-buffer-function query 
denote-query-links-display-buffer-action))))
+
+(defun denote-link-open-at-point ()
+  "Open Denote link at point."
+  (interactive)
+  (denote--link-open-at-point-subr))
+
 (defun denote-link-open-at-mouse (ev)
   "Open Denote link for mouse EV click."
   (interactive "e")
   (mouse-set-point ev)
-  (if-let* ((id (get-text-property (point) 'denote-link-id))
-            (path (denote-get-path-by-id id)))
-      (funcall denote-open-link-function path)
-    (error "Cannot resolve the link at point")))
-
-(defun denote-fontify-links (&optional limit)
-  "Fontify Denote links up until optional LIMIT.
+  (denote--link-open-at-point-subr))
 
+(defun denote--fontify-links-subr (query limit)
+  "Do the work of the font-lock match for QUERY up to LIMIT.
 Implementation based on the function `org-activate-links'."
   (catch :exit
-    (when-let* ((type (denote-filetype-heuristics (buffer-file-name))))
-      (while (re-search-forward (denote--link-in-context-regexp type) limit t)
-        (save-match-data  ; to return the matches to font-lock
-          (let* ((start (match-beginning 0))
-                 (end (match-end 0))
-                 (visible-start (match-beginning 2))
-                 (visible-end (match-end 2))
-                 (id (match-string-no-properties 1))
-                 (path (denote-get-path-by-id id))
-                 (file-link (concat "file:" path)))
-            ;; FIXME 2024-06-19: Rewrite this (unless...let...if...)
-            ;; because it is hard to reason about. But it works, so no
-            ;; pressure.
-            (unless (let ((face (get-text-property
-                                 (max (1- start) (point-min)) 'face)))
-                      (if (consp face)
-                          (memq 'font-lock-comment-face face)
-                        (eq 'font-lock-comment-face face)))
-              (let* ((properties `(face denote-faces-link
-                                        mouse-face highlight
-                                        keymap ,denote-link-mouse-map
-                                        denote-link-id ,id
-                                        help-echo ,(or 
(denote-retrieve-title-or-filename path type)
-                                                       (concat "denote:" id))
-                                        htmlize-link (:uri ,file-link)
-                                        font-lock-multiline t))
-                     (non-sticky-props
-                      '(rear-nonsticky (mouse-face highlight keymap invisible 
intangible help-echo htmlize-link)))
-                     (face-property 'link)
-                     (hidden (append '(invisible 'denote-link) properties)))
-                (remove-text-properties start end '(invisible nil))
-                (add-text-properties start visible-start hidden)
-                (add-face-text-property start end face-property)
-                (add-text-properties visible-start visible-end properties)
-                (add-text-properties visible-end end hidden)
-                (dolist (pos (list end visible-start visible-end))
-                  (add-text-properties (1- pos) pos non-sticky-props)))
-              (throw :exit t))))))      ; signal success
+    (while (re-search-forward query limit t)
+      (save-match-data  ; to return the matches to font-lock
+        (let* ((start (match-beginning 0))
+               (end (match-end 0))
+               (visible-start (or (match-beginning 2) start))
+               (visible-end (or (match-end 2) end))
+               (query (match-string-no-properties 1)))
+          (let* ((properties `(face denote-faces-link
+                                    mouse-face highlight
+                                    keymap ,denote-link-mouse-map
+                                    denote-link-query-part ,query
+                                    help-echo query
+                                    htmlize-link (:uri ,query)
+                                    font-lock-multiline t))
+                 (non-sticky-props
+                  '(rear-nonsticky (mouse-face highlight keymap invisible 
intangible help-echo htmlize-link)))
+                 (face-property 'link)
+                 (hidden (append '(invisible 'denote-link) properties)))
+            (remove-text-properties start end '(invisible nil))
+            (add-text-properties start visible-start hidden)
+            (add-face-text-property start end face-property)
+            (add-text-properties visible-start visible-end properties)
+            (add-text-properties visible-end end hidden)
+            (dolist (pos (list end visible-start visible-end))
+              (add-text-properties (1- pos) pos non-sticky-props)))
+          (throw :exit t))))      ; signal success
     nil))
 
-(defun denote-get-identifier-at-point (&optional point)
-  "Return the Denote identifier at point or optional POINT."
+(defun denote-fontify-links (limit)
+  "Provide font-lock matcher to fontify links up to LIMIT."
+  (when-let* ((type (denote-filetype-heuristics (buffer-file-name))))
+    (denote--fontify-links-subr (denote--link-in-context-regexp type) limit)))
+
+(defun denote-fontify-query-links (limit)
+    "Provide font-lock matcher to fontify query links up to LIMIT."
+  (denote--fontify-links-subr "\\[\\[denote:\\(?1:[^[]*?\\)]]" limit))
+
+(define-obsolete-function-alias
+  'denote-get-identifier-at-point
+  'denote-get-link-identifier-or-query-term-at-point
+  "4.0.0")
+
+(defun denote-get-link-identifier-or-query-term-at-point (&optional point)
+  "Return the Denote identifier or query term at point or optional POINT."
   (when-let* ((position (or point (point)))
               (face-at-point (get-text-property position 'face))
               ((or (eq face-at-point 'denote-faces-link)
                    (member 'denote-faces-link face-at-point))))
-    (or (get-text-property position 'denote-link-id)
+    (or (get-text-property position 'denote-link-query-part)
         (when-let* ((link-data (get-text-property position 'htmlize-link))
                     (link (cadr link-data)))
           (string-match denote-id-regexp link)
@@ -5216,8 +5223,9 @@ Implementation based on the function 
`org-activate-links'."
   "Return link to the Denote file path at point or optional POINT.
 To be used as a `thing-at' provider."
   (when-let* ((position (or point (point)))
-              (id (get-text-property position 'denote-link-id)))
-    (concat "file:" (denote-get-path-by-id id))))
+              (id (get-text-property position 'denote-link-query-part))
+              (path (denote-get-path-by-id id)))
+    (concat "file:" path)))
 
 (defvar thing-at-point-provider-alist)
 
@@ -5241,12 +5249,12 @@ major mode is not `org-mode' (or derived therefrom).  
Consider using
   (if denote-fontify-links-mode
       (progn
         (add-to-invisibility-spec 'denote-link)
-        (font-lock-add-keywords nil '(denote-fontify-links))
+        (font-lock-add-keywords nil '((denote-fontify-links) 
(denote-fontify-query-links)))
         (setq-local thing-at-point-provider-alist
                     (append thing-at-point-provider-alist
                             '((url . denote--get-link-file-path-at-point)))))
     (remove-from-invisibility-spec 'denote-link)
-    (font-lock-remove-keywords nil '(denote-fontify-links))
+    (font-lock-remove-keywords nil '((denote-fontify-links) 
(denote-fontify-query-links)))
     (setq-local thing-at-point-provider-alist
                 (delete
                  '(url . denote--get-link-file-path-at-point)

Reply via email to