[Tex/LaTex] Emacs / AUCTeX — Customization of keyword highlight syntax

auctexcoloremacshighlighting

font-lock-keyword-face is used by AUCTeX for all keywords, and I have not been able to find a way to create a new keyword that is a different color.

I have defined the foreground of font-lock-keyword-face to be the color red (with a white background), which affects every defined keyword.

I would like to create my own keyword that stands out from all the rest — e.g., :foreground "yellow" :background "black".

\insert-data

It looks like there are only three (3) major groups available:

  1. keywords (controlled by font-lock-keyword-face);

  2. warnings (controlled by font-latex-warning-face); and

  3. undefined-keywords (controlled by font-latex-sedate-face).

All the examples on the internet appear to focus on changing the color inside square / wavy brackets using the variable font-latex-user-keyword-classes. I have not found any working examples where a new keyword group (with different colors) is created.

NONE of the following examples create a fourth (4th) major group:

;; \EFFECT{[font-lock-type-face]}
(setq font-latex-match-textual-keywords
    '(
        ("parentext" "{")
        ("hybridblockquote" "[{")
    )
)

;; \EFFECT{[font-lock-variable-name-face]}
(setq font-latex-match-variable-keywords
    '(
        ("setlist" "[{")
        ("setlist*" "[{")
    )
)

;; \EFFECT{[font-lock-constant-face]}
(setq font-latex-match-reference-keywords
    '(
        ("citet" "[{")
        ("degrees" "")
        ("units" "{")
    )
 )

;; \font-latex-warning-face
(setq font-latex-match-warning-keywords
    '(
        ("fixme" "{") 
        ("INSERT" "")
    )
)

;; only affects inside wavy square brackets
(setq font-latex-user-keyword-classes
          '(("my-warning-commands"
                (("fixme" "{"))
                (:foreground "purple")
                command))) 

Best Answer

Here is an example of setting somethings up for hi-lock mode.

First define a face:

(defface af-bold-yellow-box '((t  (:background  "yellow" 
                                   :foreground  "black"               
                                   :bold t
                                  )))  "yellow-box-face")

Then you can define a macro to apply your faces to specified regular expressions.

(defun z-hi-lock-quizzes ()
  ;; this next line is necessary to correct sloppy hi-locking
  (if (not hi-lock-mode) 
      (progn (hi-lock-mode -1) 
             (hi-lock-mode  1)) 
    (hi-lock-mode) 
    (hi-lock-mode))
  (highlight-regexp "^%-\\*-mode:LaTeX.*$" (quote hi-conceal-content));
  (highlight-regexp "^%-@-(.+$"            (quote hi-lock-page-break));
)

I define various macros to address highlighting different features. And then I write an interactive macro which assembles and applies these.

(defun ae-hi-lock-features ()
   (interactive)
   (z-hi-lock-quizzes)
   ... call other functions ...
)

FYI I believe all the various faces I use here are faces I've defined. Even in the examples below. But faces are defined as I've illustrated above.


adding to font-lock features

Here's some code that I've used to add elements to font-lock features. But, it's been so long since I wrote this, I don't really know if the following is sufficient to get all the desired results

(setq ae-keywords:tex-mode:list 
      (list  '( comment          "^\\s *\\(%.+$\\)"                       'hi-pink                            )
             '( newpara          "\\(^%-=-.+$\\)"                         'hi-skyblue-boldred-border          )
             '( newsect          "\\(^%-\\#-.+$\\)"                       'hi-goldback-boldbluefront-border   )
             '( newpage          "\\(^%-@-(.+$\\)"                        'hi-lock-page-break                 )
             '( tab              "\\(\t\\)"                               'hi-lightblue-red-text-border       )
             '( begin.doc        "\\(\\\\\\(begin\\|end\\\){document}\\)" 'hi-goldback-boldbluefront-border)
             '( comment.b        "\\(%\\.\\.%.*$\\)"                      'hi-darkblue-lightblue-text)
             '( multiplechoice.a "\\(^\\[o\\] .+$\\)"                     'hi-light-multiple-choices)
             '( multiplechoice.b "\\(^\\[[\\?\\.\\ ]\\] .+$\\)"                   'hi-goldback-boldbluefront-border)
             '( multiplechoice.c "\\(^\\[x\\] .+$\\)"                     'hi-light-multiple-choice-answer)
             ))
(dolist (elt ae-keywords:tex-mode:list)
  (font-lock-add-keywords nil (list (list (nth 1 elt) 1 (nth 2 elt) 'append)))
  )

If the above seem too elaborate, you can do something a bit more direct as in

  (font-lock-add-keywords nil '(("\\(hello\\) \\(World\\)" 
                                2 
                                'hi-goldback-boldbluefront-border)))

EDIT

I think what you probably want to do is something more like

  (font-lock-add-keywords 'latex-mode '(("<regex>" 
                                          <level-of-subexpression>
                                          '<face-name>)))

You probably want to set <level-of-subexpression> to 0, but using subexpressions you can get nice effects as in my hello World example.