Skip to content

Commit

Permalink
Fix nrepl-client not connecting to ssh-remote after cider-jack-in
Browse files Browse the repository at this point in the history
Calling cider-jack-in from a tramp buffer on a ssh-remote would throw:
"error in process filter: Wrong type argument: stringp, nil"

This happened because nrepl--ssh-tunnel-connect is trying to
string-match on (buffer-file-name) which returns nil, because the
execution context is the nrepl buffer.

To work around this, we pass down the buffer from which cider-jack-in
was called.

Considerations:

- This should be reverted if the cause of this feature breaking is
  found and fixable. It seemed to have worked before,
  see: clojure-emacs#3264

- In nrepl-client.el the param name "jack-in-buffer" seems a bit too
  specific. But, as long as this workaround is its only usecase, I
  consider it reasonable for discoverability.

- This should be refactored as soon as there's a more general way to convey
  contextual information to lower level functions.

Fixes:
clojure-emacs#3541
clojure-emacs#3303 (partially)
  • Loading branch information
caadr committed Oct 19, 2023
1 parent 27ed547 commit 9eb941b
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 10 deletions.
3 changes: 2 additions & 1 deletion cider-connection.el
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ PARAMS is a plist containing :host, :port, :server and other parameters for
(plist-get params :server)
(lambda (_)
(cider-repl-create params))
(plist-get params :socket-file))))
(plist-get params :socket-file)
(plist-get params :jack-in-buffer))))

(defun cider-sessions ()
"Return a list of all active CIDER sessions."
Expand Down
1 change: 1 addition & 0 deletions cider.el
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,7 @@ double prefix prompt for all these parameters."
(interactive "P")
(let ((params (thread-first
params
(plist-put :jack-in-buffer (current-buffer))
(cider--update-project-dir)
(cider--check-existing-session)
(cider--update-jack-in-cmd))))
Expand Down
21 changes: 12 additions & 9 deletions nrepl-client.el
Original file line number Diff line number Diff line change
Expand Up @@ -533,15 +533,16 @@ If NO-ERROR is non-nil, show messages instead of throwing an error."
(error msg))
nil)))))

(defun nrepl-connect (host port)
(defun nrepl-connect (host port &optional jack-in-buffer)
"Connect to the nREPL server identified by HOST and PORT.
For local hosts use a direct connection. For remote hosts, if
`nrepl-force-ssh-for-remote-hosts' is nil, attempt a direct connection
first. If `nrepl-force-ssh-for-remote-hosts' is non-nil or the direct
connection failed (and `nrepl-use-ssh-fallback-for-remote-hosts' is
non-nil), try to start a SSH tunneled connection. Return a plist of the
form (:proc PROC :host \"HOST\" :port PORT) that might contain additional
key-values depending on the connection type."
key-values depending on the connection type. If JACK-IN-BUFFER is given
and a tramp buffer, reuse its ssh parameters."
(let ((localp (if host
(nrepl-local-host-p host)
(not (file-remote-p default-directory)))))
Expand All @@ -554,15 +555,15 @@ key-values depending on the connection type."
;; fallback to ssh tunneling if enabled
(and nrepl-use-ssh-fallback-for-remote-hosts
(message "[nREPL] Falling back to SSH tunneled connection ...")
(nrepl--ssh-tunnel-connect host port))
(nrepl--ssh-tunnel-connect host port jack-in-buffer))
;; fallback is either not enabled or it failed as well
(if (and (null nrepl-use-ssh-fallback-for-remote-hosts)
(not localp))
(error "[nREPL] Direct connection to %s:%s failed; try setting `nrepl-use-ssh-fallback-for-remote-hosts' to t"
host port)
(error "[nREPL] Cannot connect to %s:%s" host port)))
;; `nrepl-force-ssh-for-remote-hosts' is non-nil
(nrepl--ssh-tunnel-connect host port)))))
(nrepl--ssh-tunnel-connect host port jack-in-buffer)))))

(defun nrepl--direct-connect (host port &optional no-error)
"If HOST and PORT are given, try to `open-network-stream'.
Expand All @@ -584,10 +585,12 @@ If NO-ERROR is non-nil, show messages instead of throwing an error."
(error msg))
nil)))))

(defun nrepl--ssh-tunnel-connect (host port)
"Connect to a remote machine identified by HOST and PORT through SSH tunnel."
(defun nrepl--ssh-tunnel-connect (host port &optional jack-in-buffer)
"Connect to a remote machine identified by HOST and PORT through SSH tunnel.
If JACK-IN-BUFFER is given and a tramp buffer, reuse its connection parameters.
Defaults to the current buffer."
(message "[nREPL] Establishing SSH tunneled connection to %s:%s ..." host port)
(let* ((current-buf (buffer-file-name))
(let* ((current-buf (buffer-file-name (or jack-in-buffer (current-buffer))))
(tramp-file-regexp "/ssh:\\(.+@\\)?\\(.+?\\)\\(:\\|#\\).+")
(remote-dir (cond
;; If current buffer is a TRAMP buffer and its host is
Expand Down Expand Up @@ -704,7 +707,7 @@ Do not kill the server if there is a REPL connected to that server."
(buffer-list)))
(nrepl-kill-server-buffer server-buf)))))

(defun nrepl-start-client-process (&optional host port server-proc buffer-builder socket-file)
(defun nrepl-start-client-process (&optional host port server-proc buffer-builder socket-file jack-in-buffer)
"Create new client process identified by either HOST and PORT or SOCKET-FILE.
If SOCKET-FILE is non-nil, it takes precedence. In remote buffers, HOST
and PORT are taken from the current tramp connection. SERVER-PROC must be
Expand All @@ -713,7 +716,7 @@ of one argument (endpoint returned by `nrepl-connect') which returns a
client buffer. Return the newly created client process."
(let* ((endpoint (if socket-file
(nrepl--unix-connect (expand-file-name socket-file))
(nrepl-connect host port)))
(nrepl-connect host port jack-in-buffer)))
(client-proc (plist-get endpoint :proc))
(builder (or buffer-builder (error "`buffer-builder' must be provided")))
(client-buf (funcall builder endpoint)))
Expand Down

0 comments on commit 9eb941b

Please sign in to comment.