[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/eglot 17a3257 03/24: Do Rust's RLS hack properly with n
From: |
João Távora |
Subject: |
[elpa] externals/eglot 17a3257 03/24: Do Rust's RLS hack properly with new class-based API |
Date: |
Sat, 26 May 2018 14:31:13 -0400 (EDT) |
branch: externals/eglot
commit 17a3257e08d3486bc3859fb6423f3611bab47168
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>
Do Rust's RLS hack properly with new class-based API
* eglot.el (eglot-server-ready-p): New API method.
(eglot-handle-request, eglot-handle-notification): New
defgeneric's.
(eglot--ready-predicates, eglot--server-ready-p): Remove.
(eglot--async-request): Call eglot-server-ready-p.
(eglot--request): Tweak comment.
(eglot--rls-probably-ready-for-p): Remove.
(eglot-server-ready-p eglot-rls): Adapts earlier
eglot--rls-probably-ready-for-p.
(eglot-handle-notification eglot-rls): Specialize to eglot-rls.
(eglot-rls): New eglot-lsp-server subclass.
* eglot-tests.el (auto-detect-running-server)
(auto-reconnect, basic-completions)
(hover-after-completions): Use eglot--interactive
---
eglot-tests.el | 14 ++++----------
eglot.el | 61 ++++++++++++++++++++++++++++++----------------------------
2 files changed, 36 insertions(+), 39 deletions(-)
diff --git a/eglot-tests.el b/eglot-tests.el
index f59760c..44bf090 100644
--- a/eglot-tests.el
+++ b/eglot-tests.el
@@ -121,9 +121,7 @@
(eglot--with-test-timeout 2
(with-current-buffer
(eglot--find-file-noselect "project/coiso.rs")
- (setq server
- (eglot 'rust-mode `(transient . ,default-directory)
- '("rls") 'eglot-lsp-server))
+ (should (setq server (apply #'eglot (eglot--interactive))))
(should (eglot--current-server)))
(with-current-buffer
(eglot--find-file-noselect "project/merdix.rs")
@@ -143,9 +141,7 @@
(eglot--with-test-timeout 3
(with-current-buffer
(eglot--find-file-noselect "project/coiso.rs")
- (setq server
- (eglot 'rust-mode `(transient . ,default-directory)
- '("rls") 'eglot-lsp-server))
+ (should (setq server (apply #'eglot (eglot--interactive))))
;; In 1.2 seconds > `eglot-autoreconnect' kill servers. We
;; should have a automatic reconnection.
(run-with-timer 1.2 nil (lambda () (delete-process
@@ -169,8 +165,7 @@
(eglot--with-test-timeout 4
(with-current-buffer
(eglot--find-file-noselect "project/something.py")
- (eglot 'python-mode `(transient . ,default-directory) '("pyls")
- 'eglot-lsp-server)
+ (should (apply #'eglot (eglot--interactive)))
(goto-char (point-max))
(completion-at-point)
(should (looking-back "sys.exit"))))))
@@ -183,8 +178,7 @@
(eglot--with-test-timeout 4
(with-current-buffer
(eglot--find-file-noselect "project/something.py")
- (eglot 'python-mode `(transient . ,default-directory) '("pyls")
- 'eglot-lsp-server)
+ (should (apply #'eglot (eglot--interactive)))
(goto-char (point-max))
(setq eldoc-last-message nil)
(completion-at-point)
diff --git a/eglot.el b/eglot.el
index cb213e5..43cda1b 100644
--- a/eglot.el
+++ b/eglot.el
@@ -68,7 +68,7 @@
:prefix "eglot-"
:group 'applications)
-(defvar eglot-server-programs '((rust-mode . ("rls"))
+(defvar eglot-server-programs '((rust-mode . (eglot-rls "rls"))
(python-mode . ("pyls"))
(js-mode . ("javascript-typescript-stdio"))
(sh-mode . ("bash-language-server" "start"))
@@ -113,6 +113,23 @@ lasted more than that many seconds."
(integer :tag "Number of seconds")))
+;;; API
+;;;
+(cl-defgeneric eglot-server-ready-p (server what) ;; API
+ "Tell if SERVER is ready for WHAT in current buffer.
+If it isn't, a deferrable `eglot--async-request' *will* be
+deferred to the future."
+ (:method (_s _what)
+ "Normally not ready if outstanding changes."
+ (not (eglot--outstanding-edits-p))))
+
+(cl-defgeneric eglot-handle-request (server method id &rest params)
+ "Handle SERVER's METHOD request with ID and PARAMS.")
+
+(cl-defgeneric eglot-handle-notification (server method id &rest params)
+ "Handle SERVER's METHOD notification with PARAMS.")
+
+
;;; Process management
(defvar eglot--servers-by-project (make-hash-table :test #'equal)
"Keys are projects. Values are lists of processes.")
@@ -619,16 +636,6 @@ originated."
(eglot--log-event server `(:running-deferred ,(length actions)))
(mapc #'funcall (mapcar #'car actions))))
-(defvar eglot--ready-predicates '(eglot--server-ready-p)
- "Special hook of predicates controlling deferred actions.
-If one of these returns nil, a deferrable `eglot--async-request'
-will be deferred. Each predicate is passed the symbol for the
-request request and a process object.")
-
-(defun eglot--server-ready-p (_what _server)
- "Tell if SERVER is ready for processing deferred WHAT."
- (not (eglot--outstanding-edits-p)))
-
(cl-defmacro eglot--lambda (cl-lambda-list &body body)
(declare (indent 1) (debug (sexp &rest form)))
(let ((e (gensym "eglot--lambda-elem")))
@@ -668,8 +675,7 @@ TIMER)."
(existing (gethash (list deferred buf)
(eglot--deferred-actions server))))
(when existing (setq existing (cadr existing)))
- (if (run-hook-with-args-until-failure 'eglot--ready-predicates
- deferred server)
+ (if (eglot-server-ready-p server deferred)
(remhash (list deferred buf) (eglot--deferred-actions server))
(eglot--log-event server `(:deferring ,method :id ,id :params
,params))
(let* ((buf (current-buffer)) (point (point))
@@ -708,9 +714,9 @@ TIMER)."
"Like `eglot--async-request' for SERVER, METHOD and PARAMS, but synchronous.
Meaning only return locally if successful, otherwise exit non-locally.
DEFERRED is passed to `eglot--async-request', which see."
- ;; Launching a deferred sync request with outstanding changes is a
- ;; bad idea, since that might lead to the request never having a
- ;; chance to run, because `eglot--ready-predicates'.
+ ;; HACK: A deferred sync request with outstanding changes is a bad
+ ;; idea, since that might lead to the request never having a chance
+ ;; to run, because idle timers don't run in `accept-process-output'.
(when deferred (eglot--signal-textDocument/didChange))
(let* ((done (make-symbol "eglot-catch")) id-and-timer
(res
@@ -1583,22 +1589,19 @@ Proceed? "
;;; Rust-specific
;;;
-(defun eglot--rls-probably-ready-for-p (what server)
- "Guess if the RLS running in SERVER is ready for WHAT."
- (or (eq what :textDocument/completion) ; RLS normally ready for this
- ; one, even if building ;
- (pcase-let ((`(,_id ,what ,done ,_detail) (eglot--spinner server)))
- (and (equal "Indexing" what) done))))
+(defclass eglot-rls (eglot-lsp-server) () :documentation "Rustlang's RLS.")
-;;;###autoload
-(progn
- (add-hook 'rust-mode-hook 'eglot--setup-rls-idiosyncrasies)
- (defun eglot--setup-rls-idiosyncrasies ()
- "Prepare `eglot' to deal with RLS's special treatment."
- (add-hook 'eglot--ready-predicates 'eglot--rls-probably-ready-for-p t t)))
+(cl-defmethod eglot-server-ready-p ((server eglot-rls) what)
+ "Except for :completion, RLS isn't ready until Indexing done."
+ (and (cl-call-next-method)
+ (or ;; RLS normally ready for this, even if building.
+ (eq :textDocument/completion what)
+ (pcase-let ((`(,_id ,what ,done ,_detail) (eglot--spinner server)))
+ (and (equal "Indexing" what) done)))))
(cl-defmethod eglot-handle-notification
- (server (_method (eql :window/progress)) &key id done title message
&allow-other-keys)
+ ((server eglot-rls) (_method (eql :window/progress))
+ &key id done title message &allow-other-keys)
"Handle notification window/progress"
(setf (eglot--spinner server) (list id title done message))
(when (and (equal "Indexing" title) done)
- [elpa] externals/eglot updated (24877ae -> 897cbc3), João Távora, 2018/05/26
- [elpa] externals/eglot d673cf7 07/24: Increase test timeout in hopes of convincing Travis CI, João Távora, 2018/05/26
- [elpa] externals/eglot 89baadf 05/24: Fix indentation broken by the defclass monster commit, João Távora, 2018/05/26
- [elpa] externals/eglot 1ef8228 01/24: Introduce eglot-handle-request and eglot-handle-notification as API, João Távora, 2018/05/26
- [elpa] externals/eglot 3a1ff72 04/24: Introduce new API methods for experimental clients to use, João Távora, 2018/05/26
- [elpa] externals/eglot 9c87771 12/24: Introduce eglot--debug for unimportant messages, João Távora, 2018/05/26
- [elpa] externals/eglot 8d4c2c3 13/24: Demote unvisited diagnostics logging to debug level, João Távora, 2018/05/26
- [elpa] externals/eglot 85c5353 11/24: Add cquery support for C/C++ projects, João Távora, 2018/05/26
- [elpa] externals/eglot d40a458 14/24: Log debug messages through eglot--debug, João Távora, 2018/05/26
- [elpa] externals/eglot 17a3257 03/24: Do Rust's RLS hack properly with new class-based API,
João Távora <=
- [elpa] externals/eglot 3aa2958 06/24: Add a complex RLS test, João Távora, 2018/05/26
- [elpa] externals/eglot 07078da 08/24: Rework eglot-tests.el for better debuggability, João Távora, 2018/05/26
- [elpa] externals/eglot 0462130 15/24: New RLS tests, João Távora, 2018/05/26
- [elpa] externals/eglot e1d7ff3 09/24: Disable file-watching tests on Travis, João Távora, 2018/05/26
- [elpa] externals/eglot c8e7ab0 16/24: Don't rely on Flymake's idle timer for textDocument/didChange, João Távora, 2018/05/26
- [elpa] externals/eglot 99ca690 17/24: Simpify eglot--server-receive, João Távora, 2018/05/26
- [elpa] externals/eglot 1b5ed29 21/24: Really ensure eglot--shutdown deletes a process completely, João Távora, 2018/05/26
- [elpa] externals/eglot 897cbc3 24/24: * eglot.el (Version): Bump to 0.5, João Távora, 2018/05/26
- [elpa] externals/eglot ec10de2 23/24: Another unstable test on Travis, João Távora, 2018/05/26
- [elpa] externals/eglot d0fb9d2 22/24: Merge branch 'cquery-support' into master, João Távora, 2018/05/26