88This package provides basic interaction with a Clojure subprocess (REPL).
99It's based on ideas from the popular ` inferior-lisp ` package.
1010
11- ` inf-clojure ` has two components - a nice Clojure REPL with
12- auto-completion and a minor mode (` inf-clojure-minor-mode ` ), which
13- extends ` clojure-mode ` with commands to evaluate forms directly in the
14- REPL.
11+ ` inf-clojure ` aims to expose the extensive self-documenting features
12+ of Clojure repls into an emacs package. Inf-clojure does not require
13+ middleware or special tooling. Inf-clojure supports the following
14+ repls:
15+
16+ - Clojure
17+ - ClojureScript
18+ - planck
19+ - lumo
20+ - joker
21+ - babashka
22+
23+ ` inf-clojure ` has two components - a nice REPL buffer (` inf-clojure ` )
24+ (` inf-clojure-minor-mode ` ), which extends ` clojure-mode ` with commands
25+ to evaluate forms directly in the REPL.
1526
1627` inf-clojure ` provides a set of essential features for interactive
1728Clojure(Script) development:
@@ -83,7 +94,7 @@ Add the following to your Emacs config to enable
8394have overlapping functionality and keybindings and the result will be nothing
8495short of havoc.**
8596
86- ## Usage
97+ ## Basic Usage
8798
8899Just invoke ` M-x inf-clojure ` or press ` C-c C-z ` within a Clojure
89100source file. You should get a prompt with the supported repl types and
@@ -94,10 +105,6 @@ and you can start interacting with it.
94105If you've already started a socket repl, use ` M-x inf-clojure-connect `
95106and enter the host and port numbers.
96107
97- It is highly recommended to use a cons pair like ` ("localhost" . 5555) ` to
98- connect to a socket REPL, terminal REPLs are inherently hard to work with and
99- support will be deprecated in the foreseeable future.
100-
101108Inf-clojure aims to be very simple and offer tooling that the repl
102109itself exposes. A few commands are:
103110
@@ -107,11 +114,77 @@ itself exposes. A few commands are:
107114- show source ` C-c C-s `
108115- insert top level form into repl ` C-c C-j d `
109116
117+ For a list of all available commands in ` inf-clojure-mode ` (a.k.a. the
118+ REPL) and ` inf-clojure-minor-mode ` you can either invoke `C-h f RET
119+ inf-clojure-mode` and ` C-h f RET inf-clojure-minor-mode` or simply
120+ browse their menus.
121+
110122Many ` inf-clojure-minor-mode ` commands by default act on the symbol at
111123point. You can, however, change this behaviour by invoking such
112124commands with a prefix argument. For instance: ` C-u C-c C-v ` will ask
113125for the symbol you want to show the docstring for.
114126
127+ ## Configuration options
128+
129+ In the time-honoured Emacs tradition ` inf-clojure ` 's behaviour is extremely
130+ configurable.
131+
132+ You can set custom values to ` inf-clojure ` variables on a
133+ per-project basis using [ directory
134+ variables] ( https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html )
135+ or by setting them in in your init file.
136+
137+ You can see all the configuration options available using the command
138+ ` M-x customize-group RET inf-clojure ` .
139+
140+ The supported repl-features are in an alist called
141+ ` inc-clojure-repl-features ` and it has the following shape:
142+
143+ ``` emacs-lisp
144+ '((cljs . ((doc . "(cljs.repl/doc %s)")
145+ (source . "(cljs.repl/source %s)")
146+ (arglists . "(try (->> '%s cljs.core/resolve cljs.core/meta :arglists) (catch :default _ nil))")
147+ (apropos . "(cljs.repl/apropos \"%s\")")
148+ (ns-vars . "(cljs.repl/dir %s)")
149+ (set-ns . "(in-ns '%s)")
150+ (macroexpand . "(cljs.core/macroexpand '%s)")
151+ (macroexpand-1 . "(cljs.core/macroexpand-1 '%s)"))))
152+ ```
153+
154+ If you want to add a new repl type, just `(add-to-list
155+ 'inf-clojure-repl-features (cons new-repl-type '((doc
156+ . "(myrepl/doc-command %s") ...)))` since the datastructure is just an
157+ alist of alists.
158+
159+ If you want to update a specific form there is a function
160+ ` inf-clojure-update-repl-feature ` which can be used like so:
161+
162+ ``` emacs-lisp
163+ (inf-clojure-update-feature 'clojure 'completion "(complete.core/completions \"%s\")")
164+ ```
165+
166+ #### Caveats
167+
168+ It is highly recommended to use a cons pair like ` ("localhost" . 5555) ` to
169+ connect to a socket REPL, terminal REPLs are inherently hard to work with and
170+ support will be deprecated in the foreseeable future. If you use the
171+ same project often, make a dir-locals file with this information in ` inf-clojure-custom-startup ` .
172+
173+ Note that if you decide _ NOT_ to use the socket repl, it is highly recommended
174+ you disable output coloring and/or readline facilities: ` inf-clojure ` does not
175+ filter out ASCII escape characters at the moment and will not behave correctly.
176+
177+ For leiningen, there are no command line switches and you need to add
178+ a custom [ ` project.clj `
179+ option] ( https://github.com/technomancy/leiningen/blob/master/sample.project.clj ) :
180+
181+ ``` clojure
182+ ...
183+ :repl-options {:color false }
184+ ...
185+ ```
186+
187+
115188#### Clojure Command Line Socket REPL
116189
117190If you have the new [ Clojure CLI tools] [ ] installed you can use the ` clojure ` command:
@@ -125,15 +198,8 @@ clojure -J-Dclojure.server.repl="{:port 5555 :accept clojure.core.server/repl}"
125198Then either ` C-c M-c RET localhost RET 5555 ` from within Emacs or add the following to your ` .dir-locals.el ` :
126199
127200``` emacs-lisp
128- ((nil . ((inf-clojure-tools-deps-cmd . ("localhost" . 5555)))))
201+ ((nil . ((inf-clojure-custom-startup . ("localhost" . 5555)))))
129202```
130-
131- or the following to your [ Emacs init file] [ ] :
132-
133- ``` emacs-lisp
134- (setf inf-clojure-tools-deps-cmd '("localhost" . 5555)):
135- ```
136-
137203#### Leiningen Socket REPL
138204
139205For Leiningen, add the following option to your ` ~/.lein/profiles.clj ` or your ` project.clj ` :
@@ -160,43 +226,6 @@ For example if a `project.clj` is present in the project root folder, `inf-cloju
160226
161227After you launch ` lumo ... -n 5555 ` , as customary, either ` C-c M-c RET localhost RET 5555 ` from within Emacs or add the following to your ` .dir-locals.el ` :
162228
163- ``` emacs-lisp
164- ((nil . ((inf-clojure-lein-cmd . ("localhost" . 5555)))))
165- ```
166-
167- or the following to your [ Emacs init file] [ ] :
168-
169- ``` emacs-lisp
170- (setf inf-clojure-lein-cmd '("localhost" . 5555))
171- ```
172-
173- Project detection can be completely skipped and the ` generic ` project type can be used instead:
174-
175- ``` emacs-lisp
176- (setf inf-clojure-project-type . "generic")
177- (setf inf-clojure-generic-cmd '("localhost" 5555))
178- ```
179-
180- #### Caveats
181-
182- Note that if you decide _ NOT_ to use the socket repl, it is highly recommended
183- you disable output coloring and/or readline facilities: ` inf-clojure ` does not
184- filter out ASCII escape characters at the moment and will not behave correctly.
185-
186- You can disable coloring the following way for ` boot ` :
187-
188- ``` emacs-lisp
189- ((nil . ((inf-clojure-boot-cmd . "boot repl -C"))))
190- ```
191-
192- For leiningen, there are no command line switches and you need to add a custom [ ` project.clj ` option] ( https://github.com/technomancy/leiningen/blob/master/sample.project.clj ) :
193-
194- ``` clojure
195- ...
196- :repl-options {:color false }
197- ...
198- ```
199-
200229#### Multiple Process Support
201230
202231To run multiple Clojure processes, you start the first up
@@ -235,46 +264,11 @@ one process, this does the right thing. If you run multiple
235264processes, you might need to change ` inf-clojure-buffer ` to
236265whichever process buffer you want to use.
237266
238- ## Configuration options
239-
240- In the time-honoured Emacs tradition ` inf-clojure ` 's behaviour is extremely
241- configurable.
242-
243- You can see all the configuration options available using the command
244- ` M-x customize-group RET inf-clojure ` .
245-
246- The supported repl-features are in an alist called
247- ` inc-clojure-repl-features ` and it has the following shape:
248-
249- ``` emacs-lisp
250- '((cljs . ((doc . "(cljs.repl/doc %s)")
251- (source . "(cljs.repl/source %s)")
252- (arglists . "(try (->> '%s cljs.core/resolve cljs.core/meta :arglists) (catch :default _ nil))")
253- (apropos . "(cljs.repl/apropos \"%s\")")
254- (ns-vars . "(cljs.repl/dir %s)")
255- (set-ns . "(in-ns '%s)")
256- (macroexpand . "(cljs.core/macroexpand '%s)")
257- (macroexpand-1 . "(cljs.core/macroexpand-1 '%s)"))))
258- ```
259-
260- If you want to add a new repl type, just `(add-to-list
261- 'inf-clojure-repl-features (cons new-repl-type '((doc
262- . "(myrepl/doc-command %s") ...)))`
263-
264- If you want to update a specific form there is a function
265- ` inf-clojure-update-repl-feature ` which can be used like so:
266-
267- ``` emacs-lisp
268- (inf-clojure-update-feature 'clojure 'completion "(complete.core/completions \"%s\")")
269- ```
270-
271267#### REPL Type
272268
273- An ` inf-clojure ` REPL can be of different types: Clojure,
274- ClojureScript, Lumo and Planck are all potentially valid options.
275-
276- At the moment, the default Clojure REPL, the Lumo REPL, the Planck
277- REPL and the Joker REPL are supported.
269+ An ` inf-clojure ` REPL has an associated type. The available types are
270+ `(mapcar 'car inf-clojure-repl-features) ->> (cljs lumo planck joker
271+ clojure babashka)`
278272
279273What does it mean that a REPL type is supported - well it means that
280274` inf-clojure ` would use the proper code internally to power commands
@@ -284,15 +278,6 @@ and can't be implemented in a REPL-independent way. At startup
284278and uses this type to dispatch the proper code for the respective REPL
285279type.
286280
287- By default ` inf-clojure ` would start a standard Clojure REPL using
288- ` lein ` or ` boot ` but you can easily change this. To boot some other REPL just use the
289- right launch command (or connect to the REPL via a socket). For example, for
290- Lumo just add the following in your ` .dir-locals.el ` :
291-
292- ``` emacs-lisp
293- ((nil . ((inf-clojure-boot-cmd . "lumo -d")))) ;; inf-clojure-lein-cmd if you are using Leiningen
294- ```
295-
296281#### ElDoc
297282
298283` eldoc-mode ` is supported in Clojure source buffers and ` *inferior-clojure* `
@@ -315,31 +300,61 @@ You can leave it enabled, it just won't show anything in the echo area.
315300
316301#### Code Completion
317302
318- Code completion is particularly open to customization. Not only you can ` setq `
319- the customary ` inf-clojure-completion-form ` ,
320- ` inf-clojure-completion-form-lumo ` , ` inf-clojure-completion-form-planck ` and
321- ` inf-clojure-completion-form-joker ` - the form to send to the REPL - but you
322- can also use ` inf-clojure-completions-fn ` for specifying a function that given
323- the REPL response should return elisp data compatible with
303+ Code completion is a tricky aspect if you are trying to be as close to
304+ a generic repl as possible. Planck and lumo repl implementations
305+ explicitly provide completion functions in their repl namespaces. For
306+ clojure, you will need to have a library on your classpath. If you are
307+ using lein, you already have
308+ [ clojure-complete] ( https://github.com/ninjudd/clojure-complete ) . You
309+ could alternatively use ` compliment {:mvn/version "0.3.10"} ` .
310+
311+ ``` emacs-lisp
312+ ;; for clojure-complete
313+ (inf-clojure-update-feature 'clojure 'completion "(complete.core/completions \"%s\")")
314+
315+ ;; or
316+ ;; for compliment
317+ (inf-clojure-update-feature 'clojure 'completion "(compliment.core/completions \"%s\")")
318+
319+ ```
320+
321+ If you give a form for the completion form, it is your responsibility
322+ to ensure that this namespace is on the classpath and required. If
323+ using lein, this is done for you with clojure-complete. If adding
324+ compliment, the following sample deps.edn can conveniently add the dep
325+ to your program.
326+
327+ Sample deps.edn:
328+
329+ ``` clojure
330+ {:aliases {:compliment {:extra-deps {compliment {:mvn/version " 0.3.10" }}}}}
331+ ```
332+
333+
334+ Use the startup command: ` clojure -A:compliment ` . Then require the ns
335+ once so that the completion machinery will work: `(require
336+ 'compliment.core)`. Now tab completion should work.
337+
338+ For more advanced customization, code completion is particularly open
339+ to customization. Not only you can ` setq ` the customary
340+ ` inf-clojure-completion-form ` , ` inf-clojure-completion-form-lumo ` ,
341+ ` inf-clojure-completion-form-planck ` and
342+ ` inf-clojure-completion-form-joker ` - the form to send to the REPL -
343+ but you can also use ` inf-clojure-completions-fn ` for specifying a
344+ function that given the REPL response should return elisp data
345+ compatible with
324346[ ` completion-at-point-functions ` ] ( https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion-in-Buffers.html ) .
325- For more info run ` M-x describe-variable RET inf-clojure-completions-fn ` .
326- Another option is to have a look at
327- [ how cider does it] ( https://github.com/clojure-emacs/cider/blob/3e9ed12e8cfbad04d7618e649322765dc9bff5d6/cider-interaction.el#L595 ) .
347+ For more info run `M-x describe-variable RET
348+ inf-clojure-completions-fn`. Another option is to have a look at [ how
349+ cider does
350+ it] ( https://github.com/clojure-emacs/cider/blob/3e9ed12e8cfbad04d7618e649322765dc9bff5d6/cider-interaction.el#L595 ) .
328351
329352#### Lumo Setup
330353
331354For an optimal Lumo experience the ` -d ` needs to be passed to Lumo
332355when launched from the command line. This disable ` readline ` support
333356in order to play nicely with emacs.
334357
335- For example, you can use the following command (assuming ` cp ` contains
336- the classpath) in your ` .dir-locals.el ` :
337-
338- ``` emacs-lisp
339- ((nil . (eval . (setq inf-clojure-generic-cmd (concat "lumo -d -c "
340- (f-read (concat (inf-clojure-project-root) "cp")))))))
341- ```
342-
343358## Troubleshooting
344359
345360### Things seem broken
0 commit comments