1

I am trying to define new keywords for org-mode in order to highlight text in buffer. I followed this tutorial and this one which leads me to the following code :

(defface ex-face
  '((t (:foreground "red")))
  "Face for !")

(defface caret-face
  '((t (:foreground "orange")))
  "Face for ^")

(defface at-face
  '((t (:foreground "green")))
  "Face for %%")

(defvar my-org-custom-keywords
  '(("!!" . ex-face)
    ("^^" . caret-face)
    ("%%" . at-face)))

(defun my-org-add-custom-keywords ()
  "Add custom keywords."
  (loop for (delimiter . face) in my-org-custom-keywords
        do (add-to-list 'org-font-lock-extra-keywords
                        `(,(concat "\\(" (regexp-quote delimiter)
                                   "\\)\\([^\n\r\t]+\\)\\("
                                   (regexp-quote delimiter) "\\)")
                          (1 '(face ,face invisible t))
                          (2 ',face)
                          (3 '(face ,face invisible t))))))

(add-hook 'org-font-lock-set-keywords-hook #'my-org-add-custom-keywords)

I restarted emacs.

Unfortunately, when I ask for the value of org-font-lock-set-keywords-hook I always get : enter image description here

: GNU Emacs 26.3 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.14) : of 2020-03-26, modified by Debian : Spacemacs v.0.200.13

2
  • Why can't you set org-font-lock-extra-keywords the way you want in your init file and be done with it? Why do you need a function to set things up and have the function called from a hook? – NickD Dec 1 '20 at 22:07
  • Hi. Thanks for your comment. I am actually too much of a newbie to clearly understand what you means. This code is put in the dotspacemacs/user-config (). – user1683620 Dec 2 '20 at 11:19
0

I think you need to (require 'cl-lib) - that will define the cl-loop macro and you need to modify the code just a bit to use the cl-loop macro:

(require 'cl-lib)
(defface ex-face
  '((t (:foreground "red")))
  "Face for !")

(defface caret-face
  '((t (:foreground "orange")))
  "Face for ^")

(defface at-face
  '((t (:foreground "green")))
  "Face for %%")

(defvar my-org-custom-keywords
  '(("!!" . ex-face)
    ("^^" . caret-face)
    ("%%" . at-face)))

(defun my-org-add-custom-keywords ()
  "Add custom keywords."
  (cl-loop for (delimiter . face) in my-org-custom-keywords
        do (add-to-list 'org-font-lock-extra-keywords
                        `(,(concat "\\(" (regexp-quote delimiter)
                                   "\\)\\([^\n\r\t]+\\)\\("
                                   (regexp-quote delimiter) "\\)")
                          (1 '(face ,face invisible t))
                          (2 ',face)
                          (3 '(face ,face invisible t))))))

(add-hook 'org-font-lock-set-keywords-hook #'my-org-add-custom-keywords)

Assuming that this code is in your ~/.emacs.d/init.el file (or some other init file), then restarting emacs and opening an Org mode file should allow you to enter something like !!exclamation face!! and get what you expect: invisible !! delimiters and a red-foreground exclamation face.

If you do C-h v org-font-lock-set-keywords-hook RET you should get:

org-font-lock-set-keywords-hook is a variable defined in ‘org.el’.
Its value is (my-org-add-custom-keywords)
...

If you do C-h v org-font-lock-extra-keywords RET you will see that its value is nil: that's OK. This variable is only to be used by functions that are called by the hook (BTW, my first comment to your question was wrong: I did not realize then the special character of this variable). The variable that really controls the fontification is org-font-lock-keywords and that is set from the temporary value of org-font-lock-extra-keywords. If you check that variable with C-h v org-font-lock-keywords RET then you should see your entries:

org-font-lock-keywords is a variable defined in ‘org.el’.
Its value is shown below.

  This variable may be risky if used as a file-local variable.

Documentation:
Not documented as a variable.

Value:
(("\\(%%\\)\\([^

    ]+\\)\\(%%\\)"
  (1
   '(face at-face . #1=(invisible t)))
  (2 'at-face)
  (3
   '(face at-face . #2=(invisible t))))
 ("\\(\\^\\^\\)\\([^

    ]+\\)\\(\\^\\^\\)"
  (1
   '(face caret-face . #1#))
  (2 'caret-face)
  (3
   '(face caret-face . #2#)))
 ("\\(!!\\)\\([^

    ]+\\)\\(!!\\)"
  (1
   '(face ex-face . #1#))
  (2 'ex-face)
  (3
   '(face ex-face . #2#)))
 (org-font-lock-hook)
 ...

Assuming that that is the case, the fontification should work.

2
  • Thank you very much ! It works – user1683620 Dec 4 '20 at 6:49
  • If it has answered your question , please accept the answer. – NickD Dec 4 '20 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.