Skip to content

Commit

Permalink
New connection API and user level connection commands
Browse files Browse the repository at this point in the history
  New variables:

      cider-connection-alist, cider-connection-name, cider-connected-directories

  New connection API functions:

      cider-delete-connection-repl, cider-add-connection-repl,
      cider-get-connection, cider-project-connections-repls,
      cider-current-connection-repls, cider-current-connection-repl

  New commands for connection association:

      cider-assoc-buffer-with-connection
      cider-assoc-directory-with-connection
      cider-assoc-project-with-connection
      cider-assoc-with-connection

  New semantics:

      cider-assoc-project-with-connection, cider-connections,
      cider-current-connection, cider-project-connections

  Removed:

      cider-request-dispatch, cider-connections,
      cider-find-connection-buffer-for-project-directory,
      cider-toggle-buffer-connection, cider-clear-buffer-local-connection,
      cider-toggle-request-dispatch, cider-current-connection,
      cider--in-connection-buffer-p, cider-default-connection,
      cider-rotate-default-connection cider--guess-cljs-connection,
      cider--has-warned-about-bad-repl-type, cider-map-connections,
      cider-connections-make-default, cider--connections-make-default,
      nrepl-use-this-as-repl-buffer

  Work, but need to be re-factored/adjusted:

      cider-change-buffers-designation
      cider-connection-browser
  • Loading branch information
