Skip to content

Commit 817d37e

Browse files
committed
Merge pull request #1399 from clojure-emacs/dual-dispatch-eval
[Fix #1299] Eval in both REPLs for cljc and cljx
2 parents ac0f0d7 + cf54439 commit 817d37e

File tree

6 files changed

+92
-70
lines changed

6 files changed

+92
-70
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050
### Changes
5151

52+
* [#1299]https://github.com/clojure-emacs/cider/issues/1299 <kbd>C-c C-k</kbd> and <kbd> C-c C-l</kbd> now dispatch to both the Clojure and ClojureScript REPL (in the same project) when called from a `.cljc` or `.cljx` file.
5253
* [#1397](https://github.com/clojure-emacs/cider/issues/1297) <kbd>C-c M-n</kbd> now changes the ns of both the Clojure and ClojureScript REPL (in the same project) when called from a cljc or cljx file.
5354
* [#1348](https://github.com/clojure-emacs/cider/issues/1348): Drop the dash dependency.
5455
* The usage of the default connection has been reduced significantly. Now evaluations & related commands will be routed via the connection matching the current project automatically unless there's some ambiguity when determining the connection (like multiple or no matching connections). Simply put you'll no longer have to mess around much with connecting-setting commands (e.g. `nrepl-connection-browser`, `cider-rotate-default-connection`).

cider-client.el

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -207,30 +207,28 @@ from the file extension."
207207
(cider-connections) ; Cleanup the connections list.
208208
(if (eq cider-request-dispatch 'dynamic)
209209
(cond
210-
((cider--in-connection-buffer-p) (current-buffer))
210+
((and (not type) (cider--in-connection-buffer-p)) (current-buffer))
211211
((= 1 (length cider-connections)) (car cider-connections))
212-
(t (let ((repls (cider-find-connection-buffer-for-project-directory
213-
nil :all-connections)))
214-
(if (= 1 (length repls))
212+
(t (let ((project-connections
213+
(cider-find-connection-buffer-for-project-directory
214+
nil :all-connections)))
215+
(if (= 1 (length project-connections))
215216
;; Only one match, just return it.
216-
(car repls)
217+
(car project-connections)
217218
;; OW, find one matching the extension of current file.
218219
(let ((type (or type (file-name-extension (or (buffer-file-name) "")))))
219220
(or (seq-find (lambda (conn)
220-
(equal (with-current-buffer conn
221-
cider-repl-type)
222-
type))
223-
(append repls cider-connections))
224-
(car repls)
221+
(equal (cider--connection-type conn) type))
222+
project-connections)
223+
(car project-connections)
225224
(car cider-connections)))))))
226225
;; TODO: Add logic to dispatch to a matching Clojure/ClojureScript REPL based on file type
227226
(car cider-connections)))
228227

229228
(defun cider-other-connection (&optional connection)
230-
"Return the first connection of another type than `cider-current-connection', \
231-
in the same project, or nil.
232-
233-
If CONNECTION is provided act on that connection instead."
229+
"Return the first connection of another type than CONNECTION
230+
Only return connections in the same project or nil.
231+
CONNECTION defaults to `cider-current-connection'."
234232
(let* ((connection (or connection (cider-current-connection)))
235233
(connection-type (cider--connection-type connection))
236234
(other (if (equal connection-type "clj")
@@ -239,6 +237,17 @@ If CONNECTION is provided act on that connection instead."
239237
(unless (equal connection-type (cider--connection-type other))
240238
other)))
241239

240+
(defun cider-map-connections (function)
241+
"Call FUNCTION once for each appropriate connection.
242+
The function is called with one argument, the connection buffer.
243+
The appropriate connections are found by inspecting the current buffer. If
244+
the buffer is associated with a .cljc or .cljx file, BODY will be executed
245+
multiple times."
246+
(if-let ((is-cljc (cider--cljc-or-cljx-buffer-p))
247+
(other-connection (cider-other-connection)))
248+
(mapc function (list (cider-current-connection) other-connection))
249+
(funcall function (cider-current-connection))))
250+
242251

243252
;;; Connection Browser
244253
(defvar cider-connections-buffer-mode-map
@@ -422,29 +431,26 @@ Signal an error if it is not supported."
422431
(unless (cider-nrepl-op-supported-p op)
423432
(error "Can't find nREPL middleware providing op \"%s\". Please, install (or update) cider-nrepl %s and restart CIDER" op (upcase cider-version))))
424433

425-
(defun cider--ensure-session (request)
426-
"Make sure REQUEST has session.
427-
428-
If the nREPL request lacks a session `cider-current-session' is added."
429-
(if (seq-contains request "session")
430-
request
431-
(append request (list "session" (cider-current-session)))))
432-
433-
(defun cider-nrepl-send-request (request callback)
434+
(defun cider-nrepl-send-request (request callback &optional connection)
434435
"Send REQUEST and register response handler CALLBACK.
435436
REQUEST is a pair list of the form (\"op\" \"operation\" \"par1-name\"
436437
\"par1\" ... ).
438+
If CONNECTION is provided dispatch to that connection instead of
439+
the current connection.
440+
437441
Return the id of the sent message."
438-
(nrepl-send-request (cider--ensure-session request) callback (cider-current-connection)))
442+
(nrepl-send-request request callback (or connection (cider-current-connection))))
439443

440-
(defun cider-nrepl-send-sync-request (request &optional abort-on-input)
444+
(defun cider-nrepl-send-sync-request (request &optional connection abort-on-input)
441445
"Send REQUEST to the nREPL server synchronously.
442446
Hold till final \"done\" message has arrived and join all response messages
443447
of the same \"op\" that came along and return the accumulated response.
444448
If ABORT-ON-INPUT is non-nil, the function will return nil
445449
at the first sign of user input, so as not to hang the
446450
interface."
447-
(nrepl-send-sync-request (cider--ensure-session request) (cider-current-connection) abort-on-input))
451+
(nrepl-send-sync-request request
452+
(or connection (cider-current-connection))
453+
abort-on-input))
448454

449455
(defun cider-nrepl-send-unhandled-request (request)
450456
"Send REQUEST to the nREPL server and ignore any responses.
@@ -612,17 +618,21 @@ thing at point."
612618
;;; Requests
613619

614620
(declare-function cider-load-file-handler "cider-interaction")
615-
(defun cider-request:load-file (file-contents file-path file-name &optional callback)
621+
(defun cider-request:load-file (file-contents file-path file-name &optional connection callback)
616622
"Perform the nREPL \"load-file\" op.
617623
FILE-CONTENTS, FILE-PATH and FILE-NAME are details of the file to be
618-
loaded. If CALLBACK is nil, use `cider-load-file-handler'."
624+
loaded.
625+
626+
If CONNECTION is nil, use `cider-current-connection'.
627+
If CALLBACK is nil, use `cider-load-file-handler'."
619628
(cider-nrepl-send-request (list "op" "load-file"
620629
"session" (cider-current-session)
621630
"file" file-contents
622631
"file-path" file-path
623632
"file-name" file-name)
624633
(or callback
625-
(cider-load-file-handler (current-buffer)))))
634+
(cider-load-file-handler (current-buffer)))
635+
connection))
626636

627637

628638
;;; Sync Requests

cider-interaction.el

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,32 +1350,15 @@ unloaded."
13501350
(with-current-buffer (find-file-noselect file)
13511351
(substring-no-properties (buffer-string))))
13521352

1353-
(defun cider-load-file (filename)
1354-
"Load (eval) the Clojure file FILENAME in nREPL."
1355-
(interactive (list
1356-
(read-file-name "Load file: " nil nil nil
1357-
(when (buffer-file-name)
1358-
(file-name-nondirectory
1359-
(buffer-file-name))))))
1360-
(cider-ensure-connected)
1361-
(when-let ((buf (find-buffer-visiting filename)))
1362-
(with-current-buffer buf
1363-
(remove-overlays nil nil 'cider-type 'instrumented-defs)
1364-
(cider--clear-compilation-highlights)))
1365-
(cider--quit-error-window)
1366-
(cider--cache-ns-form)
1367-
(cider-request:load-file
1368-
(cider-file-string filename)
1369-
(funcall cider-to-nrepl-filename-function (cider--server-filename filename))
1370-
(file-name-nondirectory filename))
1371-
(message "Loading %s..." filename))
1372-
13731353
(defun cider-load-buffer (&optional buffer)
13741354
"Load (eval) BUFFER's file in nREPL.
13751355
If no buffer is provided the command acts on the current buffer.
1376-
The heavy lifting is done by `cider-load-file'."
1356+
1357+
If the buffer is for a cljc or cljx file, and both a Clojure and
1358+
ClojureScript REPL exists for the project, it is evaluated in both REPLs."
13771359
(interactive)
13781360
(check-parens)
1361+
(cider-ensure-connected)
13791362
(setq buffer (or buffer (current-buffer)))
13801363
(with-current-buffer buffer
13811364
(unless buffer-file-name
@@ -1385,7 +1368,34 @@ The heavy lifting is done by `cider-load-file'."
13851368
(or (eq cider-prompt-save-file-on-load 'always-save)
13861369
(y-or-n-p (format "Save file %s? " buffer-file-name))))
13871370
(save-buffer))
1388-
(cider-load-file buffer-file-name)))
1371+
(remove-overlays nil nil 'cider-type 'instrumented-defs)
1372+
(cider--clear-compilation-highlights)
1373+
(cider--quit-error-window)
1374+
(cider--cache-ns-form)
1375+
(let ((filename (buffer-file-name)))
1376+
(cider-map-connections
1377+
(lambda (connection)
1378+
(cider-request:load-file (cider-file-string filename)
1379+
(funcall cider-to-nrepl-filename-function
1380+
(cider--server-filename filename))
1381+
(file-name-nondirectory filename)
1382+
connection)))
1383+
(message "Loading %s..." filename))))
1384+
1385+
(defun cider-load-file (filename)
1386+
"Load (eval) the Clojure file FILENAME in nREPL.
1387+
1388+
If the file is a cljc or cljx file, and both a Clojure and ClojureScript
1389+
REPL exists for the project, it is evaluated in both REPLs.
1390+
1391+
The heavy lifting is done by `cider-load-buffer'."
1392+
(interactive (list
1393+
(read-file-name "Load file: " nil nil nil
1394+
(when (buffer-file-name)
1395+
(file-name-nondirectory
1396+
(buffer-file-name))))))
1397+
(when-let ((buffer (find-buffer-visiting filename)))
1398+
(cider-load-buffer buffer)))
13891399

13901400
(defalias 'cider-eval-file 'cider-load-file
13911401
"A convenience alias as some people are confused by the load-* names.")

cider-mode.el

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,8 @@ namespace itself."
409409
(interactive)
410410
(when cider-font-lock-dynamically
411411
(font-lock-remove-keywords nil cider--dynamic-font-lock-keywords)
412-
(when-let ((symbols (cider-resolve-ns-symbols (or ns (cider-current-ns)))))
412+
(when-let ((ns (or ns (cider-current-ns)))
413+
(symbols (cider-resolve-ns-symbols ns)))
413414
(setq-local cider--dynamic-font-lock-keywords
414415
(cider--compile-font-lock-keywords
415416
symbols (cider-resolve-ns-symbols (cider-resolve-core-ns))))

cider-repl.el

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -790,13 +790,10 @@ namespace to switch to."
790790
(cider-current-ns))))
791791
(when (or (not ns) (equal ns ""))
792792
(user-error "No namespace selected"))
793-
(cider-nrepl-request:eval (format "(in-ns '%s)" ns)
794-
(cider-repl-switch-ns-handler
795-
(cider-current-connection)))
796-
(when (cider--cljc-or-cljx-buffer-p)
797-
(when-let ((other-connection (cider-other-connection)))
798-
(cider-nrepl-request:eval (format "(in-ns '%s)" ns)
799-
(cider-repl-switch-ns-handler other-connection)))))
793+
(cider-map-connections
794+
(lambda (connection)
795+
(cider-nrepl-request:eval (format "(in-ns '%s)" ns)
796+
(cider-repl-switch-ns-handler connection)))))
800797

801798

802799
;;;;; History

nrepl-client.el

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ object is a root list or dict."
493493
;; else, throw a quiet error
494494
(t
495495
(message "Invalid bencode message detected. See %s buffer."
496-
nrepl-message-buffer-name)
496+
nrepl-message-buffer-name-template)
497497
(nrepl-log-message
498498
(format "Decoder error at position %d (`%s'):"
499499
(point) (buffer-substring (point) (min (+ (point) 10) (point-max)))))
@@ -896,14 +896,17 @@ REQUEST is a pair list of the form (\"op\" \"operation\" \"par1-name\"
896896
\"par1\" ... ). See the code of `nrepl-request:clone',
897897
`nrepl-request:stdin', etc.
898898
Return the ID of the sent message."
899-
(let* ((id (nrepl-next-request-id connection))
900-
(request (cons 'dict (lax-plist-put request "id" id)))
901-
(message (nrepl-bencode request)))
902-
(nrepl-log-message request 'request)
903-
(with-current-buffer connection
899+
(with-current-buffer connection
900+
(unless (or (plist-get request "session")
901+
(not nrepl-session))
902+
(setq request (append request (list "session" nrepl-session))))
903+
(let* ((id (nrepl-next-request-id connection))
904+
(request (cons 'dict (lax-plist-put request "id" id)))
905+
(message (nrepl-bencode request)))
906+
(nrepl-log-message request 'request)
904907
(puthash id callback nrepl-pending-requests)
905-
(process-send-string nil message))
906-
id))
908+
(process-send-string nil message)
909+
id)))
907910

908911
(defvar nrepl-ongoing-sync-request nil
909912
"Dynamically bound to t while a sync request is ongoing.")
@@ -995,7 +998,7 @@ If LINE and COLUMN are non-nil and current buffer is a file buffer, \"line\",
995998
"line" line
996999
"column" column)))))
9971000

998-
(defun nrepl-request:eval (input callback connection session &optional ns line column)
1001+
(defun nrepl-request:eval (input callback connection &optional session ns line column)
9991002
"Send the request INPUT and register the CALLBACK as the response handler.
10001003
The request is dispatched via CONNECTION and SESSION. If NS is non-nil,
10011004
include it in the request. LINE and COLUMN, if non-nil, define the position
@@ -1137,7 +1140,7 @@ the port, and the client buffer."
11371140
;;; Messages
11381141

11391142
(defcustom nrepl-log-messages t
1140-
"If non-nil, log protocol messages to the `nrepl-message-buffer-name' buffer."
1143+
"If non-nil, log protocol messages to the `nrepl-message-buffer-name-template' buffer."
11411144
:type 'boolean
11421145
:group 'nrepl)
11431146

@@ -1181,7 +1184,7 @@ operations.")
11811184
(`response (cons '<- (cdr msg)))))
11821185

11831186
(defun nrepl-log-message (msg type)
1184-
"Log the given MSG to the buffer given by `nrepl-message-buffer-name'.
1187+
"Log the given MSG to the buffer given by `nrepl-message-buffer-name-template'.
11851188
11861189
TYPE is either request or response."
11871190
(when nrepl-log-messages

0 commit comments

Comments
 (0)