Skip to content

Commit

Permalink
First attempt at dynamic registrations
Browse files Browse the repository at this point in the history
Per #363.

* eglot.el (eglot-register-capability)
(eglot-unregister-capability): Actually implement instead of warning.
(eglot-client-capabilities): Allow dynamicRegistration in many
capabilities.
(eglot-lsp-server): Add dynamic-capabilities slot.
(eglot--connect): use only initial-capabilities slot.
(eglot--capability-keyword): New helper.
(eglot--server-capable): use eglot--dynamic-capabilities.
  • Loading branch information
joaotavora committed Dec 9, 2019
1 parent add568b commit eb89f68
Showing 1 changed file with 38 additions and 20 deletions.
58 changes: 38 additions & 20 deletions eglot.el
Original file line number Diff line number Diff line change
Expand Up @@ -456,16 +456,21 @@ treated as in `eglot-dbind'."
(cl-defgeneric eglot-register-capability (server method id &rest params)
"Ask SERVER to register capability METHOD marked with ID."
(:method
(_s method _id &rest _params)
(eglot--warn "Server tried to register unsupported capability `%s'"
method)))
(server method _id &rest params)
(cl-pushnew `(,(eglot--capability-keyword method) (,@params))
(eglot--dynamic-capabilities server)
:key #'car)
(eglot--message "Server registers capability `%s'" method)))

(cl-defgeneric eglot-unregister-capability (server method id &rest params)
"Ask SERVER to register capability METHOD marked with ID."
(:method
(_s method _id &rest _params)
(eglot--warn "Server tried to unregister unsupported capability `%s'"
method)))
(server method _id &rest _params)
(setf (eglot--dynamic-capabilities server)
(cl-delete (eglot--capability-keyword method)
(eglot--dynamic-capabilities server)
:key #'car))
(eglot--message "Server unregisters capability `%s'" method)))

(cl-defgeneric eglot-client-capabilities (server)
"What the EGLOT LSP client supports for SERVER."
Expand Down Expand Up @@ -496,17 +501,17 @@ treated as in `eglot-dbind'."
:signatureInformation
`(:parameterInformation
(:labelOffsetSupport t)))
:references `(:dynamicRegistration :json-false)
:definition `(:dynamicRegistration :json-false)
:declaration `(:dynamicRegistration :json-false)
:implementation `(:dynamicRegistration :json-false)
:typeDefinition `(:dynamicRegistration :json-false)
:references `()
:definition `()
:declaration `()
:implementation `()
:typeDefinition `()
:documentSymbol (list
:dynamicRegistration :json-false
:symbolKind `(:valueSet
[,@(mapcar
#'car eglot--symbol-kind-names)]))
:documentHighlight `(:dynamicRegistration :json-false)
:documentHighlight `()
:codeAction (list
:dynamicRegistration :json-false
:codeActionLiteralSupport
Expand All @@ -516,9 +521,9 @@ treated as in `eglot-dbind'."
"refactor" "refactor.extract"
"refactor.inline" "refactor.rewrite"
"source" "source.organizeImports"])))
:formatting `(:dynamicRegistration :json-false)
:rangeFormatting `(:dynamicRegistration :json-false)
:rename `(:dynamicRegistration :json-false)
:formatting `()
:rangeFormatting `()
:rename `()
:publishDiagnostics `(:relatedInformation :json-false))
:experimental (list))))

Expand All @@ -530,8 +535,12 @@ treated as in `eglot-dbind'."
:documentation "Major mode symbol."
:accessor eglot--major-mode)
(capabilities
:documentation "JSON object containing server capabilities."
:accessor eglot--capabilities)
:documentation "JSON object of server capabilities."
:accessor eglot--initial-capabilities)
(dynamic-capabilities
:documentation "JSON object of dynamically added server capabilities."
:initform nil
:accessor eglot--dynamic-capabilities)
(server-info
:documentation "JSON object containing server info."
:accessor eglot--server-info)
Expand Down Expand Up @@ -862,11 +871,14 @@ This docstring appeases checkdoc, that's all."
server)
:capabilities (eglot-client-capabilities server))
:success-fn
(eglot--lambda ((InitializeResult) capabilities serverInfo)
(eglot--lambda ((InitializeResult)
capabilities
serverInfo)
(unless cancelled
(push server
(gethash project eglot--servers-by-project))
(setf (eglot--capabilities server) capabilities)
(setf (eglot--initial-capabilities server)
capabilities)
(setf (eglot--server-info server) serverInfo)
(jsonrpc-notify server :initialized (make-hash-table))
(dolist (buffer (buffer-list))
Expand Down Expand Up @@ -978,6 +990,9 @@ CONNECT-ARGS are passed as additional arguments to

;;; Helpers (move these to API?)
;;;
(defun eglot--capability-keyword (method)
(intern (format ":%s" (cadr (split-string (format "%s" method) "/")))))

(defun eglot--error (format &rest args)
"Error out with FORMAT with ARGS."
(error "[eglot] %s" (apply #'format format args)))
Expand Down Expand Up @@ -1139,7 +1154,10 @@ under cursor."
(unless (cl-some (lambda (feat)
(memq feat eglot-ignored-server-capabilites))
feats)
(cl-loop for caps = (eglot--capabilities (eglot--current-server-or-lose))
(cl-loop with server = (eglot--current-server-or-lose)
for caps = (append
(eglot--dynamic-capabilities server)
(eglot--initial-capabilities server))
then (cadr probe)
for (feat . more) on feats
for probe = (plist-member caps feat)
Expand Down

0 comments on commit eb89f68

Please sign in to comment.