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:
electric-pair-mode to keep your code syntactically
correct while you edit it. See Matching Parentheses.
elisp-scope-safe-macro-p for more
information about which macros Emacs considers safe to expand for
analysis. The user option elisp-scope-safe-macros controls which
macros are safe to expand during analysis in untrusted buffers.