From c5d4964961ffbd321afd72bea6cac2a8c7133463 Mon Sep 17 00:00:00 2001 From: dpsutton Date: Wed, 3 Jan 2018 08:52:31 -0600 Subject: [PATCH] [Fix #1913] Allow toggling of current buffer connection (#2149) 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). --- CHANGELOG.md | 4 ++++ cider-client.el | 35 ++++++++++++++++++++++++++------- doc/up_and_running.md | 14 +++++++++++++ test/cider-client-tests.el | 40 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54cf81068..f3a7de117 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/cider-client.el b/cider-client.el index f722874d9..e6c70b496 100644 --- a/cider-client.el +++ b/cider-client.el @@ -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." diff --git a/doc/up_and_running.md b/doc/up_and_running.md index 1277638cf..9412f3edd 100644 --- a/doc/up_and_running.md +++ b/doc/up_and_running.md @@ -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. diff --git a/test/cider-client-tests.el b/test/cider-client-tests.el index b6f561698..82cf6654e 100644 --- a/test/cider-client-tests.el +++ b/test/cider-client-tests.el @@ -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)