Code Reloading
While Clojure’s and CIDER’s interactive programming style means you’ll restart your application far less often than with other languages and development environments, sometimes you’ll want to clean everything up and reload one or more namespaces to ensure that they are up to date and there are no temporary definitions hanging around.
"Reloaded" Workflow
The workflow described below was made popular by this blog article, which served as the primary inspiration for CIDER’s take on it. |
Typing C-c M-n r or C-c M-n M-r will invoke
cider-ns-refresh
and reload all modified Clojure files on the
classpath.
Adding a prefix argument, C-u C-c M-n r, will reload all the namespaces on the classpath unconditionally, regardless of their modification status.
Adding a double prefix argument, C-u C-u M-n r, will first clear the state of the namespace tracker before reloading. This is useful for recovering from some classes of error that normal reloads would otherwise not recover from. A good example is circular dependencies. The trade-off is that stale code from any deleted files may not be completely unloaded.
cider-ns-refresh
wraps
clojure.tools.namespace, and as
such the same
benefits
and
caveats
regarding writing reloadable code also apply.
The above three operations are analogous to
clojure.tools.namespace.repl/refresh
,
clojure.tools.namespace.repl/refresh-all
and
clojure.tools.namespace.repl/clear
(followed by a normal refresh), respectively.
Configuration
You can define Clojure functions to be called before reloading, and after a
successful reload, when using cider-ns-refresh
:
(setq cider-ns-refresh-before-fn "user/stop-system!"
cider-ns-refresh-after-fn "user/start-system!")
These must be set to the namespace-qualified names of vars bound to functions of no arguments. The functions must be synchronous (blocking), and are expected to be side-effecting - they will always be executed serially, without retries.
By default, messages regarding the status of the in-progress reload
will be displayed in the echo area after you call
cider-ns-refresh
. The same information will also be recorded in the
*cider-ns-refresh-log*
buffer, along with anything printed to
*out*
or *err*
by cider-ns-refresh-before-fn
and
cider-ns-refresh-start-fn
.
You can make the *cider-ns-refresh-log*
buffer display automatically
after you call cider-ns-refresh
by setting the
cider-ns-refresh-show-log-buffer
variable to a non-nil value. This
will also prevent any related messages from also being displayed in
the echo area.
(setq cider-ns-refresh-show-log-buffer t)
By default, CIDER will prompt for whether to save all modified clojure-mode
buffers visiting files on the classpath. You can customize this behavior with
cider-ns-save-files-on-refresh
and cider-ns-save-files-on-refresh-modes
.
Using clj-reload
Support for clj-reload was introduced in CIDER 1.14.
|
You can also use cider-ns-refresh
with clj-reload instead of clojure.tools.namespace
.
It provides support for
keeping vars between reloads
among some
other differences
from tools.namespace
.
(setq cider-ns-code-reload-tool 'clj-reload)
With clj-reload
you should set the source dirs as described in
the usage docs
. If you don’t set them manually, it will default to the current project’s resource dirs in the same
way tools.namespace
does.
Down the road we may rename cider-ns-refresh to something more tool-agnostic (e.g. cider-ns-smart-reload ) to reflect
that it supports different code reload tools now.
|
Basic Code Reloading
Sometimes, cider-ns-refresh
may not work for you. If you’re looking
for a bit more forceful reloading the cider-ns-reload
(C-c M-n l)
and cider-ns-reload-all
(C-c M-n M-l) commands can be used instead. These commands
invoke Clojure’s (require ... :reload)
and (require
... :reload-all)
commands at the REPL.
These commands don’t depend on cider-nrepl , so they are always available.
|
Keybindings
Command | Keyboard shortcut | Description |
---|---|---|
|
C-c M-n r |
Reload all modified Clojure files on the classpath. Adding a prefix argument, C-u C-c M-n r, will reload all the namespaces on the classpath unconditionally, regardless of their modification status. Adding a double prefix argument, C-u C-u M-n r, will first clear the state of the namespace tracker before reloading. |
|
C-c M-n l |
Reload using |
|
C-c M-n M-l |
Reload using |