summaryrefslogtreecommitdiff
path: root/cider-mode.el
diff options
context:
space:
mode:
authorVitalie Spinu <spinuvit@gmail.com>2018-06-17 22:11:00 +0200
committerBozhidar Batsov <bozhidar.batsov@gmail.com>2018-06-17 22:11:00 +0200
commit5cb98a74bad81a2cd15f8db86c469020ed030156 (patch)
tree04f1a2b78563fb2999cca5d6a27b2d45c6995e4e /cider-mode.el
parent3e45c4ca592d67215bc22ca85d84dd87f74f5187 (diff)
New connection API and jack-in rewrite (#2324)
Second attempt on #2069. A brief description of the new functionality follows. 1) __Jack-in/connect__ - User level commands: Create new sessions: C-c M-j: cider-jack-in-clj C-c M-J: cider-jack-in-cljs C-c M-c: cider-connect-clj C-c M-C: cider-connect-cljs Add new REPLs to the current session: C-c M-s: cider-connect-sibling-clj C-c M-S: cider-connect-sibling-cljs - `cider-jack-in-clojurescript` no longer creates two repls, only the cljs repl - clj repl has no longer a special status of the "main" repl. All repls within a session share same server and are siblings of each other. You can create as many clj and cljs siblings as you want from any repl. - Creation of the client is no longer tightly bounded with the nrepl-server startup. The dynamic communication mechanism between jack-in and nrepl-server filter has been replace by a simple `on-port-callback`. 2) __New Connection and Session Management API__ - Connections (aka REPLs) are grouped in [sesman](https://github.com/vspinu/sesman) sessions. Sibling repls are added to the current session. - Cider connection commands (`cider-quit`, `cider-restart`, `cider-display-connection-info`) have been refactored to operate exclusively on the connection level. - Sesman commands operate on the whole session: ![sesman-map](https://user-images.githubusercontent.com/1363467/41355277-6864ffb8-6f21-11e8-9387-3de586477d68.png) - Associations (links) between current context (buffer, directory, project) are governed by sesman and could be formed only on the session level. In a nutshell, session can be linked to projects, directories and buffers. Buffer link have precedence over directory links, and directory have precedence over project links. When a sesman session is registered it's automatically linked with the lowest priority context (project, or directory if no project found). By default (configured with `sesman-1-to-1-links`) multiple sessions can be linked with a project or a directory, but only one session can be linked with a buffer. Cider functionality (eval, completion, repl-switching etc) operate on linked sessions. When there are multiple linked sessions ambiguity is automatically resolved by the recency of the REPL buffers (configured with `sesman-disambiguate-by-relevance`). - Show info on current links with `C-c C-s l`. Show info on current, linked or all sessions with `C-c C-s i`. - Micro-management of the server is not allowed (it's not useful and would complicate UI). All repls within a session share a server. Server can be either remote (`cider-connect`) or local (bootstraped within the emacs during `cider-jack-in-xyz`). In case of the local server, when the last connection is killed the server is automatically killed. `cider-restart` restarts the connection but not the server. `sesman-restart` restarts the server and all the connections. At least two issues I still plan to tackle here: - Restart of SSH tunneled connection has not been tested and probably doesn't work - REPL buffer naming system is no longer adequate. It should be possible to include session name as part of the buffer name and add more flexibility into the customization of buffer name templates. ----- A tot of no longer necessary or questionable functionality has been removed. The goal is to start from scratch and add only what is really necessary. I am listing all the removed functions for the ease of lookup through the github interface. Removed: cider--connection-host, cider--connection-port, cider--connection-project-dir, cider--connection-properties, cider--connection-type, cider--guess-cljs-connection, cider--has-warned-about-bad-repl-type, cider--in-connection-buffer-p, cider--quit-connection, cider--restart-connection, cider-assoc-buffer-with-connection, cider-assoc-project-with-connection, cider-change-buffers-designation, cider-clear-buffer-local-connection, cider-close-nrepl-session, cider-connections (variable), cider-current-connection (variable), cider-current-messages-buffer, cider-current-repl-buffer, cider-default-connection, cider-extract-designation-from-current-repl-buffer, cider-find-connection-buffer-for-project-directory, cider-find-reusable-repl-buffer, cider-make-connection-default, cider-map-connections, cider-other-connection, cider-project-connections, cider-project-connections-types, cider-prompt-for-project-on-connect, cider-read-connection, cider-repl-buffers, cider-replicate-connection, cider-request-dispatch, cider-rotate-default-connection, cider-toggle-buffer-connection, cider-toggle-request-dispatch, nrepl-connection-buffer-name-template, nrepl-create-client-buffer-function, nrepl-post-client-callback nrepl-prompt-to-kill-server-buffer-on-quit, nrepl-use-this-as-repl-buffer, Connection Browser Functionality: cider--connection-browser-buffer-name, cider--connection-ewoc, cider--connection-pp, cider--connections-close-connection, cider--connections-goto-connection, cider--connections-make-default, cider--connections-refresh, cider--connections-refresh-buffer, cider--ewoc-apply-at-point, cider--setup-connection-browser, cider--update-connections-display, cider-client-name-repl-type, cider-connection-browser, cider-connections-buffer-mode, cider-connections-buffer-mode-map cider-connections-close-connection, cider-connections-goto-connection, cider-connections-make-default, cider-display-connected-message, cider-project-name, Renamed: cider-current-session -> cider-nrepl-eval-session cider-current-tooling-session -> cider-nrepl-tooling-session cider-display-connection-info -> cider-describe-current-connection cider-create-sibling-cljs-repl -> cider-connect-sibling-cljs nrepl-connection-buffer-name -> nrepl-repl-buffer-name cider--close-connection-buffer -> cider--close-connection ## repl <> connection overlap cleanup cider-connections -> cider-repls cider-current-connection -> cider-current-repl cider-map-connections -> cider-map-repls cider-connection-type-for-buffer -> cider-repl-type-for-buffer cider-repl-set-type -> cider-set-repl-type
Diffstat (limited to 'cider-mode.el')
-rw-r--r--cider-mode.el140
1 files changed, 61 insertions, 79 deletions
diff --git a/cider-mode.el b/cider-mode.el
index b2ee3cf8..909830e1 100644
--- a/cider-mode.el
+++ b/cider-mode.el
@@ -49,9 +49,8 @@
(defun cider--modeline-info ()
"Return info for the cider mode modeline.
-
Info contains the connection type, project name and host:port endpoint."
- (if-let* ((current-connection (ignore-errors (cider-current-connection))))
+ (if-let* ((current-connection (ignore-errors (cider-current-repl))))
(with-current-buffer current-connection
(concat
cider-repl-type
@@ -86,14 +85,8 @@ variable to nil to disable the mode line entirely."
(defun cider--switch-to-repl-buffer (repl-buffer &optional set-namespace)
"Select the REPL-BUFFER, when possible in an existing window.
-
-Hint: You can use `display-buffer-reuse-frames' and
-`special-display-buffer-names' to customize the frame in which
-the buffer should appear.
-
When SET-NAMESPACE is t, sets the namespace in the REPL buffer to
that of the namespace in the Clojure source buffer."
- (cider-ensure-connected)
(let ((buffer (current-buffer)))
;; first we switch to the REPL buffer
(if cider-repl-display-in-current-window
@@ -107,32 +100,25 @@ that of the namespace in the Clojure source buffer."
(defun cider-switch-to-repl-buffer (&optional set-namespace)
"Select the REPL buffer, when possible in an existing window.
The buffer chosen is based on the file open in the current buffer. If
-multiple REPL buffers are associated with current connection the most
-recent is used.
-
-If the REPL buffer cannot be unambiguously determined, the REPL
-buffer is chosen based on the current connection buffer and a
-message raised informing the user.
+multiple cider sessions are associated with current connection the most
+recent is used. With a prefix arg SET-NAMESPACE sets the namespace in the
+REPL buffer to that of the namespace in the Clojure source buffer
Hint: You can use `display-buffer-reuse-frames' and
`special-display-buffer-names' to customize the frame in which
-the buffer should appear.
-
-With a prefix arg SET-NAMESPACE sets the namespace in the REPL buffer to that
-of the namespace in the Clojure source buffer."
+the buffer should appear."
(interactive "P")
- (let* ((connections (cider-connections))
- (type (cider-connection-type-for-buffer))
+ (let* ((repls (sesman-ensure-linked-session 'CIDER))
+ (type (cider-repl-type-for-buffer))
(a-repl)
- (the-repl (seq-find (lambda (b)
- (when (member b connections)
+ (the-repl (seq-find (lambda (buf)
+ (when (member buf repls)
(unless a-repl
- (setq a-repl b))
- (equal type (cider-connection-type-for-buffer b))))
+ (setq a-repl buf))
+ (equal type (cider-repl-type-for-buffer buf))))
(buffer-list))))
- (if-let* ((repl (or the-repl a-repl)))
- (cider--switch-to-repl-buffer repl set-namespace)
- (user-error "No REPL found"))))
+ (let ((repl (or the-repl a-repl)))
+ (cider--switch-to-repl-buffer repl set-namespace))))
(declare-function cider-load-buffer "cider-interaction")
@@ -153,10 +139,10 @@ Clojure buffer and the REPL buffer."
(interactive)
(if (derived-mode-p 'cider-repl-mode)
(let* ((a-buf)
- (the-buf (let ((repl-type (cider-connection-type-for-buffer)))
+ (the-buf (let ((repl-type (cider-repl-type-for-buffer)))
(seq-find (lambda (b)
(unless (with-current-buffer b (derived-mode-p 'cider-repl-mode))
- (when-let* ((type (cider-connection-type-for-buffer b)))
+ (when-let* ((type (cider-repl-type-for-buffer b)))
(unless a-buf
(setq a-buf b))
(or (equal type "multi")
@@ -171,14 +157,13 @@ Clojure buffer and the REPL buffer."
(defun cider-find-and-clear-repl-output (&optional clear-repl)
"Find the current REPL buffer and clear it.
-With a prefix argument CLEAR-REPL the command clears the entire REPL buffer.
-Returns to the buffer in which the command was invoked.
-
-See also the related commands `cider-repl-clear-buffer' and
+With a prefix argument CLEAR-REPL the command clears the entire REPL
+buffer. Returns to the buffer in which the command was invoked. See also
+the related commands `cider-repl-clear-buffer' and
`cider-repl-clear-output'."
(interactive "P")
(let ((origin-buffer (current-buffer)))
- (switch-to-buffer (cider-current-repl-buffer))
+ (switch-to-buffer (cider-current-repl))
(if clear-repl
(cider-repl-clear-buffer)
(cider-repl-clear-output))
@@ -192,22 +177,18 @@ See also the related commands `cider-repl-clear-buffer' and
:help "Starts an nREPL server (with Leiningen, Boot, or Gradle) and connects a REPL to it."]
["Connect to a REPL" cider-connect
:help "Connects to a REPL that's already running."]
- ["Replicate connection" cider-replicate-connection
- :help "Opens another connection based on a existing one. The new connection uses the same host and port as the base connection."]
- ["Quit" cider-quit :active cider-connections]
- ["Restart" cider-restart :active cider-connections]
+ ["Quit" cider-quit :active (cider-connected-p)]
+ ["Restart" cider-restart :active (cider-connected-p)]
("ClojureScript"
["Start a Clojure REPL, and a ClojureScript REPL" cider-jack-in-clojurescript
:help "Starts an nREPL server, connects a Clojure REPL to it, and then a ClojureScript REPL.
Configure `cider-cljs-repl-types' to change the ClojureScript REPL to use for your build tool."]
["Connect to a ClojureScript REPL" cider-connect-clojurescript
:help "Connects to a ClojureScript REPL that's already running."]
- ["Create a ClojureScript REPL from a Clojure REPL" cider-create-sibling-cljs-repl])
+ ["Create a ClojureScript REPL from a Clojure REPL" cider-jack-in-sibling-clojurescript])
"--"
- ["Connection info" cider-display-connection-info
- :active cider-connections]
- ["Rotate default connection" cider-rotate-default-connection
- :active (cdr cider-connections)]
+ ["Connection info" cider-describe-current-connection
+ :active (cider-connected-p)]
["Select any CIDER buffer" cider-selector]
"--"
["Configure CIDER" (customize-group 'cider)]
@@ -220,14 +201,13 @@ Configure `cider-cljs-repl-types' to change the ClojureScript REPL to use for yo
"--"
["Close ancillary buffers" cider-close-ancillary-buffers
:active (seq-remove #'null cider-ancillary-buffers)]
- ("nREPL" :active cider-connections
- ["Describe session" cider-describe-nrepl-session]
- ["Close session" cider-close-nrepl-session]
+ ("nREPL" :active (cider-connected-p)
+ ["Describe nrepl session" cider-describe-nrepl-session]
["Toggle message logging" nrepl-toggle-message-logging]))
"Menu for CIDER mode.")
(defconst cider-mode-eval-menu
- '("CIDER Eval" :visible cider-connections
+ '("CIDER Eval" :visible (cider-connected-p)
["Eval top-level sexp" cider-eval-defun-at-point]
["Eval top-level sexp to point" cider-eval-defun-to-point]
["Eval current sexp" cider-eval-sexp-at-point]
@@ -262,7 +242,7 @@ Configure `cider-cljs-repl-types' to change the ClojureScript REPL to use for yo
"Menu for CIDER mode eval commands.")
(defconst cider-mode-interactions-menu
- `("CIDER Interactions" :visible cider-connections
+ `("CIDER Interactions" :visible (cider-connected-p)
["Complete symbol" complete-symbol]
"--"
("REPL"
@@ -355,8 +335,7 @@ Configure `cider-cljs-repl-types' to change the ClojureScript REPL to use for yo
(define-key map (kbd "C-c ,") 'cider-test-commands-map)
(define-key map (kbd "C-c C-t") 'cider-test-commands-map)
(define-key map (kbd "C-c M-s") #'cider-selector)
- (define-key map (kbd "C-c M-r") #'cider-rotate-default-connection)
- (define-key map (kbd "C-c M-d") #'cider-display-connection-info)
+ (define-key map (kbd "C-c M-d") #'cider-describe-current-connection)
(define-key map (kbd "C-c C-=") #'cider-profile-map)
(define-key map (kbd "C-c C-x") #'cider-refresh)
(define-key map (kbd "C-c C-q") #'cider-quit)
@@ -507,35 +486,38 @@ Search is done with the given LIMIT."
(set-match-data md)
t))))))))
-(defun cider--anchored-search-suppressed-forms-internal (limit)
+(defun cider--anchored-search-suppressed-forms-internal (repl-types limit)
"Helper function for `cider--anchored-search-suppressed-forms`.
-LIMIT is the same as the LIMIT in `cider--anchored-search-suppressed-forms`"
- (let ((types (cider-project-connections-types)))
- (when (= (length types) 1)
- (let ((type (car types))
- (expr (read (current-buffer)))
- (start (save-excursion (backward-sexp) (point))))
- (when (<= (point) limit)
- (forward-sexp)
- (if (not (string-equal (symbol-name expr) (concat ":" type)))
- (ignore-errors
- (cl-assert (<= (point) limit))
- (let ((md (match-data nil cider--reader-conditionals-match-data)))
- (setf (nth 0 md) start)
- (setf (nth 1 md) (point))
- (set-match-data md)
- t))
- (cider--anchored-search-suppressed-forms-internal limit)))))))
+REPL-TYPES is a list of strings repl-type strings. LIMIT is the same as
+the LIMIT in `cider--anchored-search-suppressed-forms`"
+ (when (= (length repl-types) 1)
+ (let ((type (car repl-types))
+ (expr (read (current-buffer)))
+ (start (save-excursion (backward-sexp) (point))))
+ (when (<= (point) limit)
+ (forward-sexp)
+ (if (not (string-equal (symbol-name expr) (concat ":" type)))
+ (ignore-errors
+ (cl-assert (<= (point) limit))
+ (let ((md (match-data nil cider--reader-conditionals-match-data)))
+ (setf (nth 0 md) start)
+ (setf (nth 1 md) (point))
+ (set-match-data md)
+ t))
+ (cider--anchored-search-suppressed-forms-internal repl-types limit))))))
(defun cider--anchored-search-suppressed-forms (limit)
"Matcher for finding unused reader conditional expressions.
An unused reader conditional expression is an expression for a platform
that does not match the CIDER connection for the buffer. Search is done
with the given LIMIT."
- (let ((result 'retry))
+ (let ((repl-types (seq-uniq (seq-map #'cider-repl-type (cider-repls))))
+ (result 'retry))
(while (and (eq result 'retry) (<= (point) limit))
- (condition-case condition
- (setq result (cider--anchored-search-suppressed-forms-internal limit))
+ (condition-case-unless-debug condition
+ (setq result
+ (cider--anchored-search-suppressed-forms-internal
+ repl-types limit))
(invalid-read-syntax
(setq result 'retry))
(wrong-type-argument
@@ -546,12 +528,9 @@ with the given LIMIT."
(setq result nil))
(error
(setq result nil)
- (display-warning
- '(cider warning)
- (format
- (concat "Caught error during fontification while searching for forms\n"
- "that are suppressed by reader-conditionals. The error was: %S.")
- condition)))))
+ (message
+ "Error during fontification while searching for forms: %S"
+ condition))))
(if (eq result 'retry) (setq result nil))
result))
@@ -812,7 +791,8 @@ SYM and INFO is passed to `cider-docview-render'"
"Return the help-echo string for OBJ at POS.
See \(info \"(elisp) Special Properties\")"
(while-no-input
- (when (and (bufferp obj) (cider-connected-p)
+ (when (and (bufferp obj)
+ (cider-connected-p)
cider-use-tooltips (not help-at-pt-display-when-idle))
(with-current-buffer obj
(ignore-errors
@@ -860,6 +840,7 @@ property."
cider-mode-map
(if cider-mode
(progn
+ (setq-local sesman-system 'CIDER)
(cider-eldoc-setup)
(make-local-variable 'completion-at-point-functions)
(add-to-list 'completion-at-point-functions
@@ -879,7 +860,8 @@ property."
(setq-local clojure-get-indent-function #'cider--get-symbol-indent))
(setq-local clojure-expected-ns-function #'cider-expected-ns)
(setq next-error-function #'cider-jump-to-compilation-error))
- (mapc #'kill-local-variable '(completion-at-point-functions
+ (mapc #'kill-local-variable '(sesman-system
+ completion-at-point-functions
next-error-function
x-gtk-use-system-tooltips
font-lock-fontify-region-function