0

Why do I get the error: font-lock-fontify-keywords-region: Invalid function: (concat "\\\\" (regexp-opt (quote ("cs" "hepth" "hepph" "heplat" "hepex" "nuclth" "nuclex" "grqc" "qalg" "dgga" ...))) "{\\([0-9]+\\)}")

when this code is evaluated?:

(defvar biblinks-keywords
  '(((concat "\\\\" (regexp-opt '("cs"
                  "hepth"
                  "hepph"
                  "heplat"
                  "hepex"
                  "nuclth"
                  "nuclex"
                  "grqc"
                  "qalg"
                  "dgga"
                  "accphys"
                  "alggeom"
                  "astroph"
                  "chaodyn"
                  "condmat"
                  "nlinsys"
                  "nlinsi"
                  "nlin"
                  "quantph"
                  "solvint"
                  "suprcon"
                  "mathph"
                  "physics")) "{\\([0-9]+\\)}")

     (0 `(face
      link
      keymap
      ,oldarXivid-keymap)
    prepend))))

If I use the following code instead, it works:

(defvar biblinks-keywords
  '(("\\\\\\(?:a\\(?:ccphys\\|lggeom\\|stroph\\)\\|c\\(?:haodyn\\|ondmat\\|s\\)\\|dgga\\|grqc\\|hep\\(?:ex\\|lat\\|[pt]h\\)\\|mathph\\|n\\(?:lin\\(?:s\\(?:i\\|ys\\)\\)?\\|ucl\\(?:ex\\|th\\)\\)\\|physics\\|q\\(?:alg\\|uantph\\)\\|s\\(?:olvint\\|uprcon\\)\\){\\([0-9]+\\)}"
      (0 `(face
           link
           keymap
           ,oldarXivid-keymap)
         prepend))))
phils
  • 48,657
  • 3
  • 76
  • 115
Gabriele Nicolardi
  • 1,199
  • 8
  • 17
  • 1
    Because of the quote, the call to `concat` is not evaluated. You need `backquote`. See e.g. [this Emacs SE question](https://emacs.stackexchange.com/questions/7481/how-to-evaluate-the-variables-before-adding-them-to-a-list/7487#7487). – NickD Feb 01 '21 at 13:50

1 Answers1

1

The documentation for font-lock-keywords tells us:

Each element in a user-level keywords list should have one of these forms:

 MATCHER
 (MATCHER . SUBEXP)
 (MATCHER . FACENAME)
 (MATCHER . HIGHLIGHT)
 (MATCHER HIGHLIGHT ...)
 (eval . FORM)

where MATCHER can be either the regexp to search for, or the
function name to call to make the search ...

Your keywords list was:

(((concat "\\\\" (regexp-opt '("cs" ...)))))

And so the first item of that list is:

((concat "\\\\" (regexp-opt '("cs" ...))))

Which is a cons cell, so the car of that value will be MATCHER (as it is not eval). The car is:

(concat "\\\\" (regexp-opt '("cs" ...)))

MATCHER can either be a regexp or a function name, and it's not a regexp (that would be a string), so it has to be a function name. Therefore Emacs tries to call the function with the name:

(concat "\\\\" (regexp-opt '("cs" ...)))

Hence:

Invalid function: (concat "\\\\" (regexp-opt (quote ("cs" ...))))
phils
  • 48,657
  • 3
  • 76
  • 115