all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Hong Xu <hong@topbug.net>
To: 25022@debbugs.gnu.org
Subject: bug#25022: 25.1.50; Different highlighting for different citation level in message-mode
Date: Mon, 05 Dec 2016 22:08:46 -0800	[thread overview]
Message-ID: <87lgvtio7l.fsf@topbug.net> (raw)
In-Reply-To: <87r360o448.fsf@topbug.net>


[-- Attachment #1.1: message-cited-text-color.png --]
[-- Type: image/png, Size: 98934 bytes --]

[-- Attachment #1.2: Type: text/plain, Size: 1131 bytes --]


On 2016-11-24 Thu 15:22 GMT-0800, Hong Xu <hong@topbug.net> wrote:

> Currently in message-mode all cited texts are highlighted in the same
> way. It would be nicer if the highlighting of different citation levels
> can be easily customized.
>

Here is a patch and a screenshot. The default colors I chose may not be
optimal -- but I guess I'll leave that part to professionals.

Add support for different faces for different citation levels in message-mode.

	* message.el (message-font-lock-keywords)
	(message-font-lock-make-cited-text-matcher): Add support for
	different faces for different citation levels.  The faces are
	defined in the faces named `message-cited-text-N': N of the
	Mth citation level will be M mod 4.
	(message-cited-text-1, message-cited-text-2)
	(message-cited-text-3, message-cited-text-4): Add customization
	for the faces of 4 different citation level.  In the future, the
	number of faces may increase, as the code is flexible enough to
	automatically deal with that.
	(message-cite-level-function): Add a function to customize the
	determination of cite levels given the prefix of the cited text.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.3: message.patch --]
[-- Type: text/x-diff, Size: 7638 bytes --]

diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index 448ba7b99718..a61ced374aaf 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -649,6 +649,11 @@ message-cite-prefix-regexp
 	       (setq gnus-message-cite-prefix-regexp
 		     (concat "^\\(?:" value "\\)"))))))
 
+(defcustom message-cite-level-function
+  (lambda (s) (cl-count ?> s))
+  "A function to determine the level of cited text.  The function
+  accepts 1 parameter which is the matched prefix.")
+
 (defcustom message-cancel-message "I am canceling my own article.\n"
   "Message to be inserted in the cancel message."
   :group 'message-interface
@@ -1548,18 +1553,57 @@ message-separator
 (put 'message-separator-face 'face-alias 'message-separator)
 (put 'message-separator-face 'obsolete-face "22.1")
 
-(defface message-cited-text
+(defface message-cited-text-1
   '((((class color)
       (background dark))
      (:foreground "LightPink1"))
     (((class color)
       (background light))
-     (:foreground "red"))
+     (:foreground "red1"))
+    (t
+     (:bold t)))
+  "Face used for displaying 1st-level cited text."
+  :group 'message-faces)
+
+(defface message-cited-text-2
+  '((((class color)
+      (background dark))
+     (:foreground "forest green"))
+    (((class color)
+      (background light))
+     (:foreground "red4"))
     (t
      (:bold t)))
-  "Face used for displaying cited text names."
+  "Face used for displaying 2nd-level cited text."
   :group 'message-faces)
+
+(defface message-cited-text-3
+  '((((class color)
+      (background dark))
+     (:foreground "goldenrod3"))
+    (((class color)
+      (background light))
+     (:foreground "OliveDrab4"))
+    (t
+     (:bold t)))
+  "Face used for displaying 3rd-level cited text."
+  :group 'message-faces)
+
+(defface message-cited-text-4
+  '((((class color)
+      (background dark))
+     (:foreground "chocolate3"))
+    (((class color)
+      (background light))
+     (:foreground "SteelBlue4"))
+    (t
+     (:bold t)))
+  "Face used for displaying 4th-level cited text."
+  :group 'message-faces)
+
 ;; backward-compatibility alias
+(put 'message-cited-text 'face-alias 'message-cited-text-1)
+(put 'message-cited-text 'obsolete-face "26.1")
 (put 'message-cited-text-face 'face-alias 'message-cited-text)
 (put 'message-cited-text-face 'obsolete-face "22.1")
 
@@ -1596,45 +1640,83 @@ message-font-lock-make-header-matcher
 	(byte-compile form)
       form)))
 
+(defun message-font-lock-make-cited-text-matcher (level maxlevel)
+  "Generate the matcher for cited text.  LEVEL is the citation
+level to be matched and MAXLEVEL is the number of levels
+specified in the faces `message-cited-text-*'."
+  (byte-compile
+   `(lambda (limit)
+      (let (matched)
+        ;; Keep search until `message-cite-level-function' returns the level
+        ;; we want to match.
+        (while
+            (and (re-search-forward (concat "^\\("
+                                            message-cite-prefix-regexp
+                                            "\\).*")
+                                    limit t)
+                 (not (setq matched
+                            (save-match-data
+                              (= ,(1- level)
+                                 (mod
+                                  (1- (funcall message-cite-level-function
+                                               (match-string 1)))
+                                  ,maxlevel)))))))
+        matched))))
+
 (defvar message-font-lock-keywords
-  (let ((content "[ \t]*\\(.+\\(\n[ \t].*\\)*\\)\n?"))
-    `((,(message-font-lock-make-header-matcher
-	 (concat "^\\([Tt]o:\\)" content))
-       (1 'message-header-name)
-       (2 'message-header-to nil t))
-      (,(message-font-lock-make-header-matcher
-	 (concat "^\\(^[GBF]?[Cc][Cc]:\\|^[Rr]eply-[Tt]o:\\)" content))
-       (1 'message-header-name)
-       (2 'message-header-cc nil t))
-      (,(message-font-lock-make-header-matcher
-	 (concat "^\\([Ss]ubject:\\)" content))
-       (1 'message-header-name)
-       (2 'message-header-subject nil t))
-      (,(message-font-lock-make-header-matcher
-	 (concat "^\\([Nn]ewsgroups:\\|Followup-[Tt]o:\\)" content))
-       (1 'message-header-name)
-       (2 'message-header-newsgroups nil t))
-      (,(message-font-lock-make-header-matcher
-	 (concat "^\\(X-[A-Za-z0-9-]+:\\|In-Reply-To:\\)" content))
-       (1 'message-header-name)
-       (2 'message-header-xheader))
-      (,(message-font-lock-make-header-matcher
-	 (concat "^\\([A-Z][^: \n\t]+:\\)" content))
-       (1 'message-header-name)
-       (2 'message-header-other nil t))
-      ,@(if (and mail-header-separator
-		 (not (equal mail-header-separator "")))
-	    `((,(concat "^\\(" (regexp-quote mail-header-separator) "\\)$")
-	       1 'message-separator))
-	  nil)
-      ((lambda (limit)
-	 (re-search-forward (concat "^\\("
-				    message-cite-prefix-regexp
-				    "\\).*")
-			    limit t))
-       (0 'message-cited-text))
-      ("<#/?\\(multipart\\|part\\|external\\|mml\\|secure\\)[^>]*>"
-       (0 'message-mml))))
+  (nconc
+   (let ((content "[ \t]*\\(.+\\(\n[ \t].*\\)*\\)\n?"))
+     `((,(message-font-lock-make-header-matcher
+          (concat "^\\([Tt]o:\\)" content))
+        (1 'message-header-name)
+        (2 'message-header-to nil t))
+       (,(message-font-lock-make-header-matcher
+          (concat "^\\(^[GBF]?[Cc][Cc]:\\|^[Rr]eply-[Tt]o:\\)" content))
+        (1 'message-header-name)
+        (2 'message-header-cc nil t))
+       (,(message-font-lock-make-header-matcher
+          (concat "^\\([Ss]ubject:\\)" content))
+        (1 'message-header-name)
+        (2 'message-header-subject nil t))
+       (,(message-font-lock-make-header-matcher
+          (concat "^\\([Nn]ewsgroups:\\|Followup-[Tt]o:\\)" content))
+        (1 'message-header-name)
+        (2 'message-header-newsgroups nil t))
+       (,(message-font-lock-make-header-matcher
+          (concat "^\\(X-[A-Za-z0-9-]+:\\|In-Reply-To:\\)" content))
+        (1 'message-header-name)
+        (2 'message-header-xheader))
+       (,(message-font-lock-make-header-matcher
+          (concat "^\\([A-Z][^: \n\t]+:\\)" content))
+        (1 'message-header-name)
+        (2 'message-header-other nil t))
+       ,@(if (and mail-header-separator
+                  (not (equal mail-header-separator "")))
+             `((,(concat "^\\(" (regexp-quote mail-header-separator) "\\)$")
+                1 'message-separator))
+           nil)
+       ("<#/?\\(multipart\\|part\\|external\\|mml\\|secure\\)[^>]*>"
+        (0 'message-mml))))
+   ;; Additional font locks to highlight different levels of cited text
+   (let ((maxlevel 1)
+         (level 1)
+         cited-text-face
+         keywords)
+     ;; Compute the max level.
+     (while (setq cited-text-face
+                  (intern-soft (format "message-cited-text-%d" maxlevel)))
+       (setq maxlevel (1+ maxlevel)))
+     (setq maxlevel (1- maxlevel))
+     ;; Generate the keywords.
+     (while (setq cited-text-face
+                  (intern-soft (format "message-cited-text-%d" level)))
+       (setq keywords
+             (cons
+              `(,(message-font-lock-make-cited-text-matcher level maxlevel)
+                (0 ',cited-text-face))
+              keywords))
+       (setq level (1+ level)))
+     keywords))
   "Additional expressions to highlight in Message mode.")
 
 (defvar message-face-alist

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

  reply	other threads:[~2016-12-06  6:08 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-24 23:22 bug#25022: 25.1.50; Different highlighting for different citation level in message-mode Hong Xu
2016-12-06  6:08 ` Hong Xu [this message]
2016-12-06  7:39   ` Katsumi Yamaoka
2016-12-06  8:52     ` Hong Xu
2016-12-06 10:08       ` Katsumi Yamaoka
2019-06-24 23:30         ` Lars Ingebrigtsen
2016-12-06  9:17     ` Hong Xu
2016-12-06 15:31       ` Eli Zaretskii
2016-12-06 15:51         ` Lars Ingebrigtsen
2016-12-06 19:57           ` Hong Xu
2016-12-06 20:04         ` Hong Xu
2019-09-23 11:12   ` Lars Ingebrigtsen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87lgvtio7l.fsf@topbug.net \
    --to=hong@topbug.net \
    --cc=25022@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.