How to highlight all the function's name in Emacs' lisp-mode?
Asked Answered
E

2

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

Elegist answered 17/8, 2013 at 13:25 Comment(0)
K
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:)?

Kingery answered 17/8, 2013 at 13:35 Comment(4)
Thanks! Now I understand that \\(...\\) is the point. But I want to know what is that "1" meaning?Elegist
1 means the first captured group, 2 would mean the second captured group, if there was one. 0 means the whole matchKingery
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.Professionalism
This will not override already highlighted text: (font-lock-add-keywords 'lisp-mode '(("(\\s-*\\(\\_<\\(?:\\sw\\|\\s_\\)+\\)\\_>" 1 'font-lock-func-face keep)) t)Rattlehead
F
7

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.

Fatherinlaw answered 17/8, 2013 at 20:33 Comment(2)
I may have misread the code, but can't the whole condition-case be replaced with a (thing-at-point 'symbol)?Professionalism
Maybe, maybe not. ;-) See function-called-at-point, for instance.Fatherinlaw

© 2022 - 2024 — McMap. All rights reserved.