Update: more up-to-date version of this article is this link: Small rainbow-delimiters tutorial | Yoo Box
1. Introduction to Rainbow Delimiters
Rainbow delimiters mode highlights lisp parentheses of different nesting depth in different colors in Emacs. The Github link and the EmacsWiki link have setup instructions. It also highlights other nesting delimiters like square brackets (for Emacs Lisp and Clojure) and curly brackets (for Clojure).
If every time you type a paren, other parens (below the current line) get recolored, that probably means that you are not using paredit or autopair that automatically inserts close parens for you.
2. customizations from the customize interface
M-x customize-group RET rainbow-delimiters RET
It provides user options for turning off highlighting of some delimiters and you can also customize the faces used by the package.
3. other customizations
3.1. bold for the outermost parens and then gray all the way
You might want to have just the outermost parens display in bold, and have all other parens display in gray color. The following code will do the job. You can also customize the two faces defined in the code if you want.
(defface my-outermost-paren-face '((t (:weight bold))) "Face used for outermost parens.") (defface my-inner-paren-face ;; face definition I got from esk-paren-face of starter-kit-lisp '((((class color) (background dark)) (:foreground "grey50")) (((class color) (background light)) (:foreground "grey55"))) "Face used to dim inner parentheses.") (require 'cl-lib) (cl-loop for index from 1 to rainbow-delimiters-max-face-count do (let ((face (intern (format "rainbow-delimiters-depth-%d-face" index)))) (set-face-attribute face nil :foreground 'unspecified :inherit (if (= index 1) 'my-outermost-paren-face 'my-inner-paren-face))))
3.2. using stronger colors
You might want to use colors stronger than default. By strong, I mean more saturated, i.e., less gray. Use this code:
(require 'cl-lib) (require 'color) (cl-loop for index from 1 to rainbow-delimiters-max-face-count do (let ((face (intern (format "rainbow-delimiters-depth-%d-face" index)))) (cl-callf color-saturate-name (face-foreground face) 30)))
3.3. making unmatched parens stand out more
Unmatched close parens are highlighted in a color that stands out by default. But if you customize rainbow delimiters to use strong colors, you have to customize the face for unmatched parens too so that they stand out again among all those colorful parens.
This code will make unmatched parens display in bold red and with a strike through.
(set-face-attribute 'rainbow-delimiters-unmatched-face nil :foreground 'unspecified :inherit 'error :strike-through t)
This code will make them display in violet background.
(require 'paren) ; show-paren-mismatch is defined in paren.el (set-face-attribute 'rainbow-delimiters-unmatched-face nil :foreground 'unspecified :inherit 'show-paren-mismatch)
3.4. alternating dual color
Following code is for alternating between just two colors.
(require 'cl-lib) (defvar my-paren-dual-colors '("hot pink" "dodger blue")) (cl-loop for index from 1 to rainbow-delimiters-max-face-count do (set-face-foreground (intern (format "rainbow-delimiters-depth-%d-face" index)) (elt my-paren-dual-colors (if (cl-evenp index) 0 1))))
The idea is to maximize eye detection of off-by-one paren depth difference especially in code that uses one space indent convention such as cond forms. One doesn’t usually rely on colored parens to read Lisp code. He just relies on indentation to see the structure of code in most cases. Colored parens are helpful in a few cases such as some defface or let or cond forms where some lines are dense or where one space indent convention is used while the form is vertically spread out. See examples in appendix.
3.5. other dual color combinations
'("deep pink" "royal blue")
blending more into white background:
'("pink" "sky blue")
3.6. bold outermost parens
(set-face-attribute 'rainbow-delimiters-depth-1-face nil :weight 'bold)
4.1. what happens at deeper depth?
The package provides faces for depth 1 to depth 9. For deeper depth, it cycles through the faces repeatedly. It seems that whether it should cycle just from depths 2 to 9 (excluding the face for depth 1) is not set in stone yet. The customization for singling out outermost parens and the customization for dual color are somewhat buggy customizations if 1 is included in the cycle, which is the case as of now.
4.2. export to html
5.1. examples of forms where colored parens help seeing structure
These examples are simplistic for demonstration purposes. For each example, imagine a bigger example.
(when t ;; example where arguments of mapcar are ;; indented with just one space (blah blah) (mapcar (lambda (x y) (blah blah) (blah blah)) (list 1 2)) (blah blah) ;; example: let form (let ((a 1) (b (+ 1 1)) (c 3)) (blah blah blah) (blah (+ 1 1) blah) (blah)) ;; example: let form 2 ;; with a line that is about to grow dense (let ((a 1) (b (+ 1 1)) (c 3)) ; <-- (blah blah blah) (blah (+ 1 1) blah) (blah)) ;; example: cond form ;; one space indent (between (1) and (2)) (cond ((blih 1 x) (blah (+ 1 1) blah) (blah blah ; <--(1) blah)) ((blih x ; <--(2) (+ blah blah)) (blah blah)) (t (blah))) ;; example: cond form 2 ;; with one space indent (between (1), (2), (3)) (cond ((blih 1 x) (blah (+ 1 1) blah) (blah blah ;<--(1) blah)) ((blih x ;<--(2) (+ blah blah)) (blah blah))) (blah blah ;<--(3) blah) (blah) t)