branch: externals/denote
commit 626b7a8f9101770d401a59b51ec19365bbbf20a4
Author: Jean-Philippe Gagné Guay <jeanphilippe...@gmail.com>
Commit: Jean-Philippe Gagné Guay <jeanphilippe...@gmail.com>

    Rework the fontification
---
 denote.el | 156 +++++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 125 insertions(+), 31 deletions(-)

diff --git a/denote.el b/denote.el
index 6371a415b9..8f5b9bff32 100644
--- a/denote.el
+++ b/denote.el
@@ -3323,37 +3323,131 @@ and seconds."
   :group 'denote-faces
   :package-version '(denote . "2.1.0"))
 
-(defvar denote-faces--file-name-regexp
-  (concat "\\(?11:[\t\s]+\\|.*/\\)?"
-          "\\(?1:[0-9]\\{4\\}\\)\\(?12:[0-9]\\{2\\}\\)\\(?13:[0-9]\\{2\\}\\)"
-          "\\(?10:T\\)"
-          "\\(?2:[0-9]\\{2\\}\\)\\(?14:[0-9]\\{2\\}\\)\\(?15:[0-9]\\{2\\}\\)"
-          "\\(?:\\(?3:==\\)\\(?4:[^.]*?\\)\\)?"
-          "\\(?:\\(?5:--\\)\\(?6:[^.]*?\\)\\)?"
-          "\\(?:\\(?7:__\\)\\(?8:[^.]*?\\)\\)?"
-          "\\(?9:\\..*\\)?$")
-  "Regexp of file names for fontification.")
-
-(defconst denote-faces-file-name-keywords
-  `((,denote-faces--file-name-regexp
-     (11 'denote-faces-subdirectory nil t)
+;; The following matchers must obey the doc of `font-lock-keywords':
+;;   - Have one parameter, the limit of the search
+;;   - Set match-data (and restore it on failure)
+;;   - Move point after the match (or restore it on failure).
+;;   - Return t on success and nil on failure. re-search-forward returns 
(point) on success. It may be better to do the same.
+
+(defun denote-faces-dired-file-name-matcher (limit)
+  "Find the file name in a Dired line, not looking beyond LIMIT."
+  (let ((initial-match-data (match-data))
+        (initial-point (point)))
+    (if (and (re-search-forward "^.+$" limit t) ; A non-empty line
+             (dired-move-to-filename))          ; ... with a file name
+        (let ((beginning-point (point)))
+          (goto-char (match-end 0))
+          (set-match-data (list beginning-point (match-end 0)))
+          (point))
+      (goto-char initial-point)
+      (set-match-data initial-match-data)
+      nil)))
+
+(defun denote-faces-directory-matcher (limit)
+  "Match the directory in a Dired line, not looking beyond LIMIT."
+  (let ((initial-match-data (match-data))
+        (initial-point (point)))
+    (if (re-search-forward "\\(?1:.*/\\)[^/]*$" limit t)
+        (progn
+          (goto-char (match-end 1))
+          (set-match-data (list (match-beginning 1) (match-end 1)))
+          (point))
+      (goto-char initial-point)
+      (set-match-data initial-match-data)
+      nil)))
+
+(defun denote-faces-signature-matcher (limit)
+  "Match the signature in a Dired line, not looking beyond LIMIT."
+  (let ((initial-match-data (match-data))
+        (initial-point (point)))
+    (if (or (re-search-forward 
"==\\(?1:[^/]*?\\)\\(@@\\|--\\|__\\|==\\|\\.\\)[^/]*$" limit t)
+            (re-search-forward "==\\(?1:[^/]*\\)$" limit t))
+        (progn
+          (goto-char (match-end 1))
+          (set-match-data (list (match-beginning 1) (match-end 1)))
+          (point))
+      (goto-char initial-point)
+      (set-match-data initial-match-data)
+      nil)))
+
+(defun denote-faces-title-matcher (limit)
+  "Match the title in a Dired line, not looking beyond LIMIT."
+  (let ((initial-match-data (match-data))
+        (initial-point (point)))
+    (if (or (re-search-forward 
"--\\(?1:[^/]*?\\)\\(@@\\|__\\|==\\|\\.\\)[^/]*$" limit t)
+            (re-search-forward "--\\(?1:[^/]*\\)$" limit t))
+        (progn
+          (goto-char (match-end 1))
+          (set-match-data (list (match-beginning 1) (match-end 1)))
+          (point))
+      (goto-char initial-point)
+      (set-match-data initial-match-data)
+      nil)))
+
+(defun denote-faces-keywords-matcher (limit)
+  "Match the keywords in a Dired line, not looking beyond LIMIT."
+  (let ((initial-match-data (match-data))
+        (initial-point (point)))
+    (if (or (re-search-forward 
"__\\(?1:[^/]*?\\)\\(@@\\|--\\|__\\|==\\|\\.\\)[^/]*$" limit t)
+            (re-search-forward "__\\(?1:[^/]*\\)$" limit t))
+        (progn
+          (goto-char (match-end 1))
+          (set-match-data (list (match-beginning 1) (match-end 1)))
+          (point))
+      (goto-char initial-point)
+      (set-match-data initial-match-data)
+      nil)))
+
+(defconst denote-faces-matchers
+  `((denote-faces-directory-matcher
+     (goto-char (match-beginning 0))
+     (goto-char (match-end 0))
+     (0 'denote-faces-subdirectory nil t))
+    ;; Identifier anywhere in the file name.
+    
("\\(?1:[0-9]\\{4\\}\\)\\(?2:[0-9]\\{2\\}\\)\\(?3:[0-9]\\{2\\}\\)\\(?7:T\\)\\(?4:[0-9]\\{2\\}\\)\\(?5:[0-9]\\{2\\}\\)\\(?6:[0-9]\\{2\\}\\)"
+     (goto-char (match-beginning 0)) ; pre-form, executed before looking for 
the first identifier
+     (goto-char (match-end 0))       ; post-form, executed after all matches 
(identifiers here) are found
      (1 'denote-faces-year nil t)
-     (12 'denote-faces-month nil t)
-     (13 'denote-faces-day nil t)
-     (10 'denote-faces-time-delimiter nil t)
-     (2 'denote-faces-hour nil t)
-     (14 'denote-faces-minute nil t)
-     (15 'denote-faces-second nil t)
-     (3 'denote-faces-delimiter nil t)
-     (4 'denote-faces-signature nil t)
-     (5 'denote-faces-delimiter nil t)
-     (6 'denote-faces-title nil t)
-     (7 'denote-faces-delimiter nil t)
-     (8 'denote-faces-keywords nil t)
-     (9 'denote-faces-extension nil t )))
+     (2 'denote-faces-month nil t)
+     (3 'denote-faces-day nil t)
+     (4 'denote-faces-hour nil t)
+     (5 'denote-faces-minute nil t)
+     (6 'denote-faces-second nil t)
+     (7 'denote-faces-delimiter nil t))
+    ;; Title
+    (denote-faces-title-matcher
+     (goto-char (match-beginning 0))
+     (goto-char (match-end 0))
+     (0 'denote-faces-title nil t))
+    ;; Keywords
+    (denote-faces-keywords-matcher
+     (goto-char (match-beginning 0))
+     (goto-char (match-end 0))
+     (0 'denote-faces-keywords nil t))
+    ;; Signature
+    (denote-faces-signature-matcher
+     (goto-char (match-beginning 0))
+     (goto-char (match-end 0))
+     (0 'denote-faces-signature nil t))
+    ;; Delimiters
+    ("\\(@@\\|--\\|__\\|==\\)"
+     (goto-char (match-beginning 0))
+     (goto-char (match-end 0))
+     (0 'denote-faces-delimiter nil t))
+    ;; Extension
+    ("\\..*$"
+     (goto-char (match-beginning 0))
+     (goto-char (match-end 0))
+     (0 'denote-faces-extension nil t)))
+  "Matchers for fontification of file names.")
+
+(defconst denote-faces-file-name-keywords-for-dired
+  `((denote-faces-dired-file-name-matcher ,@denote-faces-matchers))
   "Keywords for fontification of file names.")
 
-(make-obsolete-variable 'denote-faces-file-name-keywords-for-backlinks nil 
"2.2.0")
+(defconst denote-faces-file-name-keywords-for-backlinks
+  `(("^.+$" ,@denote-faces-matchers))
+  "Keywords for fontification of file names.")
 
 (defface denote-faces-prompt-old-name '((t :inherit error))
   "Face for the old name shown in the prompt of `denote-rename-file' etc."
@@ -3408,13 +3502,13 @@ Otherwise `denote-dired-directories' works only with 
exact matches."
   ;; None of them could be unset upon disabling `denote-dired-mode'.
   ;; As such, I am using the `when' here.
   (when (derived-mode-p 'dired-mode)
-    (font-lock-add-keywords nil denote-faces-file-name-keywords t)))
+    (font-lock-add-keywords nil denote-faces-file-name-keywords-for-dired t)))
 
 (defun denote-dired-remove-font-lock (&rest _)
   "Remove `denote-faces-file-name-keywords' from font lock keywords."
   ;; See NOTE in `denote-dired-add-font-lock'.
   (when (derived-mode-p 'dired-mode)
-    (font-lock-remove-keywords nil denote-faces-file-name-keywords)))
+    (font-lock-remove-keywords nil denote-faces-file-name-keywords-for-dired)))
 
 (declare-function wdired-change-to-wdired-mode "wdired")
 (declare-function wdired-finish-edit "wdired")
@@ -4013,7 +4107,7 @@ matching identifiers."
   :interactive nil
   "Major mode for backlinks buffers."
   (unless denote-backlinks-show-context
-    (font-lock-add-keywords nil denote-faces-file-name-keywords t)))
+    (font-lock-add-keywords nil denote-faces-file-name-keywords-for-backlinks 
t)))
 
 (defun denote-link--prepare-backlinks (query &optional files-matching-regexp 
buffer-name display-buffer-action)
   "Create backlinks' buffer called BUFFER-NAME for the current file matching 
QUERY.

Reply via email to