Skip to content

Commit

Permalink
[Fix #1913] Allow toggling of current buffer connection (#2149)
Browse files Browse the repository at this point in the history
Cljc buffers send their evals to both clj and cljs repls if available due to
`cider-map-connections`. Toggling a current buffer's connection involves hiding
the other connection.

Previously, when toggling _again_, the original list was not consulted and only
the truncated list, preventing the other connection from being found. This
allows for the full list to be searched for the other buffer.

In addition, a prefix dictates that the local connection list is discarded in
favor of the full list, restoring the evaluation in both clj and cljs
buffers (if both are present).
  • Loading branch information
dpsutton authored and bbatsov committed Jan 3, 2018
1 parent f707955 commit c5d4964
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## master (unreleased)

### Bugs Fixed

* [#1913](https://github.com/clojure-emacs/cider/issues/1913): Fix `cider-toggle-buffer-connection` to allow cycling of connection and restoring all connections in cljc buffers

### Changes

* [#2151](https://github.com/clojure-emacs/cider/pull/2151) Improve formatting of spec in `cider-doc` buffer
Expand Down
35 changes: 28 additions & 7 deletions cider-client.el
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,35 @@ such a link cannot be established automatically."
(when conn
(setq-local cider-connections (list conn)))))

(defun cider-toggle-buffer-connection ()
"Toggle the current buffer's connection between Clojure and ClojureScript."
(interactive)
(defun cider-toggle-buffer-connection (&optional restore-all)
"Toggle the current buffer's connection between Clojure and ClojureScript.
Default behavior of a cljc buffer is to send eval commands to both Clojure
and ClojureScript. This function sets a local buffer variable to hide one
or the other. Optional argument RESTORE-ALL undo any toggled behavior by
using the default list of connections."
(interactive "P")
(cider-ensure-connected)
(let ((other-conn (cider-other-connection)))
(if other-conn
(setq-local cider-connections (list other-conn))
(user-error "No other connection available"))))
(if restore-all
(progn
(kill-local-variable 'cider-connections)
(let ((types (mapcar #'cider--connection-type (cider-connections))))
(message (format "Cider connections available: %s" types))))
(let ((current-conn (cider-current-connection))
(was-local (local-variable-p 'cider-connections))
(original-connections (cider-connections)))
;; we set the local variable to eclipse all connections in favor of the
;; toggled connection. to recover the full list we must remove the
;; obfuscation
(kill-local-variable 'cider-connections)
(if-let* ((other-conn (cider-other-connection current-conn)))
(progn
(setq-local cider-connections (list other-conn))
(message (format "Connection set to %s" (cider--connection-type other-conn))))
(progn
(when was-local
(setq-local cider-connections original-connections))
(user-error "No other connection available"))))))

(defun cider-clear-buffer-local-connection ()
"Remove association between the current buffer and a connection."
Expand Down
14 changes: 14 additions & 0 deletions doc/up_and_running.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,17 @@ You should also check out
[leiningen]: http://leiningen.org/
[boot]: http://boot-clj.com/
[piggieback]: https://github.com/cemerick/piggieback

## Working with cljc files

Ordinarily, CIDER dispatches code from `clj` files to Clojure repls and `cljs`
files to ClojureScript repls. However, `cljc` files have two possible connection
targets. By default, CIDER tries to evaluate `cljc` files in all connection
buffers, both `clj` and `cljs`. This can be modified with
`M-x cider-toggle-connection-buffer`. Toggling this once will choose one of the
connections as the primary, and successive calls to `M-x
cider-toggle-connection-buffer` will alternate which connection to use. To
restore evaluation to both connections, invoke `M-x
cider-toggle-connection-buffer` with a prefix argument. If there is only a
Clojure connection, no toggling will happen and a message will inform you that
there are no other connections to switch to.
40 changes: 40 additions & 0 deletions test/cider-client-tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,46 @@
:to-equal "stub")
(expect (cider-var-info "") :to-equal nil)))

(describe "cider-toggle-buffer-connection"
(spy-on 'message :and-return-value nil)

(describe "when there are multiple connections"
(it "toggles between multiple buffers"
(with-connection-buffer "clj" clj-buffer
(with-connection-buffer "cljs" cljs-buffer
(with-temp-buffer
(setq major-mode 'clojurec-mode)
(expect (cider-connections)
:to-equal (list cljs-buffer clj-buffer))

(cider-toggle-buffer-connection)
(expect (cider-connections)
:to-equal (list clj-buffer))

(cider-toggle-buffer-connection)
(expect (cider-connections)
:to-equal (list cljs-buffer))

(cider-toggle-buffer-connection t)
(expect (cider-connections)
:to-equal (list cljs-buffer clj-buffer)))))))

(describe "when there is a single connection"
(it "reports a user error"
(with-connection-buffer "clj" clj-buffer
(with-temp-buffer
(setq major-mode 'clojurec-mode)
(expect (cider-connections)
:to-equal (list clj-buffer))

(expect (cider-toggle-buffer-connection) :to-throw 'user-error)

(expect (cider-connections)
:to-equal (list clj-buffer))

(expect (local-variable-p 'cider-connections)
:to-be nil))))))

(describe "cider-make-connection-default"
:var (connections)

Expand Down

0 comments on commit c5d4964

Please sign in to comment.