GitHub - alphapapa/prism.el: Disperse Lisp forms (and other languages) into a sp...
source link: https://github.com/alphapapa/prism.el
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
README.org
prism.el
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.
Contents
Screenshots
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 org-get-entries-from-diary
from org-agenda.el
, the 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 date
and 1
are arguments to funcall
, not part of the if
form.
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 prism-mode
:
Here’s an Emacs C function:
It might even help save you from deeply nested, callback-style JavaScript, turning this:
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:
Whitespace-sensitive languages
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 prism-colors
: font-lock-type-face
, font-lock-function-name-face
, font-lock-constant-face
, and font-lock-keyword-face
):
This example shows Python with prism-comments
enabled (showing theme doom-challenger-deep
):
It even works in Haskell (showing theme doom-molokai
):
Customizable colors
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 desaturations
and 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 doom-gruvbox
:
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:
Buffer-local themes
You can even set themes buffer-locally (the theme-choosing command shown here is not included, but you can easily define your own “chooser” command using unpackaged/define-chooser):
Comparisons
prism
is much like rainbow-blocks, but it differs in a few ways:
prism
optionally colorizes comments and strings according to the depth of their surrounding code.prism
highlights parens with the color of the outer list’s symbols, which helps parens stand out from symbols and shows which depth surrounds a list.prism
adds to theface
text property, which respects existing fontification, whilerainbow-blocks
sets thefont-lock-face
text property, which overrides existing fontification. This means thatprism
is compatible with packages like highlight-function-calls and highlight-quoted.prism
usesfont-lock-add-keywords
, whilerainbow-blocks
usesjit-lock-register
. Which is better? Good question. Hopefully, the former…
Installation
The easiest way is to use quelpa-use-package like this:
(use-package prism :quelpa (prism :fetcher github :repo "alphapapa/prism.el"))
Usage
- Run the appropriate command for the current buffer:
- For Lisp and C-like languages, use
prism-mode
. - For significant-whitespace languages like Python, or ones whose depth is not always indicated by parenthetical characters, like shell, use
prism-whitespace-mode
instead.
- For Lisp and C-like languages, use
- Enjoy.
- If the colors aren’t satisfactory, use command
prism-randomize-colors
to randomize theprism
colors according to the current Emacs theme. When you find a set you like, you may save the colors with commandprism-save-colors
. - When a theme is loaded or disabled, and
prism-colors
is a list of faces (rather than a list of colors),prism-colors
is automatically updated. Ifprism-colors
is a list of colors, callprism-set-colors
orprism-randomize-colors
manually to update for a new theme. - 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.
Advanced
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.
Faces may be remapped buffer-locally by setting the LOCAL
argument to t
(interactively, with one universal prefix); if set to reset
(interactively, with two prefixes), local remappings are cleared.
If 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)))
Changelog
0.2
Added
- Command
prism-randomize-colors
, which setsfaces
based on a random, shuffled selection offont-lock
faces in the current Emacs theme.
Fixed
- Performance issues with large Lisp forms.
0.1
First tagged version. Possibly a few sneaky bugs lurking, but seems to work well.
Credits
Inspired by rainbow-blocks, rainbow-identifiers, and rainbow-delimiters.
Development
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-mode
was enabled and callprism-mode
again to disable it. - Please report the backtrace to the issue tracker so it can be fixed. Include contents of the buffer when possible.
License
GPLv3
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK