prism disperses lisp forms (and other languages) into a spectrum of color by depth. It’s similar to
rainbow-blocks, but it respects existing non-color face properties, and allows flexible configuration of faces and colors. It also optionally colorizes strings and/or comments by code depth in a similar, customizable way.
Lisp and C-like languages
One of the benefits of
prism is making it easy to see which list elements are in. For example, in this excerpt from
funcall’s first argument is an unusually indented
if form, and the indentation nearly aligns the
funcall’s second argument,
date, at the column where the
if’s else clause would usually be. But with depth-based colorization, it’s easy to see that
1 are arguments to
funcall, not part of the
It’s also easy to distinguish the
diary-list-entries-hook variable’s value form from other variables, and the
entries variable’s different color clearly shows that it has no value form.
It is also useful for non-Lisp languages. For example, here’s an example of JSON in
Here’s an Emacs C function:
Into this (using theme
doom-outrun-electric). Note how the
bind is the same color as the
function keyword and braces that it corresponds to:
For whitespace-sensitive languages,
prism-whitespace-mode determines depth by a combination of indentation and list nesting. For example, Python (showing theme
doom-vibrant with these faces set in variable
This example shows Python with
prism-comments enabled (showing theme
It even works in Haskell (showing theme
It’s easy to adjust the colors with
prism-set-colors. Here are some examples.
You can use just a few faces in combination with the
lightens to create a palette of colors:
Or even a single color, going in one direction:
…or the other:
The default configuration looks decent in the default Emacs theme:
If you use Doom themes, you can use
doom-color to get colors from the theme:
But some of them look nice without any customization, like
If you use solarized-theme, you can use
solarized-with-color-variables to get colors from the theme:
And you can adjust the palette extensively by changing the applied desaturation and lightening:
You can shuffle the order of the colors until you find a pattern you like:
prism is much like rainbow-blocks, but it differs in a few ways:
prismoptionally colorizes comments and strings according to the depth of their surrounding code.
prismhighlights parens with the color of the outer list’s symbols, which helps parens stand out from symbols and shows which depth surrounds a list.
prismadds to the
facetext property, which respects existing fontification, while
font-lock-facetext property, which overrides existing fontification. This means that
prismis compatible with packages like highlight-function-calls and highlight-quoted.
jit-lock-register. Which is better? Good question. Hopefully, the former…
The easiest way is to use quelpa-use-package like this:
(use-package prism :quelpa (prism :fetcher github :repo "alphapapa/prism.el"))
- Run the appropriate command for the current buffer:
- For Lisp and C-like languages, use
- For significant-whitespace languages like Python, or ones whose depth is not always indicated by parenthetical characters, like shell, use
- For Lisp and C-like languages, use
When a theme is loaded or disabled, colors are automatically updated.
To customize, see the
prism customization group, e.g. by using M-x customize-group RET prism RET. For example, by default, comments and strings are colorized according to depth, similarly to code, but this can be disabled.
More advanced customization of faces is done by calling
prism-set-colors, which can override the default settings and perform additional color manipulations. The primary argument is
COLORS, which should be a list of colors, each of which may be a name, a hex RGB string, or a face name (of which the foreground color is used). Note that the list of colors need not be as long as the number of faces that’s actually set (e.g. the default is 16 faces), because the colors are automatically repeated and adjusted as necessary.
prism-set-colors is called with the
SAVE argument, the results are saved to customization options so that
prism-mode will use those colors by default.
Here’s an example that the author finds pleasant (seen in the first screenshot):
(prism-set-colors :num 16 :desaturations (cl-loop for i from 0 below 16 collect (* i 2.5)) :lightens (cl-loop for i from 0 below 16 collect (* i 2.5)) :colors (list "dodgerblue" "medium sea green" "sandy brown") :comments-fn (lambda (color) (prism-blend color (face-attribute 'font-lock-comment-face :foreground) 0.25)) :strings-fn (lambda (color) (prism-blend color "white" 0.5)))
Early prototype stages.
Bug reports, feature requests, suggestions — oh my!
In the event that a bug in the font-locking functions cause Emacs to enter an infinite loop, you can stop it without killing Emacs by following these steps:
- From a shell, run
pkill -SIGUSR2 emacs. Usually once is enough, but not always.
- After Emacs displays a backtrace, switch to the buffer where
prism-modewas enabled and call
prism-modeagain to disable it.
- Please report the backtrace to the issue tracker so it can be fixed. Include contents of the buffer when possible.