Skip to content

Commit b2dd4a7

Browse files
lycheesebbatsov
authored andcommitted
Allow merging sesman sessions of a project
- Makes cider-repls return the combination of all sesman sessions or those sessions with same host associated with a project - Adds a custom var for toggling the new functionality Closes #2946.
1 parent dd4c555 commit b2dd4a7

File tree

4 files changed

+159
-6
lines changed

4 files changed

+159
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ JVM-specific code outside of JVM Clojure.
1717
* Do not always perform `undef-all`. Undef only with `C-u` prefix.
1818
* Fix extraction of namespace name.
1919

20+
* [#2946](https://github.com/clojure-emacs/cider/issues/2946): Add custom var `cider-merge-sessions` to allow combining sessions in two different ways: Setting `cider-merge-sessions` to `'host` will merge all sessions associated with the same host within a project. Setting it to `'project` will combine all sessions of a project irrespective of their host.
21+
2022
## 1.4.0 (2022-05-02)
2123

2224
## New features

cider-connection.el

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,19 @@ available) and the matching REPL buffer."
6161
:safe #'booleanp
6262
:package-version '(cider . "0.9.0"))
6363

64+
;;;###autoload
65+
(defcustom cider-merge-sessions nil
66+
"Controls session combination behaviour.
67+
68+
Symbol `host' combines all sessions of a project associated with the same host.
69+
Symbol `project' combines all sessions of a project.
70+
71+
All other values do not combine any sessions."
72+
:type 'symbol
73+
:group 'cider
74+
:safe #'symbolp
75+
:package-version '(cider . "1.5"))
76+
6477
(defconst cider-required-nrepl-version "0.6.0"
6578
"The minimum nREPL version that's known to work properly with CIDER.")
6679

@@ -874,6 +887,33 @@ no linked session or there is no REPL of TYPE within the current session."
874887
((listp type) (member buffer-repl-type type))
875888
(t (string= type buffer-repl-type)))))
876889

