[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/eglot 6531c8b 58/69: Merge branch 'master' into jsonrpc
From: |
João Távora |
Subject: |
[elpa] externals/eglot 6531c8b 58/69: Merge branch 'master' into jsonrpc-refactor |
Date: |
Fri, 22 Jun 2018 11:55:04 -0400 (EDT) |
branch: externals/eglot
commit 6531c8b208736c9f30f829608791deaa44a9160f
Merge: 7371f68 1506172
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>
Merge branch 'master' into jsonrpc-refactor
---
eglot-tests.el | 19 +++++++-----
eglot.el | 94 +++++++++++++++++++++++++++++++++++++---------------------
2 files changed, 72 insertions(+), 41 deletions(-)
diff --git a/eglot-tests.el b/eglot-tests.el
index 56ec980..b57b949 100644
--- a/eglot-tests.el
+++ b/eglot-tests.el
@@ -181,6 +181,9 @@ Pass TIMEOUT to `eglot--with-timeout'."
(define-derived-mode rust-mode prog-mode "Rust"))
(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode))
+(defun eglot--tests-connect ()
+ (apply #'eglot--connect (eglot--guess-contact)))
+
(ert-deftest auto-detect-running-server ()
"Visit a file and M-x eglot, then visit a neighbour. "
(skip-unless (executable-find "rls"))
@@ -192,7 +195,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
(eglot--with-timeout 2
(with-current-buffer
(eglot--find-file-noselect "project/coiso.rs")
- (should (setq server (apply #'eglot (eglot--interactive))))
+ (should (setq server (eglot--tests-connect)))
(should (eglot--current-server)))
(with-current-buffer
(eglot--find-file-noselect "project/merdix.rs")
@@ -212,7 +215,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
(eglot--with-timeout 3
(with-current-buffer
(eglot--find-file-noselect "project/coiso.rs")
- (should (setq server (apply #'eglot (eglot--interactive))))
+ (should (setq server (eglot--tests-connect)))
;; In 1.2 seconds > `eglot-autoreconnect' kill servers. We
;; should have a automatic reconnection.
(run-with-timer 1.2 nil (lambda () (delete-process
@@ -244,7 +247,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
:client-notifications c-notifs
:client-replies c-replies
)
- (should (apply #'eglot (eglot--interactive)))
+ (should (eglot--tests-connect))
(let (register-id)
(eglot--wait-for (s-requests 1)
(&key id method &allow-other-keys)
@@ -274,7 +277,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
(eglot--find-file-noselect "diag-project/main.rs")
(should (zerop (shell-command "cargo init")))
(eglot--sniffing (:server-notifications s-notifs)
- (apply #'eglot (eglot--interactive))
+ (eglot--tests-connect)
(eglot--wait-for (s-notifs 1)
(&key _id method &allow-other-keys)
(string= method 'textDocument/publishDiagnostics))
@@ -304,7 +307,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
:client-replies c-replies
:client-requests c-reqs
)
- (apply #'eglot (eglot--interactive))
+ (eglot--tests-connect)
(goto-char (point-min))
(search-forward "return te")
(insert "st")
@@ -342,7 +345,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
:client-replies c-replies
:client-requests c-reqs
)
- (apply #'eglot (eglot--interactive))
+ (eglot--tests-connect)
(goto-char (point-min)) (search-forward "return te")
(eglot-rename "bla")
(should (equal (buffer-string) "fn test() -> i32 { let bla=3; return
bla; }")))))))
@@ -355,7 +358,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
(eglot--with-timeout 4
(with-current-buffer
(eglot--find-file-noselect "project/something.py")
- (should (apply #'eglot (eglot--interactive)))
+ (should (eglot--tests-connect))
(goto-char (point-max))
(completion-at-point)
(should (looking-back "sys.exit"))))))
@@ -368,7 +371,7 @@ Pass TIMEOUT to `eglot--with-timeout'."
(eglot--with-timeout 4
(with-current-buffer
(eglot--find-file-noselect "project/something.py")
- (should (apply #'eglot (eglot--interactive)))
+ (should (eglot--tests-connect))
(goto-char (point-max))
(setq eldoc-last-message nil)
(completion-at-point)
diff --git a/eglot.el b/eglot.el
index 32879ec..0a060a5 100644
--- a/eglot.el
+++ b/eglot.el
@@ -46,6 +46,13 @@
;; To "unmanage" these buffers, shutdown the server with M-x
;; eglot-shutdown.
;;
+;; You can also do:
+;;
+;; (add-hook 'foo-mode-hook 'eglot-ensure)
+;;
+;; To attempt to start an eglot session automatically everytime a
+;; foo-mode buffer is visited.
+;;
;;; Code:
(require 'json)
@@ -255,8 +262,10 @@ function with the server still running."
(defvar eglot--command-history nil
"History of CONTACT arguments to `eglot'.")
-(defun eglot--interactive ()
- "Helper for `eglot'."
+(defun eglot--guess-contact (&optional interactive)
+ "Helper for `eglot'.
+Return (MANAGED-MODE PROJECT CONTACT CLASS).
+If INTERACTIVE, maybe prompt user."
(let* ((guessed-mode (if buffer-file-name major-mode))
(managed-mode
(cond
@@ -274,17 +283,20 @@ function with the server still running."
(prog1 (car guess) (setq guess (cdr guess)))
'eglot-lsp-server))
(program (and (listp guess) (stringp (car guess)) (car guess)))
- (base-prompt "[eglot] Enter program to execute (or <host>:<port>): ")
+ (base-prompt
+ (and interactive
+ "[eglot] Enter program to execute (or <host>:<port>): "))
(prompt
- (cond (current-prefix-arg base-prompt)
- ((null guess)
- (format "[eglot] Sorry, couldn't guess for `%s'\n%s!"
- managed-mode base-prompt))
- ((and program (not (executable-find program)))
- (concat (format "[eglot] I guess you want to run `%s'"
- (combine-and-quote-strings guess))
- (format ", but I can't find `%s' in PATH!" program)
- "\n" base-prompt))))
+ (and base-prompt
+ (cond (current-prefix-arg base-prompt)
+ ((null guess)
+ (format "[eglot] Sorry, couldn't guess for `%s'!\n%s"
+ managed-mode base-prompt))
+ ((and program (not (executable-find program)))
+ (concat (format "[eglot] I guess you want to run `%s'"
+ (combine-and-quote-strings guess))
+ (format ", but I can't find `%s' in PATH!"
program)
+ "\n" base-prompt)))))
(contact
(if prompt
(let ((s (read-shell-command
@@ -296,7 +308,7 @@ function with the server still running."
(list (match-string 1 s) (string-to-number (match-string 2
s)))
(split-string-and-unquote s)))
guess)))
- (list managed-mode project class contact t)))
+ (list managed-mode project class contact)))
;;;###autoload
(defun eglot (managed-major-mode project class contact &optional interactive)
@@ -327,26 +339,22 @@ keyword-value plist used to initialize CLASS or a plain
list as
described in `eglot-server-programs', which see.
INTERACTIVE is t if called interactively."
- (interactive (eglot--interactive))
- (let* ((nickname (file-name-base (directory-file-name
- (car (project-roots project)))))
- (current-server (eglot--current-server))
+ (interactive (append (eglot--guess-contact t) '(t)))
+ (let* ((current-server (eglot--current-server))
(live-p (and current-server (jsonrpc-running-p current-server))))
(if (and live-p
interactive
(y-or-n-p "[eglot] Live process found, reconnect instead? "))
(eglot-reconnect current-server interactive)
(when live-p (ignore-errors (eglot-shutdown current-server)))
- (let ((server (eglot--connect project
- managed-major-mode
- (format "%s/%s" nickname
managed-major-mode)
- nickname
+ (let ((server (eglot--connect managed-major-mode
+ project
class
contact)))
(eglot--message "Connected! Process `%s' now \
managing `%s' buffers in project `%s'."
(jsonrpc-name server) managed-major-mode
- nickname)
+ (eglot--project-nickname server))
server))))
(defun eglot-reconnect (server &optional interactive)
@@ -355,14 +363,34 @@ INTERACTIVE is t if called interactively."
(interactive (list (eglot--current-server-or-lose) t))
(when (jsonrpc-running-p server)
(ignore-errors (eglot-shutdown server interactive)))
- (eglot--connect (eglot--project server)
- (eglot--major-mode server)
- (jsonrpc-name server)
- (eglot--project-nickname server)
+ (eglot--connect (eglot--major-mode server)
+ (eglot--project server)
(eieio-object-class-name server)
(eglot--saved-initargs server))
(eglot--message "Reconnected!"))
+(defvar eglot--managed-mode) ; forward decl
+
+(defun eglot-ensure ()
+ "Start Eglot session for current buffer if there isn't one."
+ (let ((buffer (current-buffer)))
+ (cl-labels
+ ((maybe-connect
+ ()
+ (remove-hook 'post-command-hook #'maybe-connect nil)
+ (eglot--with-live-buffer buffer
+ (if eglot--managed-mode
+ (eglot--message "%s is already managed by existing `%s'"
+ buffer
+ (eglot--project-nickname
(eglot--current-server)))
+ (let ((server (apply #'eglot--connect (eglot--guess-contact))))
+ (eglot--message
+ "Automatically started `%s' to manage `%s' buffers in project
`%s'"
+ (eglot--project-nickname server)
+ major-mode
+ (eglot--project-nickname server)))))))
+ (add-hook 'post-command-hook #'maybe-connect 'append nil))))
+
(defun eglot-events-buffer (server)
"Display events buffer for SERVER."
(interactive (eglot--current-server-or-lose))
@@ -380,12 +408,12 @@ INTERACTIVE is t if called interactively."
(defvar eglot-connect-hook nil "Hook run after connecting in
`eglot--connect'.")
-(defun eglot--connect (project managed-major-mode name nickname
- class contact)
- "Connect to PROJECT, MANAGED-MAJOR-MODE, NAME.
-And don't forget NICKNAME and CLASS, CONTACT. This docstring
-appeases checkdoc, that's all."
- (let* ((readable-name (format "EGLOT (%s/%s)" nickname managed-major-mode))
+(defun eglot--connect (managed-major-mode project class contact)
+ "Connect to MANAGED-MAJOR-MODE, PROJECT, CLASS and CONTACT.
+This docstring appeases checkdoc, that's all."
+ (let* ((nickname (file-name-base (directory-file-name
+ (car (project-roots project)))))
+ (readable-name (format "EGLOT (%s/%s)" nickname managed-major-mode))
(initargs
(cond ((keywordp (car contact)) contact)
((integerp (cadr contact))
@@ -410,7 +438,7 @@ appeases checkdoc, that's all."
(server
(apply
#'make-instance class
- :name name
+ :name readable-name
:notification-dispatcher (funcall spread
#'eglot-handle-notification)
:request-dispatcher (funcall spread #'eglot-handle-request)
:on-shutdown #'eglot--on-shutdown
- [elpa] externals/eglot 2917214 47/69: Merge master into jsonrpc-refactor, (continued)
- [elpa] externals/eglot 2917214 47/69: Merge master into jsonrpc-refactor, João Távora, 2018/06/22
- [elpa] externals/eglot f730fff 48/69: Merge branch 'master' into jsonrpc-refactor, João Távora, 2018/06/22
- [elpa] externals/eglot aaca7de 60/69: Fix ridiculous bug, João Távora, 2018/06/22
- [elpa] externals/eglot d87f4bf 55/69: jsonrpc--log-event should also be private, João Távora, 2018/06/22
- [elpa] externals/eglot a65d3f4 53/69: Make message and warning helpers private, João Távora, 2018/06/22
- [elpa] externals/eglot 9e9dc57 30/69: Merge branch 'master' into jsonrpc-refactor (using regular merge), João Távora, 2018/06/22
- [elpa] externals/eglot 6c9d41e 38/69: Add reasonably sophisticated deferred action tests, João Távora, 2018/06/22
- [elpa] externals/eglot 2da7d92 50/69: Simplify JSONRPC status setting, João Távora, 2018/06/22
- [elpa] externals/eglot 69a622a 64/69: Fix some typos, João Távora, 2018/06/22
- [elpa] externals/eglot 7371f68 57/69: * jsonrpc.el: Rewrite commentary., João Távora, 2018/06/22
- [elpa] externals/eglot 6531c8b 58/69: Merge branch 'master' into jsonrpc-refactor,
João Távora <=
- [elpa] externals/eglot 59cc3fb 61/69: jsonrpc-connection-receive is now a public convenience function, João Távora, 2018/06/22
- [elpa] externals/eglot d371f05 49/69: Request dispatcher's return value determines response, João Távora, 2018/06/22
- [elpa] externals/eglot 0f20fdf 68/69: Tiny README.md change, João Távora, 2018/06/22
- [elpa] externals/eglot cef3c29 22/69: Heroically merge master into jsonrpc-refactor (using imerge), João Távora, 2018/06/22
- [elpa] externals/eglot a4441c6 37/69: Merge master into jsonrpc-refactor (using imerge), João Távora, 2018/06/22
- [elpa] externals/eglot 0e44b27 27/69: jsonrpc.el uses classes and generic functions, João Távora, 2018/06/22
- [elpa] externals/eglot 856a224 62/69: Simplify jsonrpc-connection-send, João Távora, 2018/06/22
- [elpa] externals/eglot 1f09fd3 59/69: Review commentary section before another review cycle, João Távora, 2018/06/22
- [elpa] externals/eglot 8fda30c 67/69: Merge master into jsonrpc-refactor (using imerge), João Távora, 2018/06/22
- [elpa] externals/eglot 7f4e273 31/69: Merge master into jsonrpc-refactor (using imerge), João Távora, 2018/06/22