Skip to content

Rich Comments Support

Why bother with Rich comments? Read on. Consider watching this Youtube video for a demo of the workflow using the (in?)famous FizzBuzz problem as an example.

Things in comment are not evaluated

The Clojure comment macro is defined like so:

(defmacro comment
  "Ignores body, yields nil"
  {:added "1.0"}
  [& body])

It has no forms in its body and will therefore always (as long as the Clojure Reader can read it) evaluate to nil. That is: nothing in the (comment ...) form will get evaluated when the file is loaded.

This makes it a very good ”place” where you can develop code, experiment with code, and keep example code. Since you will be able to load/evaluate the current file without worrying that the code in the comment form will get evaluated. This also holds true when using tools that hot-reload the code on save, such as Figwheel, shadow-cljs and Krell.

To develop or refine a function you might:

  1. Open up a (comment ...) form
  2. Inside this form, type a first, super simple, version (or refinement) of your function and evaluate it
  3. Inside the same comment form, type some code to test your function and evaluate that
    • Or type and evaluate some code you might need for your function
  4. Repeat from 2., until the function does what you want it to do
  5. Move the function definition out of the comment form
  6. Clean up the comment form to keep some of the test code as example use, or ”design decision log” for the function.

Note

Using (comment ...) forms for developing code is very common among Clojure coders. Rich Hickey is known for using it, which is why they are called Rich comments to begin with (even if it also is a very rich experience).

Calva encourages Rich comments

Calva has several features to facilitate the Rich comments workflow, e.g.

  1. A command that helps you create a new Rich comment form quickly: Calva: Add Rich Comment, ctrl+alt+r c
  2. Special Syntax highlight. By default comment forms are rendered in italics
  3. Special top-level form context
  4. Special formatting

comment is top-level

To make it easy to evaluate forms in (comment ...) forms, they create a new top-level context. Instead of you having to place the cursor with precision before evaluating the current form, you can have the cursor anywhere within a comment enclosed form and Evaluate Top-Level Form.

This carries over to all commands in Calva which deal with the top level form. Including custom command snippets.

Special formatting

To invite a Rich comments workflow, the Calva command Format Current Form will not fold the closing bracket of the (comment ...) form. Instead it will place this bracket on a line of its own (or keep it there).

(comment
  )

With the cursor somewhere directly inside the comment form (denoted with a |):

(comment
  (def foo
:foo)|)

tab

(comment
  (def foo
    :foo)
  |)

Thinking space is kept

The formatter will not remove newlines between the cursor and the closing bracket. So if you have entered a few lines to get ”thinking” room:

(comment
  (def foo
:foo)

|

)

tab

(comment
  (def foo
    :foo)

  |

  )

Fold when done

To fold the trailing paren automatically, place the cursor immediately outside (before or after) the form:

(comment
  (def foo
:foo))|

tab

(comment
  (def foo
    :foo))|

Enabled by default

You can disable this behavior with the setting: calva.fmt.keepCommentTrailParenOnOwnLine.

But why would you? It is awesome! 😄

Only for the Current Form

Note

This treatment only applies to formatting of the current form. With fold when done as an exception.