890+
(defun cider--get-host-from-session (session)
891+
"Returns the host associated with SESSION."
892+
(plist-get (cider--gather-session-params session)
893+
:host))
894+
895+
(defun cider--make-sessions-list-with-hosts (sessions)
896+
"Makes a list of SESSIONS and their hosts.
897+
Returns a list of the form ((session1 host1) (session2 host2) ...)."
898+
(mapcar (lambda (session)
899+
(list session (cider--get-host-from-session session)))
900+
sessions))
901+
902+
(defun cider--get-sessions-with-same-host (session sessions)
903+
"Returns a list of SESSIONS with the same host as SESSION."
904+
(mapcar #'car
905+
(seq-filter (lambda (x)
906+
(string-equal (cadr x)
907+
(cider--get-host-from-session session)))
908+
(cider--make-sessions-list-with-hosts sessions))))
909+
910+
(defun cider--extract-connections (sessions)
911+
"Returns a flattened list of all session buffers in SESSIONS."
912+
(cl-reduce (lambda (x y)
913+
(append x (cdr y)))
914+
sessions
915+
:initial-value '()))
916+
877917
(defun cider-repls (&optional type ensure)
878918
"Return cider REPLs of TYPE from the current session.
879919
If TYPE is nil or multi, return all REPLs. If TYPE is a list of types,
@@ -883,9 +923,24 @@ throw an error if no linked session exists."
883923
((listp type)
884924
(mapcar #'cider-maybe-intern type))
885925
((cider-maybe-intern type))))
886-
(repls (cdr (if ensure
887-
(sesman-ensure-session 'CIDER)
888-
(sesman-current-session 'CIDER)))))
926+
(repls (pcase cider-merge-sessions
927+
('host
928+
(if ensure
929+
(or (cider--extract-connections (cider--get-sessions-with-same-host
930+
(sesman-current-session 'CIDER)
931+
(sesman-current-sessions 'CIDER)))
932+
(user-error "No linked %s sessions" 'CIDER))
933+
(cider--extract-connections (cider--get-sessions-with-same-host
934+
(sesman-current-session 'CIDER)
935+
(sesman-current-sessions 'CIDER)))))
936+
('project
937+
(if ensure
938+
(or (cider--extract-connections (sesman-current-sessions 'CIDER))
939+
(user-error "No linked %s sessions" 'CIDER))
940+
(cider--extract-connections (sesman-current-sessions 'CIDER))))
941+
(_ (cdr (if ensure
942+
(sesman-ensure-session 'CIDER)
943+
(sesman-current-session 'CIDER)))))))
889944
(or (seq-filter (lambda (b)
890945
(cider--match-repl-type type b))
891946
repls)

doc/modules/ROOT/pages/usage/managing_connections.adoc

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,23 @@ You can add new REPLs to the current session with:
7171

7272
A very common use-case would be to run `cider-jack-in-clj` for some project and then follow up with `cider-connect-sibling-cljs`.
7373

74-
NOTE: Unless there are both Clojure and ClojureScript REPLs in the same session smart-dispatch commands (e.g. evaluate the code
75-
in the right Clojure/ClojureScript REPL, toggle between Clojure and ClojureScript REPL) won't work. A very common problem
76-
newcomers experience is to create a Clojure REPL and a ClojureScript REPL in separate sessions and wonder why those are not
74+
[NOTE]
75+
====
76+
Unless there are both Clojure and ClojureScript REPLs in the same
77+
session smart-dispatch commands (e.g. evaluate the code in the right
78+
Clojure/ClojureScript REPL, toggle between Clojure and ClojureScript REPL) won't
79+
work. A very common problem newcomers experience is to create a Clojure REPL and
80+
a ClojureScript REPL in separate sessions and wonder why those are not
7781
interacting properly with one another.
7882
83+
In the case of using separate config files for the clj and cljs dependencies
84+
(e.g. clj dependencies in `deps.edn` and cljs dependencies in `shadow-cljs.edn`)
85+
it is currently impossible to group those two repls in the same session.
86+
However, this can be worked around with `cider-merge-sessions`. Setting it to
87+
`'host` will combine all sessions associated with the same host within a
88+
project. Setting it to `'project` will combine all sessions in the same project.
89+
====
90+
7991
=== Session Life-Cycle Management
8092

8193
Session life-cycle management commands live on the https://github.com/vspinu/sesman[Sesman] keymap (kbd:[C-c C-s])

test/cider-connection-tests.el

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,90 @@
272272
(expect (cider-repls) :to-equal (list bb2 bb1))
273273
(expect (cider-repls 'cljs) :to-equal (list bb2)))))))))))))
274274

275+
(describe "when multiple sessions exist and cider-merge-sessions is set to :project"
276+
(it "always returns all connections associated with a project"
277+
(let ((proj-dir (expand-file-name "/tmp/proj-dir"))
278+
(cider-merge-sessions 'project))
279+
(let ((default-directory proj-dir))
280+
(with-repl-buffer ses-name 'clj bb1
281+
(with-repl-buffer ses-name 'cljs bb2
282+
(with-repl-buffer ses-name2 'clj b1
283+
(with-repl-buffer ses-name2 'cljs b2
284+
285+
(expect (cider-repls) :to-have-same-items-as (list b2 b1 bb2 bb1))
286+
287+
(switch-to-buffer bb1)
288+
(expect (cider-repls) :to-have-same-items-as (list b2 b1 bb2 bb1))
289+
290+
;; follows type arguments
291+
(expect (cider-repls 'clj) :to-have-same-items-as (list b1 bb1))
292+
(expect (cider-repls 'cljs) :to-have-same-items-as (list b2 bb2))
293+
294+
(switch-to-buffer bb2)
295+
;; follows file type
296+
(with-temp-buffer
297+
(setq major-mode 'clojure-mode)
298+
(expect (cider-repls) :to-have-same-items-as (list b2 b1 bb2 bb1))
299+
(expect (cider-repls 'clj) :to-have-same-items-as (list b1 bb1)))
300+
301+
(with-temp-buffer
302+
(setq major-mode 'clojurescript-mode)
303+
(expect (cider-repls) :to-have-same-items-as (list b2 b1 bb2 bb1))
304+
(expect (cider-repls 'cljs) :to-have-same-items-as (list b2 bb2))))))))))
305+
(it "only returns the connections of the active project"
306+
(let ((a-dir (expand-file-name "/tmp/a-dir"))
307+
(b-dir (expand-file-name "/tmp/b-dir"))
308+
(cider-merge-sessions 'project))
309+
(let ((default-directory a-dir))
310+
(with-repl-buffer ses-name 'clj bb1
311+
(with-repl-buffer ses-name 'cljs bb2
312+
(let ((default-directory b-dir))
313+
(with-repl-buffer ses-name2 'clj b1
314+
(with-repl-buffer ses-name2 'cljs b2
315+
316+
(expect (cider-repls) :to-have-same-items-as (list b2 b1))
317+
318+
(switch-to-buffer bb1)
319+
(expect (cider-repls) :to-have-same-items-as (list bb2 bb1))
320+
321+
;; follows type arguments
322+
(expect (cider-repls 'clj) :to-have-same-items-as (list bb1))
323+
(expect (cider-repls 'cljs) :to-have-same-items-as (list bb2))
324+
325+
(switch-to-buffer bb2)
326+
;; follows file type
327+
(let ((default-directory b-dir))
328+
(with-temp-buffer
329+
(setq major-mode 'clojure-mode)
330+
(expect (cider-repls) :to-have-same-items-as (list b2 b1))
331+
(expect (cider-repls 'clj) :to-have-same-items-as (list b1))))
332+
333+
(let ((default-directory a-dir))
334+
(with-temp-buffer
335+
(setq major-mode 'clojurescript-mode)
336+
(expect (cider-repls) :to-have-same-items-as (list bb2 bb1))
337+
(expect (cider-repls 'cljs) :to-have-same-items-as (list bb2)))))))))))))
338+
339+
(describe "when multiple sessions exist and cider-combine-merge-sessions is set to :host"
340+
(before-each
341+
(spy-on 'cider--gather-session-params :and-call-fake (lambda (session)
342+
(if (string-equal (car session) "local")
343+
'(:host "localhost")
344+
'(:host "remotehost")))))
345+
(it "returns only the sessions associated with the current session's host"
346+
(let ((cider-merge-sessions 'host)
347+
(local-session "local")
348+
(remote-session "remote")
349+
(proj-dir (expand-file-name "/tmp/proj-dir")))
350+
(let ((default-directory proj-dir))
351+
(with-repl-buffer local-session 'clj l1
352+
(with-repl-buffer local-session 'clj l2
353+
(with-repl-buffer remote-session 'clj r1
354+
(switch-to-buffer r1)
355+
(expect (cider-repls) :to-have-same-items-as (list r1))
356+
(switch-to-buffer l1)
357+
(expect (cider-repls) :to-have-same-items-as (list l1 l2)))))))))
358+
275359
(describe "killed buffers"
276360
(it "do not show up in it"
277361
(let ((default-directory (expand-file-name "/tmp/some-dir")))

0 commit comments

Comments
 (0)