-
Notifications
You must be signed in to change notification settings - Fork 0
Emacs
Although you can use any editor you like to edit the ClojureScript One files, the authors (and many Clojure programmers) use emacs. On this page we document some of the things you can do to improve your experience working with ClojureScript One in emacs.
By default, ClojureScript files are not associated with clojure-mode
in emacs. Put the following lines into your .emacs
or
.emacs.d/init.el
file:
(add-to-list 'auto-mode-alist '("\\.cljs$" . clojure-mode))
Working with ClojureScript One differs from working in Clojure in that you are often simultaneously working with two different REPLs: a ClojureScript REPL where you want to evaluate commands in the browser, and a Clojure REPL where you want to evaluate commands against the server portion of the application. A trick that we've used to pull this off is to run the one of them in an inferior lisp buffer, and the other in shell-mode. We define commands and keys for sending expressions to the shell buffer and use the existing commands to send expressions to the inferior lisp buffer. It's a bit of a hack, but an occasionally handy one.
To make it work, put the following into your .emacs
or
.emacs.d/init.el
file:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Allow input to be sent to somewhere other than inferior-lisp
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; This is a total hack: we're hardcoding the name of the shell buffer
(defun shell-send-input (input)
"Send INPUT into the *shell* buffer and leave it visible."
(save-selected-window
(switch-to-buffer-other-window "*shell*")
(goto-char (point-max))
(insert input)
(comint-send-input)))
(defun defun-at-point ()
"Return the text of the defun at point."
(apply #'buffer-substring-no-properties
(region-for-defun-at-point)))
(defun region-for-defun-at-point ()
"Return the start and end position of defun at point."
(save-excursion
(save-match-data
(end-of-defun)
(let ((end (point)))
(beginning-of-defun)
(list (point) end)))))
(defun expression-preceding-point ()
"Return the expression preceding point as a string."
(buffer-substring-no-properties
(save-excursion (backward-sexp) (point))
(point)))
(defun shell-eval-last-expression ()
"Send the expression preceding point to the *shell* buffer."
(interactive)
(shell-send-input (expression-preceding-point)))
(defun shell-eval-defun ()
"Send the current toplevel expression to the *shell* buffer."
(interactive)
(shell-send-input (defun-at-point)))
(add-hook 'clojure-mode-hook
'(lambda ()
(define-key clojure-mode-map (kbd "C-c e") 'shell-eval-last-expression)
(define-key clojure-mode-map (kbd "C-c x") 'shell-eval-defun)))
Once there, you can eval this code by selecting it and typing M-x eval-region
. Any open Clojure files will need to be reopened for
these changes to take effect.
For this example, we will start the Clojure REPL in the shell mode buffer and the ClojureScript REPL in the inferior lisp buffer. You can reverse these if it suits your preference.
- Run
M-x shell
to get a new*shell*
buffer - In the
*shell*
buffer, change to the One directory by typingcd /path/to/one
- Start a Clojure REPL by running
script/repl
- Start the dev server in the REPL by executing
(use 'one.sample.dev-server)
and then(run-server)
- Open a new emacs window and switch to it:
C-x 2
followed byC-x o
- Change the default directory of the new window:
M-x cd
followed by/path/to/one
- Start another Clojure REPL by typing
C-u M-x inferior-lisp
followed byscript/repl
- Start a ClojureScript REPL in the new Clojure REPL with the commands
(use 'one.sample.dev-server)
and(cljs-repl)
- Connect a browser session to the ClojureScript REPL by opening a browser and visiting http://localhost:8080/.
You're now ready to run commands in either the Clojure REPL or the ClojureScript one. Use the following keys:
-
C-M-x
: Send the top-level expression at point to the inferior-lisp buffer (in our example, this is the ClojureScript REPL). -
C-c C-e
: Send the expression that ends just before point to the inferior-lisp buffer (in our example, this is the ClojureScript REPL). -
C-c x
: Send the top-level expression at point to the shell buffer (in our example, this is the Clojure REPL). -
C-c e
: Send the expression that ends just before point to the shell buffer (in our example, this is the Clojure REPL).
Consider the following code, with the cursor positioned at the
location indicated by the |
character:
(+ 2| 3)
Here is what each of the above keys would result in:
-
C-M-x
: Evaluate(+ 2 3)
in the ClojureScript REPL. -
C-c C-e
: Evaluate2
in the ClojureScript REPL. -
C-c x
: Evaluate(+ 2 3)
in the Clojure REPL. -
C-c e
: Evaluate2
in the Clojure REPL.
If the keys don't work, it may be as a result of interference with slime minor mode. Try disabling slime-mode in your Clojure buffer.