vspinu committed Aug 2, 2017
1 parent 71f737d commit 5807f2b
Show file tree
Hide file tree
Showing 19 changed files with 790 additions and 933 deletions.
690 changes: 314 additions & 376 deletions cider-client.el

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cider-debug.el
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ In order to work properly, this mode must be activated by
;; cider-nrepl has a chance to send the next message, and so that the user
;; doesn't accidentally hit `n' between two messages (thus editing the code).
(when-let ((proc (unless nrepl-ongoing-sync-request
(get-buffer-process (cider-current-connection)))))
(get-buffer-process (cider-current-connection-repl)))))
(accept-process-output proc 1))
(unless cider--debug-mode
(setq buffer-read-only nil)
Expand Down
213 changes: 80 additions & 133 deletions cider-interaction.el
Original file line number Diff line number Diff line change
Expand Up @@ -1040,10 +1040,11 @@ evaluation command. Honor `cider-auto-jump-to-error'."

(defun cider-need-input (buffer)
"Handle an need-input request from BUFFER."
;; FIXME: breaks with cljc
(with-current-buffer buffer
(nrepl-request:stdin (concat (read-from-minibuffer "Stdin: ") "\n")
(cider-stdin-handler buffer)
(cider-current-connection))))
(cider-current-connection-repl))))

(defun cider-emit-into-color-buffer (buffer value)
"Emit into color BUFFER the provided VALUE."
Expand Down Expand Up @@ -1103,6 +1104,7 @@ ADDITIONAL-PARAMS is a plist to be appended to the request message.
If `cider-interactive-eval-override' is a function, call it with the same
arguments and only proceed with evaluation if it returns nil."
(cider-ensure-connected)
(let ((form (or form (apply #'buffer-substring-no-properties bounds)))
(start (car-safe bounds))
(end (car-safe (cdr-safe bounds))))
Expand All @@ -1111,21 +1113,18 @@ arguments and only proceed with evaluation if it returns nil."
(unless (and cider-interactive-eval-override
(functionp cider-interactive-eval-override)
(funcall cider-interactive-eval-override form callback bounds))
(cider-map-connections #'ignore :any)
(cider-map-connections
(lambda (connection)
(cider--prep-interactive-eval form connection)
(cider-nrepl-request:eval
form
(or callback (cider-interactive-eval-handler nil bounds))
;; always eval ns forms in the user namespace
;; otherwise trying to eval ns form for the first time will produce an error
(if (cider-ns-form-p form) "user" (cider-current-ns))
(when start (line-number-at-pos start))
(when start (cider-column-number-at-pos start))
additional-params
connection))
:both))))
(dolist (repl (cider-current-connection-repls))
(cider--prep-interactive-eval form repl)
(cider-nrepl-request:eval
form
(or callback (cider-interactive-eval-handler nil bounds))
;; always eval ns forms in the user namespace
;; otherwise trying to eval ns form for the first time will produce an error
(if (cider-ns-form-p form) "user" (cider-current-ns))
(when start (line-number-at-pos start))
(when start (cider-column-number-at-pos start))
additional-params
repl)))))

(defun cider-eval-region (start end)
"Evaluate the region between START and END."
Expand Down Expand Up @@ -1176,8 +1175,9 @@ With a prefix arg, LOC, insert before the form, otherwise afterwards."
"Evaluate the expression preceding point and insert its result in the REPL.
If invoked with a PREFIX argument, switch to the REPL buffer."
(interactive "P")
;; FIXME: handler doesn't consider cljc
(cider-interactive-eval nil
(cider-insert-eval-handler (cider-current-connection))
(cider-insert-eval-handler (cider-current-connection-repl))
(cider-last-sexp 'bounds))
(when prefix
(cider-switch-to-repl-buffer)))
Expand All @@ -1186,7 +1186,8 @@ If invoked with a PREFIX argument, switch to the REPL buffer."
"Evaluate expr before point and insert its pretty-printed result in the REPL.
If invoked with a PREFIX argument, switch to the REPL buffer."
(interactive "P")
(let* ((conn-buffer (cider-current-connection)))
;; FIME: breaks with cljc
(let* ((conn-buffer (cider-current-connection-repl)))
(cider-interactive-eval nil
(cider-insert-eval-handler conn-buffer)
(cider-last-sexp 'bounds)
Expand Down Expand Up @@ -1321,7 +1322,8 @@ passing arguments."
If EVAL is non-nil the form will also be evaluated."
(while (string-match "\\`[ \t\n\r]+\\|[ \t\n\r]+\\'" form)
(setq form (replace-match "" t t form)))
(with-current-buffer (cider-current-connection)
;; FIXME: breaks with cljc
(with-current-buffer (cider-current-connection-repl)
(goto-char (point-max))
(let ((beg (point)))
(insert form)
Expand Down Expand Up @@ -1371,7 +1373,8 @@ See command `cider-mode'."
(add-hook 'clojure-mode-hook #'cider-mode)
(dolist (buffer (cider-util--clojure-buffers))
(with-current-buffer buffer
(cider-mode +1))))
(when (cider-current-connection)
(cider-mode +1)))))

(defun cider-disable-on-existing-clojure-buffers ()
"Disable command `cider-mode' on existing Clojure buffers."
Expand Down Expand Up @@ -1427,20 +1430,18 @@ opposite of what that option dictates."
"Toggle ns tracing.
Defaults to the current ns. With prefix arg QUERY, prompts for a ns."
(interactive "P")
(cider-map-connections
(lambda (conn)
(with-current-buffer conn
(cider-ensure-op-supported "toggle-trace-ns")
(let ((ns (if query
(completing-read "Toggle trace for ns: "
(cider-sync-request:ns-list))
(cider-current-ns))))
(let* ((trace-response (cider-sync-request:toggle-trace-ns ns))
(ns-status (nrepl-dict-get trace-response "ns-status")))
(pcase ns-status
("not-found" (error "Namespace %s not found" (cider-propertize ns 'ns)))
(_ (message "Namespace %s %s" (cider-propertize ns 'ns) ns-status)))))))
:clj))
(dolist (repl (cider-current-connection-repls "clj"))
(with-current-buffer repl
(cider-ensure-op-supported "toggle-trace-ns")
(let ((ns (if query
(completing-read "Toggle trace for ns: "
(cider-sync-request:ns-list))
(cider-current-ns))))
(let* ((trace-response (cider-sync-request:toggle-trace-ns ns))
(ns-status (nrepl-dict-get trace-response "ns-status")))
(pcase ns-status
("not-found" (error "Namespace %s not found" (cider-propertize ns 'ns)))
(_ (message "Namespace %s %s" (cider-propertize ns 'ns) ns-status))))))))

(defun cider-undef ()
"Undefine a symbol from the current ns."
Expand Down Expand Up @@ -1545,34 +1546,32 @@ refresh functions (defined in `cider-refresh-before-fn' and
(let ((clear? (member mode '(clear 16)))
(refresh-all? (member mode '(refresh-all 4)))
(inhibit-refresh-fns (member mode '(inhibit-fns -1))))
(cider-map-connections
(lambda (conn)
;; Inside the lambda, so the buffer is not created if we error out.
(let ((log-buffer (or (get-buffer cider-refresh-log-buffer)
(cider-make-popup-buffer cider-refresh-log-buffer))))
(when cider-refresh-show-log-buffer
(cider-popup-buffer-display log-buffer))
(when inhibit-refresh-fns
(cider-emit-into-popup-buffer log-buffer
"inhibiting refresh functions\n"
nil
t))
(when clear?
(cider-nrepl-send-sync-request '("op" "refresh-clear") conn))
(cider-nrepl-send-request
(nconc `("op" ,(if refresh-all? "refresh-all" "refresh")
"print-length" ,cider-stacktrace-print-length
"print-level" ,cider-stacktrace-print-level)
(when (cider--pprint-fn)
`("pprint-fn" ,(cider--pprint-fn)))
(when (and (not inhibit-refresh-fns) cider-refresh-before-fn)
`("before" ,cider-refresh-before-fn))
(when (and (not inhibit-refresh-fns) cider-refresh-after-fn)
`("after" ,cider-refresh-after-fn)))
(lambda (response)
(cider-refresh--handle-response response log-buffer))
conn)))
:clj 'any-mode)))
(dolist (conn (cider-current-connection-repls "clj"))
;; Inside the lambda, so the buffer is not created if we error out.
(let ((log-buffer (or (get-buffer cider-refresh-log-buffer)
(cider-make-popup-buffer cider-refresh-log-buffer))))
(when cider-refresh-show-log-buffer
(cider-popup-buffer-display log-buffer))
(when inhibit-refresh-fns
(cider-emit-into-popup-buffer log-buffer
"inhibiting refresh functions\n"
nil
t))
(when clear?
(cider-nrepl-send-sync-request '("op" "refresh-clear") conn))
(cider-nrepl-send-request
(nconc `("op" ,(if refresh-all? "refresh-all" "refresh")
"print-length" ,cider-stacktrace-print-length
"print-level" ,cider-stacktrace-print-level)
(when (cider--pprint-fn)
`("pprint-fn" ,(cider--pprint-fn)))
(when (and (not inhibit-refresh-fns) cider-refresh-before-fn)
`("before" ,cider-refresh-before-fn))
(when (and (not inhibit-refresh-fns) cider-refresh-after-fn)
`("after" ,cider-refresh-after-fn)))
(lambda (response)
(cider-refresh--handle-response response log-buffer))
conn)))))

(defun cider-file-string (file)
"Read the contents of a FILE and return as a string."
Expand Down Expand Up @@ -1602,16 +1601,14 @@ ClojureScript REPL exists for the project, it is evaluated in both REPLs."
(cider--quit-error-window)
(let ((filename (buffer-file-name buffer))
(ns-form (cider-ns-form)))
(cider-map-connections
(lambda (connection)
(when ns-form
(cider-repl--cache-ns-form ns-form connection))
(cider-request:load-file (cider-file-string filename)
(funcall cider-to-nrepl-filename-function
(cider--server-filename filename))
(file-name-nondirectory filename)
connection))
:both)
(dolist (repl (cider-current-connection-repls))
(when ns-form
(cider-repl--cache-ns-form ns-form repl))
(cider-request:load-file (cider-file-string filename)
(funcall cider-to-nrepl-filename-function
(cider--server-filename filename))
(file-name-nondirectory filename)
repl))
(message "Loading %s..." filename))))

(defun cider-load-file (filename)
Expand Down Expand Up @@ -1724,9 +1721,9 @@ START and END represent the region's boundaries."
"Describe an nREPL session."
(interactive)
(cider-ensure-connected)
(let ((selected-session (completing-read "Describe nREPL session: " (nrepl-sessions (cider-current-connection)))))
(let ((selected-session (completing-read "Describe nREPL session: " (nrepl-sessions (cider-current-connection-repl)))))
(when (and selected-session (not (equal selected-session "")))
(let* ((session-info (nrepl-sync-request:describe (cider-current-connection)))
(let* ((session-info (nrepl-sync-request:describe (cider-current-connection-repl)))
(ops (nrepl-dict-keys (nrepl-dict-get session-info "ops")))
(session-id (nrepl-dict-get session-info "session"))
(session-type (cond
Expand All @@ -1745,87 +1742,37 @@ START and END represent the region's boundaries."
"Close an nREPL session for the current connection."
(interactive)
(cider-ensure-connected)
(nrepl-sync-request:close (cider-current-connection))
(message "Closed nREPL session"))

;;; quiting
(defun cider--close-buffer (buffer)
"Close the BUFFER and kill its associated process (if any)."
(when (buffer-live-p buffer)
(with-current-buffer buffer
(when-let ((proc (get-buffer-process buffer)))
(when (process-live-p proc)
(when (or (not nrepl-server-buffer)
;; Sync request will hang if the server is dead.
(process-live-p (get-buffer-process nrepl-server-buffer)))
(when (or nrepl-session nrepl-tooling-session)
(nrepl-sync-request:close buffer)))
(when proc (delete-process proc)))))
(kill-buffer buffer)))

(defun cider-close-ancillary-buffers ()
"Close buffers that are shared across connections."
(interactive)
(dolist (buf-name cider-ancillary-buffers)
(when (get-buffer buf-name)
(kill-buffer buf-name))))

(defun cider--quit-connection (conn)
"Quit the connection CONN."
(when conn
(cider--close-connection-buffer conn)))
(nrepl-sync-request:close (cider-current-connection-repl))
(message "Closed nREPL session"))

(defun cider-quit (&optional quit-all)
"Quit the currently active CIDER connection.
With a prefix argument QUIT-ALL the command will kill all connections
and all ancillary CIDER buffers."
(interactive "P")
(cider-ensure-connected)
(if (and quit-all (y-or-n-p "Are you sure you want to quit all CIDER connections? "))
(progn
(dolist (connection cider-connections)
(cider--quit-connection connection))
(mapcar #'cider--quit-connection cider-connection-alist)
(message "All active nREPL connections were closed"))
(let ((connection (cider-current-connection)))
(let ((conn (cider-current-connection)))
(when (y-or-n-p (format "Are you sure you want to quit the current CIDER connection %s? "
(cider-propertize (buffer-name connection) 'bold)))
(cider--quit-connection connection))))
(cider-propertize (car conn) 'bold)))
(cider--quit-connection conn))))
;; if there are no more connections we can kill all ancillary buffers
(unless (cider-connected-p)
(cider-close-ancillary-buffers)))

(defun cider--restart-connection (conn)
"Restart the connection CONN."
(let ((project-dir (with-current-buffer conn nrepl-project-dir))
(buf-name (buffer-name conn))
;; save these variables before we kill the connection
(conn-creation-method (with-current-buffer conn cider-connection-created-with))
(conn-endpoint (with-current-buffer conn nrepl-endpoint)))
(cider--quit-connection conn)
;; Workaround for a nasty race condition https://github.com/clojure-emacs/cider/issues/439
;; TODO: Find a better way to ensure `cider-quit' has finished
(message "Waiting for CIDER connection %s to quit..."
(cider-propertize buf-name 'bold))
(sleep-for 2)
(pcase conn-creation-method
(`connect (apply #'cider-connect conn-endpoint))
(`jack-in (if project-dir
(let ((default-directory project-dir))
(cider-jack-in))
(error "Can't restart CIDER connection for unknown project")))
(_ (error "Unexpected value %S for `cider-connection-created-with'"
conn-creation-method)))))

(defun cider-restart (&optional restart-all)
"Restart the currently active CIDER connection.
If RESTART-ALL is t, then restarts all connections."
(interactive "P")
(cider-ensure-connected)
(if restart-all
(dolist (conn cider-connections)
(dolist (conn cider-connection-alist)
(cider--restart-connection conn))
(cider--restart-connection (cider-current-connection))))
(dolist (conn (cider-current-connection-repls))
(cider--restart-connection conn))))

(defvar cider--namespace-history nil
"History of user input for namespace prompts.")
Expand Down
Loading

0 comments on commit 5807f2b

Please sign in to comment.