6

How to highlight all the function's name in Emacs' lisp-mode? I want them bolded.

In other words, all the words from ( to the first space. Don't care exceptions like (a . b)

Just like GitHub:

enter image description here

Drew
  • 29,895
  • 7
  • 74
  • 104
kuanyui
  • 782
  • 13
  • 23

2 Answers2

7

Use this:

(defface font-lock-func-face 
    '((nil (:foreground "#7F0055" :weight bold))
      (t (:bold t :italic t)))
  "Font Lock mode face used for function calls."
  :group 'font-lock-highlighting-faces)

(font-lock-add-keywords 
 'emacs-lisp-mode
 '(("(\\s-*\\(\\_<\\(?:\\sw\\|\\s_\\)+\\)\\_>"
    1 'font-lock-func-face)))

A funny thing: this messes up with let bindings, just like Github. But that's what you asked for, right:)?

abo-abo
  • 20,038
  • 3
  • 50
  • 71
  • 1
    Thanks! Now I understand that `\\(...\\)` is the point. But I want to know what is that "1" meaning? – kuanyui Aug 17 '13 at 13:58
  • 1
    1 means `the first captured group`, 2 would mean the second captured group, if there was one. 0 means the whole match – abo-abo Aug 17 '13 at 14:00
  • Better: Please remove the variable, and just leave the `defface`. Face variables are obsolete. You may probably want to use the built-in `font-lock-function-name-face` instead. The regexp fails to catch some fairly common function names (i.e. `string=`, `<=`, `+`, or `foo/bar`). `"(\\s-*\\(\\_<\\(?:\\sw\\|\\s_\\)+\\)\\_>"` gives a more complete coverage. –  Aug 19 '13 at 14:34
  • This will not override already highlighted text: `(font-lock-add-keywords 'lisp-mode '(("(\\s-*\\(\\_<\\(?:\\sw\\|\\s_\\)+\\)\\_>" 1 'font-lock-func-face keep)) t)` – Bad_ptr Jul 21 '17 at 16:17
6

The code below highlights the names of known Emacs-Lisp functions.

Be aware that it does so even if some occurrence of a given function name does not represent the function. For example, the name might be used as a variable name. Not a big problem in practice, but good to know.

;; `setq' is a variable here, but it is highlighted anyway.
(let ((setq  (foobar)))...)

To turn on the highlighting automatically in Emacs-Lisp mode, do this:

(font-lock-add-keywords 'emacs-lisp-mode
                        '((my-fl . 'font-lock-constant-face)) ; Or whatever face you want.                            'APPEND)

(defun my-fl (_limit)
  (let ((opoint  (point))
        (found   nil))
    (with-syntax-table emacs-lisp-mode-syntax-table
      (while (not found)
        (cond ((condition-case ()
                   (save-excursion
                     (skip-chars-forward "'")
                     (setq opoint  (point))
                     (let ((obj  (read (current-buffer))))
                       (and (symbolp obj)  (fboundp obj)
                            (progn (set-match-data (list opoint (point))) t))))
                 (error nil))
               (forward-sexp 1)
               (setq opoint  (point)
                     found   t))
              (t
               (if (looking-at "\\(\\sw\\|\\s_\\)")
                   (forward-sexp 1)
                 (forward-char 1)))))
      found)))

Note: If you want to see the effect of only this highlighting, then first do this in an Emacs-Lisp mode buffer, to get rid of other Emacs-Lisp font-lock highlighting:

M-: (setq font-lock-keywords  ()) RET

UPDATE ---

I created a minor-mode command and library for this:

It lets you highlight defined Emacs-Lisp symbols: functions and variables, only functions, or only variables. Alternatively you can highlight only symbols not known to be defined.

Drew
  • 29,895
  • 7
  • 74
  • 104
  • 2
    I may have misread the code, but can't the whole `condition-case` be replaced with a `(thing-at-point 'symbol)`? –  Aug 19 '13 at 14:38
  • Maybe, maybe not. ;-) See `function-called-at-point`, for instance. – Drew Aug 20 '13 at 03:48