16.13.3 Semantic Font Lock

Semantic highlighting is feature in which an editor uses some kind of semantic analysis to understand a program’s source code, and communicates useful information about the meaning of different tokens to the user by highlighting these tokens according to their specific role in the program.

Semantic highlighting is more sophisticated than traditional “syntax highlighting”, which only considers the syntactic role of a token, i.e., how it affects the code’s parsing, unlike semantic analysis which takes into account the token’s effect on the program’s execution. For example, a semantic highlighting implementation may be able to tell apart local and global variables and give distinct highlighting to each category, even though the language’s syntax doesn’t make such a distinction. Semantic highlighting is especially beneficial in languages in which syntactic constructs can mean completely different things depending on the context in which they occur, such as Lisp and Prolog. In such languages, syntactic analysis alone misses a lot of important information that coders need to reason about their programs.

Some language servers provide semantic highlighting information, which Emacs can leverage via its LSP client, Eglot. See Eglot Features in Eglot: The Emacs LSP Client.

Additionally, Emacs implements semantic highlighting for Emacs Lisp as an optional feature of emacs-lisp-mode (see Executing Lisp Expressions). To enable it, customize the option elisp-fontify-semantically to a non-nil value. The rest of this subsection describes the use of this Emacs Lisp-specific semantic highlighting support.

When elisp-fontify-semantically is enabled, emacs-lisp-mode analyzes your code and highlights symbols according to their semantic roles, as part of the mode’s usual Font Lock highlighting (see Font Lock mode). It doesn’t affect the highlighting of strings, comments and other syntactic elements such as brackets; elisp-fontify-semantically only affects highlighting of symbols.

The semantic analysis assigns to each symbol a symbol role, such as “function”, “local variable”, “face name”, etc. Each symbol role has an associated face property, which is applied to symbols with that role during semantic highlighting. By default, most of these faces inherit from appropriate font-lock-* faces. For example, locally-bound variables get the elisp-bound-variable face, which inherits from font-lock-variable-use-face.

The semantic analysis can differentiate between more than 50 such symbol roles, but you don’t need to memorize the appearance of so many faces to leverage semantic highlighting: you can hover over an highlighted symbol with the mouse to see a tooltip with the exact role Emacs inferred for that symbol (see Tooltips). If you want to disable this extra information, customize elisp-add-help-echo to the nil value.

There are a few more points you should keep in mind when using elisp-fontify-semantically: