Giter Site home page Giter Site logo

eglot's Introduction

Build status GNU ELPA MELPA

M-x Eglot

Emacs Polyglot is the Emacs LSP client that stays out of your way:

See also eglot-x for non-standard protocol extensions support.

Get stable GNU ELPA version

Just type M-x package-install RET eglot RET into Emacs 26.3+.

Now find some source file, any source file, and type M-x eglot.

That's it. If you're lucky, this guesses the LSP program to start for the language you're using. Otherwise, it prompts you to enter one.

Get latest development version from GNU-Devel ELPA

First, configure this repository.

(add-to-list 'package-archives '("gnu-devel" . "https://elpa.gnu.org/devel/"))

Then, use M-x package-install or M-x package-update to install an ELPA package from the latest upstream.

Contribute to Eglot's development

Eglot is now in Emacs's core! Upcoming Emacs 29 will have M-x eglot built-in.

The recommended way to experiment with changes to the latest Eglot is to compile Emacs yourself.

From a development perspective, moving to core allows us to work on Eglot in tandem with other related packages already in Emacs, such as Flymake, ElDoc, Xref, Project.

This means adding or tweaking an Emacs LSP feature is a matter of submitting a single patch targetting multiple relevant packages, not just Eglot.

These :core packages (Eglot included) are then released periodically to GNU ELPA, so users of other Emacs's versions can get them via M-x package-install.

Status of this GitHub repository

This repository is not the development upstream anymore, but it's not dead (yet):

Connecting to a server

These are just some of the servers that M-x eglot can use out of the box. The full list can be consulted in the eglot-server-programs variable, where you can easily add your own servers.

Obligatory animated gif section

Completion

eglot-completions

The animation shows company-mode presenting the completion candidates to the user, but Eglot works with the built-in completion-at-point function as well, which is usually bound to C-M-i.

Snippet completion

eglot-snippets-on-completion

Eglot provides template based completion if the server supports snippet completion and yasnippet is enabled before Eglot connects to the server. The animation shows company-mode, but completion-at-point also works with snippets.

Diagnostics

eglot-diagnostics

Eglot relays the diagnostics information received from the LSP server to Emacs's Flymake, which annotates/underlines the problematic parts of the buffer. The information is shared with the ElDoc system, meaning that the commands eldoc and eldoc-doc-buffer (the latter bound to C-h-. for convenience) show diagnostics along with other documentation under point.

Flymake provides other convenient ways to view and manage diagnostic errors. These are described in its manual.

When Eglot manages a buffer, it disables pre-existing Flymake backends. See variable eglot-stay-out-of to change that.

Code Actions

eglot-code-actions

The LSP server may provide code actions, for example, to fix a diagnostic error or to suggest refactoring edits. The commands are frequently associating with Flymake diagnostic annotations, so that left-clicking them shows a menu. Additionally, the command eglot-code-actions asks the server for any code spanning a given region.

Sometimes, these code actions are initiated by the server. See eglot-confirm-server-initiated-edits to control that behaviour.

Hover on symbol /function signature

eglot-hover-on-symbol

Here, too, the LSP server's view of a given symbol or function signature is relayed to the ElDoc system. The commands eldoc and eldoc-doc-buffer commands access that information.

There are customization variables to help adjust ElDoc's liberal use of the lower "echo area", among other options. If you still find the solicitous nature of this LSP feature too distracing, you can use eglot-ignored-server-capabilities to turn it off.

Rename

eglot-rename

Type M-x eglot-rename RET to rename the symbol at point.

Find definition

eglot-xref-find-definition

To jump to the definition of a symbol, use the built-in xref-find-definitions command, which is bound to M-..

Find references

eglot-xref-find-references

Eglot here relies on Emacs' built-in functionality as well. xref-find-references is bound to M-?. Additionally, Eglot provides the following similar commands: eglot-find-declaration, eglot-find-implementation, eglot-find-typeDefinition.

Historical differences to lsp-mode.el

Around May 2018, I wrote a comparison of Eglot to lsp-mode.el, and was discussed with its then-maintainer. That mode has since been refactored/rewritten and now purports to support a lot of features that differentiated Eglot from it. It may now be very different or very similar to Eglot, or even sing with the birds in the trees, so go check it out. That said, here's the original comparison, which I will not be updating any more.

"Eglot is considerably less code and hassle than lsp-mode.el. In most cases, there's nothing to configure. It's a minimalist approach focused on user experience and performance.

User-visible differences:

  • The single most visible difference is the friendly entry point M-x eglot, not M-x eglot-<language>. Also, there are no eglot-<language> extra packages.

  • There's no "whitelisting" or "blacklisting" directories to languages. M-x eglot starts servers to handle file of a major mode inside a specific project, using Emacs's built-in project.el library to discover projects. Then it automatically detects current and future opened files under that project and syncs with server;

  • Easy way to quit/restart a server, just middle/right click on the connection name;

  • Pretty interactive mode-line section for live tracking of server communication;

  • Automatically restarts frequently crashing servers;

  • Slow-to-start servers start asynchronously in the background;

  • Server-initiated edits are confirmed with the user;

  • Diagnostics work out-of-the-box (no flycheck.el needed);

  • Smoother/more responsive (read below).

Under the hood:

  • Message parser is much simpler.
  • Defers signature requests like textDocument/hover until server is ready.
  • Sends textDocument/didChange for groups of edits, not one per each tiny change.
  • Easier to read and maintain elisp. Yeah I know, very subjective, so judge for yourself.
  • Doesn't require anything other than Emacs, but will automatically upgrade to work with stuff outside Emacs, like company, markdown-mode, if you happen to have these installed.
  • Has automated tests that check against actual LSP servers."

Copyright Assignment

Eglot is subject to the same copyright assignment policy as GNU Emacs.

Any legally significant contributions can only be merged after the author has completed their paperwork. Please ask for the request form, and we'll send it to you.

eglot's People

Contributors

astoff avatar athas avatar cybershadow avatar dandavison avatar edkolev avatar fbergroth avatar ilohmar avatar jabranham avatar jaelsasser avatar jgarte avatar jimporter avatar joaotavora avatar juergenhoetzel avatar leungbk avatar manuel-uberti avatar marsam avatar meqif avatar mkcms avatar mohkale avatar muffinmad avatar nemethf avatar purcell avatar rprimus avatar sfllaw avatar skangas avatar ssnnoo avatar stephe-ada-guru avatar theothornhill avatar trittweiler avatar xuchunyang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eglot's Issues

Use together with Company

This is probably a dumb question, but how do you get completions from Eglot to Company? I tried looking at your .emacs.d settings but couldn't find anything that'd help me get any kind of completion in my Emacs. Thanks for the great package though!

Make it work on windows

In issue #1, the secondary "hang" problem is probably windows-specific. In version 0.3, commit 12691c2, I pushed some code to make it work on windows and did some testing, but I'm opening this issue to register any more problems.

Fine-tune cquery support

@jaelsasser here's a fresh issue to continue the discussion started in #6.

Regarding the renaming issue, it's of course nicer to implement some kind of $fileDump request, but I wonder if it isn't simpler just to put some kind of printf somewhere in cquery.

That is, I think it might very well be eglot who is not reporting the changes correctly. Other servers are probably more lenient on this, but I more or less recall the spec saying something about overlapping changes and how you shouldn't do that. Well, Eglot does it.

I don't think it's a question of reporting them twice, because other servers would have suffered from the same error.

EDIT: read below, I ruled out the above hypotheses. it's on cquery, I think.

Another problem I'm having is that I can't get my git-built cquery to load my simple project. Is there a simple project guaranteed to work on a brand-new built cquery? Actually, never mind, I just got a minuscule hello-world.c to load.

Handle experimental/unknown server methods gracefully

Hi again, it's me again! I tried using eglot with go-langserver on a go project, and got some super massive error messages in my *Messages* buffer. Here's one I got from hitting M-? on the SetCookie in https://github.com/antifuchs/htpasswd-login/blob/d710f5ddb89a4fa6a1f57c229b0ae44301c06133/http.go#L139 (the buffer contents are in expand-o-fields to save you some scrolling):

The error message from my *Messages* buffer
error in process filter: cl-no-applicable-method: No applicable method: eglot-handle-notification, #s(#s(eieio--class eglot-lsp-server "Represents a server. Wraps a process for LSP communication." (#s(eieio--class jsonrpc-process-connection "A JSONRPC connection over an Emacs process.
The following initargs are accepted:

:PROCESS (mandatory), a live running Emacs process object or a
function of no arguments producing one such object.  The process
represents either a pipe connection to locally running process or
a stream connection to a network host.  The remote endpoint is
expected to understand JSONRPC messages with basic HTTP-style
enveloping headers such as \"Content-Length:\".

:ON-SHUTDOWN (optional), a function of one argument, the
connection object, called when the process dies ." (#s(eieio--class jsonrpc-connection "Base class representing a JSONRPC connection.
The following initargs are accepted:

:NAME (mandatory), a string naming the connection

:REQUEST-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC requests.
CONN is a `jsonrpc-connection' object, method is a symbol, and
PARAMS is a plist representing a JSON object.  The function is
expected to return a JSONRPC result, a plist of (:result
RESULT) or signal an error of type `jsonrpc-error'.

:NOTIFICATION-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC
notifications.  CONN, METHOD and PARAMS are the same as in
:REQUEST-DISPATCHER." nil [#s(cl-slot-descriptor name unbound t ((:documentation . "A name for the connection"))) #s(cl-slot-descriptor -request-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked requests."))) #s(cl-slot-descriptor -notification-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked notifications."))) #s(cl-slot-descriptor last-error unbound t ((:documentation . "Last JSONRPC error message received from endpoint."))) #s(cl-slot-descriptor -request-continuations (make-hash-table) t ((:documentation . "A hash table of request ID to continuation lambdas."))) #s(cl-slot-descriptor -events-buffer unbound t ((:documentation . "A buffer pretty-printing the JSON-RPC RPC events"))) #s(cl-slot-descriptor -deferred-actions (make-hash-table :test (function equal)) t ((:documentation . "Map (DEFERRED BUF) to (FN TIMER ID).  FN isa saved DEFERRED `async-request' from BUF, to be sent not laterthan TIMER as ID."))) #s(cl-slot-descriptor -next-request-id 0 t ((:documentation . "Next number used for a request")))] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data (name 0 -request-dispatcher 1 -notification-dispatcher 2 last-error 3 -request-continuations 4 -events-buffer 5 -deferred-actions 6 -next-request-id 7)) (jsonrpc-process-connection) ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher)) [] [] #s(#5 unbound ignore ignore unbound #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 0) (:custom-groups nil :documentation "Base class representing a JSONRPC connection.
The following initargs are accepted:

:NAME (mandatory), a string naming the connection

:REQUEST-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC requests.
CONN is a `jsonrpc-connection' object, method is a symbol, and
PARAMS is a plist representing a JSON object.  The function is
expected to return a JSONRPC result, a plist of (:result
RESULT) or signal an error of type `jsonrpc-error'.

:NOTIFICATION-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC
notifications.  CONN, METHOD and PARAMS are the same as in
:REQUEST-DISPATCHER."))) [#s(cl-slot-descriptor name unbound t ((:documentation . "A name for the connection"))) #s(cl-slot-descriptor -request-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked requests."))) #s(cl-slot-descriptor -notification-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked notifications."))) #s(cl-slot-descriptor last-error unbound t ((:documentation . "Last JSONRPC error message received from endpoint."))) #s(cl-slot-descriptor -request-continuations (make-hash-table) t ((:documentation . "A hash table of request ID to continuation lambdas."))) #s(cl-slot-descriptor -events-buffer unbound t ((:documentation . "A buffer pretty-printing the JSON-RPC RPC events"))) #s(cl-slot-descriptor -deferred-actions (make-hash-table :test (function equal)) t ((:documentation . "Map (DEFERRED BUF) to (FN TIMER ID).  FN isa saved DEFERRED `async-request' from BUF, to be sent not laterthan TIMER as ID."))) #s(cl-slot-descriptor -next-request-id 0 t ((:documentation . "Next number used for a request"))) #s(cl-slot-descriptor -process unbound t ((:documentation . "Process object wrapped by the this connection."))) #s(cl-slot-descriptor -expected-bytes unbound t ((:documentation . "How many bytes declared by server"))) #s(cl-slot-descriptor -on-shutdown (function ignore) t ((:documentation . "Function run when the process dies.")))] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data (name 0 -request-dispatcher 1 -notification-dispatcher 2 last-error 3 -request-continuations 4 -events-buffer 5 -deferred-actions 6 -next-request-id 7 -process 8 -expected-bytes 9 -on-shutdown 10)) (eglot-lsp-server) ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher) (:process . -process) (:on-shutdown . -on-shutdown)) [] [] #s(#3 unbound ignore ignore unbound #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 0 unbound unbound ignore) (:custom-groups nil :documentation "A JSONRPC connection over an Emacs process.
The following initargs are accepted:

:PROCESS (mandatory), a live running Emacs process object or a
function of no arguments producing one such object.  The process
represents either a pipe connection to locally running process or
a stream connection to a network host.  The remote endpoint is
expected to understand JSONRPC messages with basic HTTP-style
enveloping headers such as \"Content-Length:\".

:ON-SHUTDOWN (optional), a function of one argument, the
connection object, called when the process dies ."))) [#s(cl-slot-descriptor name unbound t ((:documentation . "A name for the connection"))) #s(cl-slot-descriptor -request-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked requests."))) #s(cl-slot-descriptor -notification-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked notifications."))) #s(cl-slot-descriptor last-error unbound t ((:documentation . "Last JSONRPC error message received from endpoint."))) #s(cl-slot-descriptor -request-continuations (make-hash-table) t ((:documentation . "A hash table of request ID to continuation lambdas."))) #s(cl-slot-descriptor -events-buffer unbound t ((:documentation . "A buffer pretty-printing the JSON-RPC RPC events"))) #s(cl-slot-descriptor -deferred-actions (make-hash-table :test (function equal)) t ((:documentation . "Map (DEFERRED BUF) to (FN TIMER ID).  FN isa saved DEFERRED `async-request' from BUF, to be sent not laterthan TIMER as ID."))) #s(cl-slot-descriptor -next-request-id 0 t ((:documentation . "Next number used for a request"))) #s(cl-slot-descriptor -process unbound t ((:documentation . "Process object wrapped by the this connection."))) #s(cl-slot-descriptor -expected-bytes unbound t ((:documentation . "How many bytes declared by server"))) #s(cl-slot-descriptor -on-shutdown (function ignore) t ((:documentation . "Function run when the process dies."))) #s(cl-slot-descriptor project-nickname unbound t ((:documentation . "Short nickname for the associated project."))) #s(cl-slot-descriptor major-mode unbound t ((:documentation . "Major mode symbol."))) #s(cl-slot-descriptor capabilities unbound t ((:documentation . "JSON object containing server capabilities."))) #s(cl-slot-descriptor shutdown-requested unbound t ((:documentation . "Flag set when server is shutting down."))) #s(cl-slot-descriptor project unbound t ((:documentation . "Project associated with server."))) #s(cl-slot-descriptor spinner (\` (nil nil t)) t ((:documentation . "List (ID DOING-WHAT DONE-P) representing server progress."))) #s(cl-slot-descriptor inhibit-autoreconnect t t ((:documentation . "Generalized boolean inhibiting auto-reconnection if true."))) #s(cl-slot-descriptor file-watches (make-hash-table :test (function equal)) t ((:documentation . "Map ID to list of WATCHES for `didChangeWatchedFiles'."))) #s(cl-slot-descriptor managed-buffers unbound t ((:documentation . "List of buffers managed by server."))) #s(cl-slot-descriptor saved-initargs unbound t ((:documentation . "Saved initargs for reconnection purposes."))) #s(cl-slot-descriptor inferior-process unbound t ((:documentation . "Server subprocess started automatically.")))] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data (name 0 -request-dispatcher 1 -notification-dispatcher 2 last-error 3 -request-continuations 4 -events-buffer 5 -deferred-actions 6 -next-request-id 7 -process 8 -expected-bytes 9 -on-shutdown 10 project-nickname 11 major-mode 12 capabilities 13 shutdown-requested 14 project 15 spinner 16 inhibit-autoreconnect 17 file-watches 18 managed-buffers 19 saved-initargs 20 inferior-process 21)) (eglot-cquery eglot-rls) ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher) (:process . -process) (:on-shutdown . -on-shutdown)) [] [] #s(#1 unbound ignore ignore unbound #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 0 unbound unbound ignore unbound unbound unbound unbound unbound (nil nil t) t #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound unbound unbound) (:custom-groups nil :documentation "Represents a server. Wraps a process for LSP communication.")) "EGLOT (htpasswd-login/go-mode)" #[128 "รร€ร‚รƒ๏ฟฝ!ร„๏ฟฝ!@\"\"๏ฟฝ" [eglot-handle-request apply append butlast last] 7 "

(fn &rest ARGS)"] #[128 "รร€ร‚รƒ๏ฟฝ!ร„๏ฟฝ!@\"\"๏ฟฝ" [eglot-handle-notification apply append butlast last] 7 "

(fn &rest ARGS)"] nil #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ( 25 (#[257 "รร€ร‚๏ฟฝD\"๏ฟฝ" [jsonrpc-request-catch-tag165 throw done] 5 "

(fn RESULT)"] #[257 "รร‚รƒร„ร…ร†ร€!ร‡\"รˆร‰%๏ฟฝ\"๏ฟฝ" [jsonrpc-request-catch-tag165 apply make-byte-code 128 "ร๏ฟฝร‚\"A@ร๏ฟฝรƒ\"A@ร๏ฟฝร„\"A@๏ฟฝ๏ฟฝ๏ฟฝ=๏ฟฝ๏ฟฝ@ร…>๏ฟฝ&๏ฟฝ๏ฟฝAAยฒ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝร†๏ฟฝ>A@๏ฟฝ4๏ฟฝร‡ยฒ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝรˆร‰๏ฟฝ@\"๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝรŠร€รˆร‹๏ฟฝ๏ฟฝBรŒ๏ฟฝ๏ฟฝBร๏ฟฝ๏ฟฝBF\"๏ฟฝ" vconcat vector [plist-member :code :message :data (:code :message :data :allow-other-keys) :allow-other-keys nil error "Keyword argument %s not one of (:code :message :data)" throw jsonrpc-error-code jsonrpc-error-message jsonrpc-error-data] 11 "

(fn &key CODE MESSAGE DATA)"] 8 "

(fn JSONRPC-LAMBDA-ELEM69)"] nil))) #<buffer *EGLOT (htpasswd-login/go-mode) events*> #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 25 #<process EGLOT (htpasswd-login/go-mode)> nil eglot--on-shutdown "htpasswd-login" go-mode (:textDocumentSync 2 :hoverProvider t :signatureHelpProvider (:triggerCharacters ["(" ","]) :definitionProvider t :typeDefinitionProvider t :referencesProvider t :documentSymbolProvider t :workspaceSymbolProvider t :implementationProvider t :documentFormattingProvider t :xworkspaceReferencesProvider t :xdefinitionProvider t :xworkspaceSymbolByProperties t) unbound (magit . "/Users/asf/go/src/github.com/antifuchs/htpasswd-login/") (nil nil t) nil #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) (#<buffer sessions.go> #<buffer http.go>) (:process #[0 "ร‚รƒรร„ร€ร…ร†ร‡รˆร‰รŠร‹รŒร\"!&
๏ฟฝ" [("go-langserver") "EGLOT (htpasswd-login/go-mode)" make-process :name :command :connection-type pipe :coding utf-8-emacs-unix :stderr get-buffer-create format "*%s stderr*"] 14]) nil), $/partialResult, :id, 25, :patch, [(:op "replace" :path "" :value [])]
error in process filter: No applicable method: eglot-handle-notification, #s(#s(eieio--class eglot-lsp-server "Represents a server. Wraps a process for LSP communication." (#s(eieio--class jsonrpc-process-connection "A JSONRPC connection over an Emacs process.
The following initargs are accepted:

:PROCESS (mandatory), a live running Emacs process object or a
function of no arguments producing one such object.  The process
represents either a pipe connection to locally running process or
a stream connection to a network host.  The remote endpoint is
expected to understand JSONRPC messages with basic HTTP-style
enveloping headers such as \"Content-Length:\".

:ON-SHUTDOWN (optional), a function of one argument, the
connection object, called when the process dies ." (#s(eieio--class jsonrpc-connection "Base class representing a JSONRPC connection.
The following initargs are accepted:

:NAME (mandatory), a string naming the connection

:REQUEST-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC requests.
CONN is a `jsonrpc-connection' object, method is a symbol, and
PARAMS is a plist representing a JSON object.  The function is
expected to return a JSONRPC result, a plist of (:result
RESULT) or signal an error of type `jsonrpc-error'.

:NOTIFICATION-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC
notifications.  CONN, METHOD and PARAMS are the same as in
:REQUEST-DISPATCHER." nil [#s(cl-slot-descriptor name unbound t ((:documentation . "A name for the connection"))) #s(cl-slot-descriptor -request-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked requests."))) #s(cl-slot-descriptor -notification-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked notifications."))) #s(cl-slot-descriptor last-error unbound t ((:documentation . "Last JSONRPC error message received from endpoint."))) #s(cl-slot-descriptor -request-continuations (make-hash-table) t ((:documentation . "A hash table of request ID to continuation lambdas."))) #s(cl-slot-descriptor -events-buffer unbound t ((:documentation . "A buffer pretty-printing the JSON-RPC RPC events"))) #s(cl-slot-descriptor -deferred-actions (make-hash-table :test (function equal)) t ((:documentation . "Map (DEFERRED BUF) to (FN TIMER ID).  FN isa saved DEFERRED `async-request' from BUF, to be sent not laterthan TIMER as ID."))) #s(cl-slot-descriptor -next-request-id 0 t ((:documentation . "Next number used for a request")))] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data (name 0 -request-dispatcher 1 -notification-dispatcher 2 last-error 3 -request-continuations 4 -events-buffer 5 -deferred-actions 6 -next-request-id 7)) (jsonrpc-process-connection) ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher)) [] [] #s(#5 unbound ignore ignore unbound #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 0) (:custom-groups nil :documentation "Base class representing a JSONRPC connection.
The following initargs are accepted:

:NAME (mandatory), a string naming the connection

:REQUEST-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC requests.
CONN is a `jsonrpc-connection' object, method is a symbol, and
PARAMS is a plist representing a JSON object.  The function is
expected to return a JSONRPC result, a plist of (:result
RESULT) or signal an error of type `jsonrpc-error'.

:NOTIFICATION-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC
notifications.  CONN, METHOD and PARAMS are the same as in
:REQUEST-DISPATCHER."))) [#s(cl-slot-descriptor name unbound t ((:documentation . "A name for the connection"))) #s(cl-slot-descriptor -request-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked requests."))) #s(cl-slot-descriptor -notification-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked notifications."))) #s(cl-slot-descriptor last-error unbound t ((:documentation . "Last JSONRPC error message received from endpoint."))) #s(cl-slot-descriptor -request-continuations (make-hash-table) t ((:documentation . "A hash table of request ID to continuation lambdas."))) #s(cl-slot-descriptor -events-buffer unbound t ((:documentation . "A buffer pretty-printing the JSON-RPC RPC events"))) #s(cl-slot-descriptor -deferred-actions (make-hash-table :test (function equal)) t ((:documentation . "Map (DEFERRED BUF) to (FN TIMER ID).  FN isa saved DEFERRED `async-request' from BUF, to be sent not laterthan TIMER as ID."))) #s(cl-slot-descriptor -next-request-id 0 t ((:documentation . "Next number used for a request"))) #s(cl-slot-descriptor -process unbound t ((:documentation . "Process object wrapped by the this connection."))) #s(cl-slot-descriptor -expected-bytes unbound t ((:documentation . "How many bytes declared by server"))) #s(cl-slot-descriptor -on-shutdown (function ignore) t ((:documentation . "Function run when the process dies.")))] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data (name 0 -request-dispatcher 1 -notification-dispatcher 2 last-error 3 -request-continuations 4 -events-buffer 5 -deferred-actions 6 -next-request-id 7 -process 8 -expected-bytes 9 -on-shutdown 10)) (eglot-lsp-server) ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher) (:process . -process) (:on-shutdown . -on-shutdown)) [] [] #s(#3 unbound ignore ignore unbound #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 0 unbound unbound ignore) (:custom-groups nil :documentation "A JSONRPC connection over an Emacs process.
The following initargs are accepted:

:PROCESS (mandatory), a live running Emacs process object or a
function of no arguments producing one such object.  The process
represents either a pipe connection to locally running process or
a stream connection to a network host.  The remote endpoint is
expected to understand JSONRPC messages with basic HTTP-style
enveloping headers such as \"Content-Length:\".

:ON-SHUTDOWN (optional), a function of one argument, the
connection object, called when the process dies ."))) [#s(cl-slot-descriptor name unbound t ((:documentation . "A name for the connection"))) #s(cl-slot-descriptor -request-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked requests."))) #s(cl-slot-descriptor -notification-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked notifications."))) #s(cl-slot-descriptor last-error unbound t ((:documentation . "Last JSONRPC error message received from endpoint."))) #s(cl-slot-descriptor -request-continuations (make-hash-table) t ((:documentation . "A hash table of request ID to continuation lambdas."))) #s(cl-slot-descriptor -events-buffer unbound t ((:documentation . "A buffer pretty-printing the JSON-RPC RPC events"))) #s(cl-slot-descriptor -deferred-actions (make-hash-table :test (function equal)) t ((:documentation . "Map (DEFERRED BUF) to (FN TIMER ID).  FN isa saved DEFERRED `async-request' from BUF, to be sent not laterthan TIMER as ID."))) #s(cl-slot-descriptor -next-request-id 0 t ((:documentation . "Next number used for a request"))) #s(cl-slot-descriptor -process unbound t ((:documentation . "Process object wrapped by the this connection."))) #s(cl-slot-descriptor -expected-bytes unbound t ((:documentation . "How many bytes declared by server"))) #s(cl-slot-descriptor -on-shutdown (function ignore) t ((:documentation . "Function run when the process dies."))) #s(cl-slot-descriptor project-nickname unbound t ((:documentation . "Short nickname for the associated project."))) #s(cl-slot-descriptor major-mode unbound t ((:documentation . "Major mode symbol."))) #s(cl-slot-descriptor capabilities unbound t ((:documentation . "JSON object containing server capabilities."))) #s(cl-slot-descriptor shutdown-requested unbound t ((:documentation . "Flag set when server is shutting down."))) #s(cl-slot-descriptor project unbound t ((:documentation . "Project associated with server."))) #s(cl-slot-descriptor spinner (\` (nil nil t)) t ((:documentation . "List (ID DOING-WHAT DONE-P) representing server progress."))) #s(cl-slot-descriptor inhibit-autoreconnect t t ((:documentation . "Generalized boolean inhibiting auto-reconnection if true."))) #s(cl-slot-descriptor file-watches (make-hash-table :test (function equal)) t ((:documentation . "Map ID to list of WATCHES for `didChangeWatchedFiles'."))) #s(cl-slot-descriptor managed-buffers unbound t ((:documentation . "List of buffers managed by server."))) #s(cl-slot-descriptor saved-initargs unbound t ((:documentation . "Saved initargs for reconnection purposes."))) #s(cl-slot-descriptor inferior-process unbound t ((:documentation . "Server subprocess started automatically.")))] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data (name 0 -request-dispatcher 1 -notification-dispatcher 2 last-error 3 -request-continuations 4 -events-buffer 5 -deferred-actions 6 -next-request-id 7 -process 8 -expected-bytes 9 -on-shutdown 10 project-nickname 11 major-mode 12 capabilities 13 shutdown-requested 14 project 15 spinner 16 inhibit-autoreconnect 17 file-watches 18 managed-buffers 19 saved-initargs 20 inferior-process 21)) (eglot-cquery eglot-rls) ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher) (:process . -process) (:on-shutdown . -on-shutdown)) [] [] #s(#1 unbound ignore ignore unbound #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 0 unbound unbound ignore unbound unbound unbound unbound unbound (nil nil t) t #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound unbound unbound) (:custom-groups nil :documentation "Represents a server. Wraps a process for LSP communication.")) "EGLOT (htpasswd-login/go-mode)" #[128 "รร€ร‚รƒ๏ฟฝ!ร„๏ฟฝ!@\"\"๏ฟฝ" [eglot-handle-request apply append butlast last] 7 "

(fn &rest ARGS)"] #[128 "รร€ร‚รƒ๏ฟฝ!ร„๏ฟฝ!@\"\"๏ฟฝ" [eglot-handle-notification apply append butlast last] 7 "

(fn &rest ARGS)"] nil #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ( 25 (#[257 "รร€ร‚๏ฟฝD\"๏ฟฝ" [jsonrpc-request-catch-tag165 throw done] 5 "

(fn RESULT)"] #[257 "รร‚รƒร„ร…ร†ร€!ร‡\"รˆร‰%๏ฟฝ\"๏ฟฝ" [jsonrpc-request-catch-tag165 apply make-byte-code 128 "ร๏ฟฝร‚\"A@ร๏ฟฝรƒ\"A@ร๏ฟฝร„\"A@๏ฟฝ๏ฟฝ๏ฟฝ=๏ฟฝ๏ฟฝ@ร…>๏ฟฝ&๏ฟฝ๏ฟฝAAยฒ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝร†๏ฟฝ>A@๏ฟฝ4๏ฟฝร‡ยฒ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝรˆร‰๏ฟฝ@\"๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝรŠร€รˆร‹๏ฟฝ๏ฟฝBรŒ๏ฟฝ๏ฟฝBร๏ฟฝ๏ฟฝBF\"๏ฟฝ" vconcat vector [plist-member :code :message :data (:code :message :data :allow-other-keys) :allow-other-keys nil error "Keyword argument %s not one of (:code :message :data)" throw jsonrpc-error-code jsonrpc-error-message jsonrpc-error-data] 11 "

(fn &key CODE MESSAGE DATA)"] 8 "

(fn JSONRPC-LAMBDA-ELEM69)"] nil))) #<buffer *EGLOT (htpasswd-login/go-mode) events*> #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 25 #<process EGLOT (htpasswd-login/go-mode)> nil eglot--on-shutdown "htpasswd-login" go-mode (:textDocumentSync 2 :hoverProvider t :signatureHelpProvider (:triggerCharacters ["(" ","]) :definitionProvider t :typeDefinitionProvider t :referencesProvider t :documentSymbolProvider t :workspaceSymbolProvider t :implementationProvider t :documentFormattingProvider t :xworkspaceReferencesProvider t :xdefinitionProvider t :xworkspaceSymbolByProperties t) unbound (magit . "/Users/asf/go/src/github.com/antifuchs/htpasswd-login/") (nil nil t) nil #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) (#<buffer sessions.go> #<buffer http.go>) (:process #[0 "ร‚รƒรร„ร€ร…ร†ร‡รˆร‰รŠร‹รŒร\"!&
๏ฟฝ" [("go-langserver") "EGLOT (htpasswd-login/go-mode)" make-process :name :command :connection-type pipe :coding utf-8-emacs-unix :stderr get-buffer-create format "*%s stderr*"] 14]) nil), $/partialResult, :id, 25, :patch, [(:op "replace" :path "" :value [])]
error in process filter: cl-no-applicable-method: No applicable method: eglot-handle-notification, #s(#s(eieio--class eglot-lsp-server "Represents a server. Wraps a process for LSP communication." (#s(eieio--class jsonrpc-process-connection "A JSONRPC connection over an Emacs process.
The following initargs are accepted:

:PROCESS (mandatory), a live running Emacs process object or a
function of no arguments producing one such object.  The process
represents either a pipe connection to locally running process or
a stream connection to a network host.  The remote endpoint is
expected to understand JSONRPC messages with basic HTTP-style
enveloping headers such as \"Content-Length:\".

:ON-SHUTDOWN (optional), a function of one argument, the
connection object, called when the process dies ." (#s(eieio--class jsonrpc-connection "Base class representing a JSONRPC connection.
The following initargs are accepted:

:NAME (mandatory), a string naming the connection

:REQUEST-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC requests.
CONN is a `jsonrpc-connection' object, method is a symbol, and
PARAMS is a plist representing a JSON object.  The function is
expected to return a JSONRPC result, a plist of (:result
RESULT) or signal an error of type `jsonrpc-error'.

:NOTIFICATION-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC
notifications.  CONN, METHOD and PARAMS are the same as in
:REQUEST-DISPATCHER." nil [#s(cl-slot-descriptor name unbound t ((:documentation . "A name for the connection"))) #s(cl-slot-descriptor -request-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked requests."))) #s(cl-slot-descriptor -notification-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked notifications."))) #s(cl-slot-descriptor last-error unbound t ((:documentation . "Last JSONRPC error message received from endpoint."))) #s(cl-slot-descriptor -request-continuations (make-hash-table) t ((:documentation . "A hash table of request ID to continuation lambdas."))) #s(cl-slot-descriptor -events-buffer unbound t ((:documentation . "A buffer pretty-printing the JSON-RPC RPC events"))) #s(cl-slot-descriptor -deferred-actions (make-hash-table :test (function equal)) t ((:documentation . "Map (DEFERRED BUF) to (FN TIMER ID).  FN isa saved DEFERRED `async-request' from BUF, to be sent not laterthan TIMER as ID."))) #s(cl-slot-descriptor -next-request-id 0 t ((:documentation . "Next number used for a request")))] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data (name 0 -request-dispatcher 1 -notification-dispatcher 2 last-error 3 -request-continuations 4 -events-buffer 5 -deferred-actions 6 -next-request-id 7)) (jsonrpc-process-connection) ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher)) [] [] #s(#5 unbound ignore ignore unbound #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 0) (:custom-groups nil :documentation "Base class representing a JSONRPC connection.
The following initargs are accepted:

:NAME (mandatory), a string naming the connection

:REQUEST-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC requests.
CONN is a `jsonrpc-connection' object, method is a symbol, and
PARAMS is a plist representing a JSON object.  The function is
expected to return a JSONRPC result, a plist of (:result
RESULT) or signal an error of type `jsonrpc-error'.

:NOTIFICATION-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC
notifications.  CONN, METHOD and PARAMS are the same as in
:REQUEST-DISPATCHER."))) [#s(cl-slot-descriptor name unbound t ((:documentation . "A name for the connection"))) #s(cl-slot-descriptor -request-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked requests."))) #s(cl-slot-descriptor -notification-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked notifications."))) #s(cl-slot-descriptor last-error unbound t ((:documentation . "Last JSONRPC error message received from endpoint."))) #s(cl-slot-descriptor -request-continuations (make-hash-table) t ((:documentation . "A hash table of request ID to continuation lambdas."))) #s(cl-slot-descriptor -events-buffer unbound t ((:documentation . "A buffer pretty-printing the JSON-RPC RPC events"))) #s(cl-slot-descriptor -deferred-actions (make-hash-table :test (function equal)) t ((:documentation . "Map (DEFERRED BUF) to (FN TIMER ID).  FN isa saved DEFERRED `async-request' from BUF, to be sent not laterthan TIMER as ID."))) #s(cl-slot-descriptor -next-request-id 0 t ((:documentation . "Next number used for a request"))) #s(cl-slot-descriptor -process unbound t ((:documentation . "Process object wrapped by the this connection."))) #s(cl-slot-descriptor -expected-bytes unbound t ((:documentation . "How many bytes declared by server"))) #s(cl-slot-descriptor -on-shutdown (function ignore) t ((:documentation . "Function run when the process dies.")))] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data (name 0 -request-dispatcher 1 -notification-dispatcher 2 last-error 3 -request-continuations 4 -events-buffer 5 -deferred-actions 6 -next-request-id 7 -process 8 -expected-bytes 9 -on-shutdown 10)) (eglot-lsp-server) ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher) (:process . -process) (:on-shutdown . -on-shutdown)) [] [] #s(#3 unbound ignore ignore unbound #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 0 unbound unbound ignore) (:custom-groups nil :documentation "A JSONRPC connection over an Emacs process.
The following initargs are accepted:

:PROCESS (mandatory), a live running Emacs process object or a
function of no arguments producing one such object.  The process
represents either a pipe connection to locally running process or
a stream connection to a network host.  The remote endpoint is
expected to understand JSONRPC messages with basic HTTP-style
enveloping headers such as \"Content-Length:\".

:ON-SHUTDOWN (optional), a function of one argument, the
connection object, called when the process dies ."))) [#s(cl-slot-descriptor name unbound t ((:documentation . "A name for the connection"))) #s(cl-slot-descriptor -request-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked requests."))) #s(cl-slot-descriptor -notification-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked notifications."))) #s(cl-slot-descriptor last-error unbound t ((:documentation . "Last JSONRPC error message received from endpoint."))) #s(cl-slot-descriptor -request-continuations (make-hash-table) t ((:documentation . "A hash table of request ID to continuation lambdas."))) #s(cl-slot-descriptor -events-buffer unbound t ((:documentation . "A buffer pretty-printing the JSON-RPC RPC events"))) #s(cl-slot-descriptor -deferred-actions (make-hash-table :test (function equal)) t ((:documentation . "Map (DEFERRED BUF) to (FN TIMER ID).  FN isa saved DEFERRED `async-request' from BUF, to be sent not laterthan TIMER as ID."))) #s(cl-slot-descriptor -next-request-id 0 t ((:documentation . "Next number used for a request"))) #s(cl-slot-descriptor -process unbound t ((:documentation . "Process object wrapped by the this connection."))) #s(cl-slot-descriptor -expected-bytes unbound t ((:documentation . "How many bytes declared by server"))) #s(cl-slot-descriptor -on-shutdown (function ignore) t ((:documentation . "Function run when the process dies."))) #s(cl-slot-descriptor project-nickname unbound t ((:documentation . "Short nickname for the associated project."))) #s(cl-slot-descriptor major-mode unbound t ((:documentation . "Major mode symbol."))) #s(cl-slot-descriptor capabilities unbound t ((:documentation . "JSON object containing server capabilities."))) #s(cl-slot-descriptor shutdown-requested unbound t ((:documentation . "Flag set when server is shutting down."))) #s(cl-slot-descriptor project unbound t ((:documentation . "Project associated with server."))) #s(cl-slot-descriptor spinner (\` (nil nil t)) t ((:documentation . "List (ID DOING-WHAT DONE-P) representing server progress."))) #s(cl-slot-descriptor inhibit-autoreconnect t t ((:documentation . "Generalized boolean inhibiting auto-reconnection if true."))) #s(cl-slot-descriptor file-watches (make-hash-table :test (function equal)) t ((:documentation . "Map ID to list of WATCHES for `didChangeWatchedFiles'."))) #s(cl-slot-descriptor managed-buffers unbound t ((:documentation . "List of buffers managed by server."))) #s(cl-slot-descriptor saved-initargs unbound t ((:documentation . "Saved initargs for reconnection purposes."))) #s(cl-slot-descriptor inferior-process unbound t ((:documentation . "Server subprocess started automatically.")))] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data (name 0 -request-dispatcher 1 -notification-dispatcher 2 last-error 3 -request-continuations 4 -events-buffer 5 -deferred-actions 6 -next-request-id 7 -process 8 -expected-bytes 9 -on-shutdown 10 project-nickname 11 major-mode 12 capabilities 13 shutdown-requested 14 project 15 spinner 16 inhibit-autoreconnect 17 file-watches 18 managed-buffers 19 saved-initargs 20 inferior-process 21)) (eglot-cquery eglot-rls) ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher) (:process . -process) (:on-shutdown . -on-shutdown)) [] [] #s(#1 unbound ignore ignore unbound #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 0 unbound unbound ignore unbound unbound unbound unbound unbound (nil nil t) t #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound unbound unbound) (:custom-groups nil :documentation "Represents a server. Wraps a process for LSP communication.")) "EGLOT (htpasswd-login/go-mode)" #[128 "รร€ร‚รƒ๏ฟฝ!ร„๏ฟฝ!@\"\"๏ฟฝ" [eglot-handle-request apply append butlast last] 7 "

(fn &rest ARGS)"] #[128 "รร€ร‚รƒ๏ฟฝ!ร„๏ฟฝ!@\"\"๏ฟฝ" [eglot-handle-notification apply append butlast last] 7 "

(fn &rest ARGS)"] nil #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ( 25 (#[257 "รร€ร‚๏ฟฝD\"๏ฟฝ" [jsonrpc-request-catch-tag165 throw done] 5 "

(fn RESULT)"] #[257 "รร‚รƒร„ร…ร†ร€!ร‡\"รˆร‰%๏ฟฝ\"๏ฟฝ" [jsonrpc-request-catch-tag165 apply make-byte-code 128 "ร๏ฟฝร‚\"A@ร๏ฟฝรƒ\"A@ร๏ฟฝร„\"A@๏ฟฝ๏ฟฝ๏ฟฝ=๏ฟฝ๏ฟฝ@ร…>๏ฟฝ&๏ฟฝ๏ฟฝAAยฒ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝร†๏ฟฝ>A@๏ฟฝ4๏ฟฝร‡ยฒ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝรˆร‰๏ฟฝ@\"๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝรŠร€รˆร‹๏ฟฝ๏ฟฝBรŒ๏ฟฝ๏ฟฝBร๏ฟฝ๏ฟฝBF\"๏ฟฝ" vconcat vector [plist-member :code :message :data (:code :message :data :allow-other-keys) :allow-other-keys nil error "Keyword argument %s not one of (:code :message :data)" throw jsonrpc-error-code jsonrpc-error-message jsonrpc-error-data] 11 "

(fn &key CODE MESSAGE DATA)"] 8 "

(fn JSONRPC-LAMBDA-ELEM69)"] nil))) #<buffer *EGLOT (htpasswd-login/go-mode) events*> #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 25 #<process EGLOT (htpasswd-login/go-mode)> nil eglot--on-shutdown "htpasswd-login" go-mode (:textDocumentSync 2 :hoverProvider t :signatureHelpProvider (:triggerCharacters ["(" ","]) :definitionProvider t :typeDefinitionProvider t :referencesProvider t :documentSymbolProvider t :workspaceSymbolProvider t :implementationProvider t :documentFormattingProvider t :xworkspaceReferencesProvider t :xdefinitionProvider t :xworkspaceSymbolByProperties t) unbound (magit . "/Users/asf/go/src/github.com/antifuchs/htpasswd-login/") (nil nil t) nil #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) (#<buffer sessions.go> #<buffer http.go>) (:process #[0 "ร‚รƒรร„ร€ร…ร†ร‡รˆร‰รŠร‹รŒร\"!&
๏ฟฝ" [("go-langserver") "EGLOT (htpasswd-login/go-mode)" make-process :name :command :connection-type pipe :coding utf-8-emacs-unix :stderr get-buffer-create format "*%s stderr*"] 14]) nil), $/partialResult, :id, 25, :patch, [(:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/cookie_test.go" :range (:start (:line 152 :character 1) :end (:line 152 :character 10)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/cookie_test.go" :range (:start (:line 153 :character 1) :end (:line 153 :character 10)))) (:op "add" :path "/-" :value (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range (:start (:line 101 :character 8) :end (:line 101 :character 17)))) (:op "add" :path "/-" :value (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range (:start (:line 108 :character 8) :end (:line 108 :character 17)))) (:op "add" :path "/-" :value (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range (:start (:line 138 :character 7) :end (:line 138 :character 16)))) (:op "add" :path "/-" :value (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range (:start (:line 192 :character 12) :end (:line 192 :character 21)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 595 :character 2) :end (:line 595 :character 11)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 598 :character 2) :end (:line 598 :character 11)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 601 :character 2) :end (:line 601 :character 11)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 702 :character 2) :end (:line 702 :character 11)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1583 :character 3) :end (:line 1583 :character 12)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1584 :character 3) :end (:line 1584 :character 12)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1593 :character 3) :end (:line 1593 :character 12)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1594 :character 3) :end (:line 1594 :character 12)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1595 :character 3) :end (:line 1595 :character 12)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1604 :character 3) :end (:line 1604 :character 12)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1605 :character 3) :end (:line 1605 :character 12))))]
error in process filter: No applicable method: eglot-handle-notification, #s(#s(eieio--class eglot-lsp-server "Represents a server. Wraps a process for LSP communication." (#s(eieio--class jsonrpc-process-connection "A JSONRPC connection over an Emacs process.
The following initargs are accepted:

:PROCESS (mandatory), a live running Emacs process object or a
function of no arguments producing one such object.  The process
represents either a pipe connection to locally running process or
a stream connection to a network host.  The remote endpoint is
expected to understand JSONRPC messages with basic HTTP-style
enveloping headers such as \"Content-Length:\".

:ON-SHUTDOWN (optional), a function of one argument, the
connection object, called when the process dies ." (#s(eieio--class jsonrpc-connection "Base class representing a JSONRPC connection.
The following initargs are accepted:

:NAME (mandatory), a string naming the connection

:REQUEST-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC requests.
CONN is a `jsonrpc-connection' object, method is a symbol, and
PARAMS is a plist representing a JSON object.  The function is
expected to return a JSONRPC result, a plist of (:result
RESULT) or signal an error of type `jsonrpc-error'.

:NOTIFICATION-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC
notifications.  CONN, METHOD and PARAMS are the same as in
:REQUEST-DISPATCHER." nil [#s(cl-slot-descriptor name unbound t ((:documentation . "A name for the connection"))) #s(cl-slot-descriptor -request-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked requests."))) #s(cl-slot-descriptor -notification-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked notifications."))) #s(cl-slot-descriptor last-error unbound t ((:documentation . "Last JSONRPC error message received from endpoint."))) #s(cl-slot-descriptor -request-continuations (make-hash-table) t ((:documentation . "A hash table of request ID to continuation lambdas."))) #s(cl-slot-descriptor -events-buffer unbound t ((:documentation . "A buffer pretty-printing the JSON-RPC RPC events"))) #s(cl-slot-descriptor -deferred-actions (make-hash-table :test (function equal)) t ((:documentation . "Map (DEFERRED BUF) to (FN TIMER ID).  FN isa saved DEFERRED `async-request' from BUF, to be sent not laterthan TIMER as ID."))) #s(cl-slot-descriptor -next-request-id 0 t ((:documentation . "Next number used for a request")))] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data (name 0 -request-dispatcher 1 -notification-dispatcher 2 last-error 3 -request-continuations 4 -events-buffer 5 -deferred-actions 6 -next-request-id 7)) (jsonrpc-process-connection) ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher)) [] [] #s(#5 unbound ignore ignore unbound #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 0) (:custom-groups nil :documentation "Base class representing a JSONRPC connection.
The following initargs are accepted:

:NAME (mandatory), a string naming the connection

:REQUEST-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC requests.
CONN is a `jsonrpc-connection' object, method is a symbol, and
PARAMS is a plist representing a JSON object.  The function is
expected to return a JSONRPC result, a plist of (:result
RESULT) or signal an error of type `jsonrpc-error'.

:NOTIFICATION-DISPATCHER (optional), a function of three
arguments (CONN METHOD PARAMS) for handling JSONRPC
notifications.  CONN, METHOD and PARAMS are the same as in
:REQUEST-DISPATCHER."))) [#s(cl-slot-descriptor name unbound t ((:documentation . "A name for the connection"))) #s(cl-slot-descriptor -request-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked requests."))) #s(cl-slot-descriptor -notification-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked notifications."))) #s(cl-slot-descriptor last-error unbound t ((:documentation . "Last JSONRPC error message received from endpoint."))) #s(cl-slot-descriptor -request-continuations (make-hash-table) t ((:documentation . "A hash table of request ID to continuation lambdas."))) #s(cl-slot-descriptor -events-buffer unbound t ((:documentation . "A buffer pretty-printing the JSON-RPC RPC events"))) #s(cl-slot-descriptor -deferred-actions (make-hash-table :test (function equal)) t ((:documentation . "Map (DEFERRED BUF) to (FN TIMER ID).  FN isa saved DEFERRED `async-request' from BUF, to be sent not laterthan TIMER as ID."))) #s(cl-slot-descriptor -next-request-id 0 t ((:documentation . "Next number used for a request"))) #s(cl-slot-descriptor -process unbound t ((:documentation . "Process object wrapped by the this connection."))) #s(cl-slot-descriptor -expected-bytes unbound t ((:documentation . "How many bytes declared by server"))) #s(cl-slot-descriptor -on-shutdown (function ignore) t ((:documentation . "Function run when the process dies.")))] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data (name 0 -request-dispatcher 1 -notification-dispatcher 2 last-error 3 -request-continuations 4 -events-buffer 5 -deferred-actions 6 -next-request-id 7 -process 8 -expected-bytes 9 -on-shutdown 10)) (eglot-lsp-server) ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher) (:process . -process) (:on-shutdown . -on-shutdown)) [] [] #s(#3 unbound ignore ignore unbound #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 0 unbound unbound ignore) (:custom-groups nil :documentation "A JSONRPC connection over an Emacs process.
The following initargs are accepted:

:PROCESS (mandatory), a live running Emacs process object or a
function of no arguments producing one such object.  The process
represents either a pipe connection to locally running process or
a stream connection to a network host.  The remote endpoint is
expected to understand JSONRPC messages with basic HTTP-style
enveloping headers such as \"Content-Length:\".

:ON-SHUTDOWN (optional), a function of one argument, the
connection object, called when the process dies ."))) [#s(cl-slot-descriptor name unbound t ((:documentation . "A name for the connection"))) #s(cl-slot-descriptor -request-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked requests."))) #s(cl-slot-descriptor -notification-dispatcher (function ignore) t ((:documentation . "Dispatcher for remotely invoked notifications."))) #s(cl-slot-descriptor last-error unbound t ((:documentation . "Last JSONRPC error message received from endpoint."))) #s(cl-slot-descriptor -request-continuations (make-hash-table) t ((:documentation . "A hash table of request ID to continuation lambdas."))) #s(cl-slot-descriptor -events-buffer unbound t ((:documentation . "A buffer pretty-printing the JSON-RPC RPC events"))) #s(cl-slot-descriptor -deferred-actions (make-hash-table :test (function equal)) t ((:documentation . "Map (DEFERRED BUF) to (FN TIMER ID).  FN isa saved DEFERRED `async-request' from BUF, to be sent not laterthan TIMER as ID."))) #s(cl-slot-descriptor -next-request-id 0 t ((:documentation . "Next number used for a request"))) #s(cl-slot-descriptor -process unbound t ((:documentation . "Process object wrapped by the this connection."))) #s(cl-slot-descriptor -expected-bytes unbound t ((:documentation . "How many bytes declared by server"))) #s(cl-slot-descriptor -on-shutdown (function ignore) t ((:documentation . "Function run when the process dies."))) #s(cl-slot-descriptor project-nickname unbound t ((:documentation . "Short nickname for the associated project."))) #s(cl-slot-descriptor major-mode unbound t ((:documentation . "Major mode symbol."))) #s(cl-slot-descriptor capabilities unbound t ((:documentation . "JSON object containing server capabilities."))) #s(cl-slot-descriptor shutdown-requested unbound t ((:documentation . "Flag set when server is shutting down."))) #s(cl-slot-descriptor project unbound t ((:documentation . "Project associated with server."))) #s(cl-slot-descriptor spinner (\` (nil nil t)) t ((:documentation . "List (ID DOING-WHAT DONE-P) representing server progress."))) #s(cl-slot-descriptor inhibit-autoreconnect t t ((:documentation . "Generalized boolean inhibiting auto-reconnection if true."))) #s(cl-slot-descriptor file-watches (make-hash-table :test (function equal)) t ((:documentation . "Map ID to list of WATCHES for `didChangeWatchedFiles'."))) #s(cl-slot-descriptor managed-buffers unbound t ((:documentation . "List of buffers managed by server."))) #s(cl-slot-descriptor saved-initargs unbound t ((:documentation . "Saved initargs for reconnection purposes."))) #s(cl-slot-descriptor inferior-process unbound t ((:documentation . "Server subprocess started automatically.")))] #s(hash-table size 65 test eq rehash-size 1.5 rehash-threshold 0.8125 data (name 0 -request-dispatcher 1 -notification-dispatcher 2 last-error 3 -request-continuations 4 -events-buffer 5 -deferred-actions 6 -next-request-id 7 -process 8 -expected-bytes 9 -on-shutdown 10 project-nickname 11 major-mode 12 capabilities 13 shutdown-requested 14 project 15 spinner 16 inhibit-autoreconnect 17 file-watches 18 managed-buffers 19 saved-initargs 20 inferior-process 21)) (eglot-cquery eglot-rls) ((:name . name) (:request-dispatcher . -request-dispatcher) (:notification-dispatcher . -notification-dispatcher) (:process . -process) (:on-shutdown . -on-shutdown)) [] [] #s(#1 unbound ignore ignore unbound #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 0 unbound unbound ignore unbound unbound unbound unbound unbound (nil nil t) t #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) unbound unbound unbound) (:custom-groups nil :documentation "Represents a server. Wraps a process for LSP communication.")) "EGLOT (htpasswd-login/go-mode)" #[128 "รร€ร‚รƒ๏ฟฝ!ร„๏ฟฝ!@\"\"๏ฟฝ" [eglot-handle-request apply append butlast last] 7 "

(fn &rest ARGS)"] #[128 "รร€ร‚รƒ๏ฟฝ!ร„๏ฟฝ!@\"\"๏ฟฝ" [eglot-handle-notification apply append butlast last] 7 "

(fn &rest ARGS)"] nil #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ( 25 (#[257 "รร€ร‚๏ฟฝD\"๏ฟฝ" [jsonrpc-request-catch-tag165 throw done] 5 "

(fn RESULT)"] #[257 "รร‚รƒร„ร…ร†ร€!ร‡\"รˆร‰%๏ฟฝ\"๏ฟฝ" [jsonrpc-request-catch-tag165 apply make-byte-code 128 "ร๏ฟฝร‚\"A@ร๏ฟฝรƒ\"A@ร๏ฟฝร„\"A@๏ฟฝ๏ฟฝ๏ฟฝ=๏ฟฝ๏ฟฝ@ร…>๏ฟฝ&๏ฟฝ๏ฟฝAAยฒ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝร†๏ฟฝ>A@๏ฟฝ4๏ฟฝร‡ยฒ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝรˆร‰๏ฟฝ@\"๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝรŠร€รˆร‹๏ฟฝ๏ฟฝBรŒ๏ฟฝ๏ฟฝBร๏ฟฝ๏ฟฝBF\"๏ฟฝ" vconcat vector [plist-member :code :message :data (:code :message :data :allow-other-keys) :allow-other-keys nil error "Keyword argument %s not one of (:code :message :data)" throw jsonrpc-error-code jsonrpc-error-message jsonrpc-error-data] 11 "

(fn &key CODE MESSAGE DATA)"] 8 "

(fn JSONRPC-LAMBDA-ELEM69)"] nil))) #<buffer *EGLOT (htpasswd-login/go-mode) events*> #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) 25 #<process EGLOT (htpasswd-login/go-mode)> nil eglot--on-shutdown "htpasswd-login" go-mode (:textDocumentSync 2 :hoverProvider t :signatureHelpProvider (:triggerCharacters ["(" ","]) :definitionProvider t :typeDefinitionProvider t :referencesProvider t :documentSymbolProvider t :workspaceSymbolProvider t :implementationProvider t :documentFormattingProvider t :xworkspaceReferencesProvider t :xdefinitionProvider t :xworkspaceSymbolByProperties t) unbound (magit . "/Users/asf/go/src/github.com/antifuchs/htpasswd-login/") (nil nil t) nil #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ()) (#<buffer sessions.go> #<buffer http.go>) (:process #[0 "ร‚รƒรร„ร€ร…ร†ร‡รˆร‰รŠร‹รŒร\"!&
๏ฟฝ" [("go-langserver") "EGLOT (htpasswd-login/go-mode)" make-process :name :command :connection-type pipe :coding utf-8-emacs-unix :stderr get-buffer-create format "*%s stderr*"] 14]) nil), $/partialResult, :id, 25, :patch, [(:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/cookie_test.go" :range (:start (:line 152 :character 1) :end (:line 152 :character 10)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/cookie_test.go" :range (:start (:line 153 :character 1) :end (:line 153 :character 10)))) (:op "add" :path "/-" :value (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range (:start (:line 101 :character 8) :end (:line 101 :character 17)))) (:op "add" :path "/-" :value (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range (:start (:line 108 :character 8) :end (:line 108 :character 17)))) (:op "add" :path "/-" :value (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range (:start (:line 138 :character 7) :end (:line 138 :character 16)))) (:op "add" :path "/-" :value (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range (:start (:line 192 :character 12) :end (:line 192 :character 21)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 595 :character 2) :end (:line 595 :character 11)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 598 :character 2) :end (:line 598 :character 11)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 601 :character 2) :end (:line 601 :character 11)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 702 :character 2) :end (:line 702 :character 11)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1583 :character 3) :end (:line 1583 :character 12)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1584 :character 3) :end (:line 1584 :character 12)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1593 :character 3) :end (:line 1593 :character 12)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1594 :character 3) :end (:line 1594 :character 12)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1595 :character 3) :end (:line 1595 :character 12)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1604 :character 3) :end (:line 1604 :character 12)))) (:op "add" :path "/-" :value (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range (:start (:line 1605 :character 3) :end (:line 1605 :character 12))))]

Here's the contents of the events buffer between me pressing M-? and eglot showing results:

events buffer, lines 1424 through 1657
client-request (id:34) Wed Jul 11 00:25:35 2018:
(:jsonrpc "2.0" :id 34 :method "textDocument/documentSymbol" :params
          (:textDocument
           (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go")))

server-reply (id:34) Wed Jul 11 00:25:35 2018:
(:id 34 :result
     [(:name "isParent" :kind 12 :location
             (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range
                   (:start
                    (:line 35 :character 5)
                    :end
                    (:line 35 :character 13))))
      (:name "moreRelevant" :kind 12 :location
             (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range
                   (:start
                    (:line 50 :character 5)
                    :end
                    (:line 50 :character 17))))]
     :jsonrpc "2.0")

client-request (id:35) Wed Jul 11 00:25:36 2018:
(:jsonrpc "2.0" :id 35 :method "textDocument/references" :params
          (:textDocument
           (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go")
           :position
           (:line 138 :character 7)
           :context
           (:includeDeclaration t)))

server-notification Wed Jul 11 00:25:36 2018:
(:method "$/partialResult" :params
         (:id 35 :patch
              [(:op "replace" :path "" :value
                    [])])
         :jsonrpc "2.0")

server-notification Wed Jul 11 00:25:36 2018:
(:method "$/partialResult" :params
         (:id 35 :patch
              [(:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
                          (:start
                           (:line 595 :character 2)
                           :end
                           (:line 595 :character 11))))
               (:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
                          (:start
                           (:line 598 :character 2)
                           :end
                           (:line 598 :character 11))))
               (:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
                          (:start
                           (:line 601 :character 2)
                           :end
                           (:line 601 :character 11))))
               (:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
                          (:start
                           (:line 702 :character 2)
                           :end
                           (:line 702 :character 11))))
               (:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
                          (:start
                           (:line 1583 :character 3)
                           :end
                           (:line 1583 :character 12))))
               (:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
                          (:start
                           (:line 1584 :character 3)
                           :end
                           (:line 1584 :character 12))))
               (:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
                          (:start
                           (:line 1593 :character 3)
                           :end
                           (:line 1593 :character 12))))
               (:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
                          (:start
                           (:line 1594 :character 3)
                           :end
                           (:line 1594 :character 12))))
               (:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
                          (:start
                           (:line 1595 :character 3)
                           :end
                           (:line 1595 :character 12))))
               (:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
                          (:start
                           (:line 1604 :character 3)
                           :end
                           (:line 1604 :character 12))))
               (:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
                          (:start
                           (:line 1605 :character 3)
                           :end
                           (:line 1605 :character 12))))
               (:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/cookie_test.go" :range
                          (:start
                           (:line 152 :character 1)
                           :end
                           (:line 152 :character 10))))
               (:op "add" :path "/-" :value
                    (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/cookie_test.go" :range
                          (:start
                           (:line 153 :character 1)
                           :end
                           (:line 153 :character 10))))
               (:op "add" :path "/-" :value
                    (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range
                          (:start
                           (:line 101 :character 8)
                           :end
                           (:line 101 :character 17))))
               (:op "add" :path "/-" :value
                    (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range
                          (:start
                           (:line 108 :character 8)
                           :end
                           (:line 108 :character 17))))
               (:op "add" :path "/-" :value
                    (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range
                          (:start
                           (:line 138 :character 7)
                           :end
                           (:line 138 :character 16))))
               (:op "add" :path "/-" :value
                    (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range
                          (:start
                           (:line 192 :character 12)
                           :end
                           (:line 192 :character 21))))])
         :jsonrpc "2.0")

server-reply (id:35) Wed Jul 11 00:25:36 2018:
(:id 35 :result
     [(:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
            (:start
             (:line 595 :character 2)
             :end
             (:line 595 :character 11)))
      (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
            (:start
             (:line 598 :character 2)
             :end
             (:line 598 :character 11)))
      (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
            (:start
             (:line 601 :character 2)
             :end
             (:line 601 :character 11)))
      (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
            (:start
             (:line 702 :character 2)
             :end
             (:line 702 :character 11)))
      (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
            (:start
             (:line 1583 :character 3)
             :end
             (:line 1583 :character 12)))
      (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
            (:start
             (:line 1584 :character 3)
             :end
             (:line 1584 :character 12)))
      (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
            (:start
             (:line 1593 :character 3)
             :end
             (:line 1593 :character 12)))
      (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
            (:start
             (:line 1594 :character 3)
             :end
             (:line 1594 :character 12)))
      (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
            (:start
             (:line 1595 :character 3)
             :end
             (:line 1595 :character 12)))
      (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
            (:start
             (:line 1604 :character 3)
             :end
             (:line 1604 :character 12)))
      (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/client_test.go" :range
            (:start
             (:line 1605 :character 3)
             :end
             (:line 1605 :character 12)))
      (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/cookie_test.go" :range
            (:start
             (:line 152 :character 1)
             :end
             (:line 152 :character 10)))
      (:uri "file:///usr/local/Cellar/go/1.10/libexec/src/net/http/cookie_test.go" :range
            (:start
             (:line 153 :character 1)
             :end
             (:line 153 :character 10)))
      (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range
            (:start
             (:line 101 :character 8)
             :end
             (:line 101 :character 17)))
      (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range
            (:start
             (:line 108 :character 8)
             :end
             (:line 108 :character 17)))
      (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range
            (:start
             (:line 138 :character 7)
             :end
             (:line 138 :character 16)))
      (:uri "file:///Users/asf/go/src/github.com/antifuchs/htpasswd-login/http.go" :range
            (:start
             (:line 192 :character 12)
             :end
             (:line 192 :character 21)))]
     :jsonrpc "2.0")

The stderr buffer is empty. I'm using go-langserver from github.com/sourcegraph/go-langserver at rev 1fe24b2b, and current master HEAD of eglot, 3ac4b64

clangd support

Hello,

I just wanted to know if eglot is supposed to work out of the box with clangd (if it does, which minimum version should be used).

Wrong :character position is reported by eglot's text sync functions when narrowing is in effect

When I use clangd and have a buffer with these contents:

int main()
{
    return;
}

and I narrow to the word return, and then insert 0 (space + 0) at the end of of the buffer, eglot sends the following notification to the server:

(:jsonrpc "2.0" :method "textDocument/didChange" :params
	  (:textDocument
	   (:uri "file:///tmp/proj/src/main.c" :version 4)
	   :contentChanges
	   [(:range
	     (:start
	      (:line 2 :character 6)
	      :end
	      (:line 2 :character 6))
	     :rangeLength 0 :text " ")
	    (:range
	     (:start
	      (:line 2 :character 7)
	      :end
	      (:line 2 :character 7))
	     :rangeLength 0 :text "0")]))

which is wrong, because the range of characters where the buffer changed is line 2, characters 10-11.
Eglot treats point-min as beginning of line in that case.

Request: Asynchronous completion backend

Hi, thanks for the package!

Working with completion-at-point/company-capf, it seems like completions are being done synchronously. Playing around with Emacs' codebase (window.c) and cquery, it seems there is slight lag/stutter when typing.

I gave a shot here but it seems too slow (typing latency is faster but completions take a while to return?) to be useable.

(setq-local company-backends '(company-eglot))
(setq-local company-idle-delay .01)

(defun company-eglot (command &optional arg &rest ignored)
  ""
  (interactive (list 'interactive))
  (cl-case command
    (interactive (company-begin-backend 'company-eglot))
    (prefix
     (not (company-in-string-or-comment))
     (or (company-grab-symbol-cons "\\.\\|->\\|::\\|/" 2)
         'stop)
     ;; `company' won't continue completion with this.
     ;; (when eglot--managed-mode
     ;;   (symbol-at-point))
     )
    (candidates
     (let ((current-buffer (current-buffer)))
       (cons
        :async
        (lambda (cb)
          (let ((server (eglot--current-server-or-lose)))
            (jsonrpc-async-request
             server
             :textDocument/completion
             (eglot--TextDocumentPositionParams)
             :deferred :textDocument/completion
             :success-fn
             (lambda (resp)
               (let* ((items (if (vectorp resp) resp (plist-get resp :items)))
                      (result (mapcar
                               (jsonrpc-lambda (&rest all &key label insertText &allow-other-keys)
                                 (let ((insert (or insertText label)))
                                   (add-text-properties 0 1 all insert)
                                   (put-text-property 0 1 'eglot--lsp-completion all insert)
                                   insert))
                               items)))
                 (with-current-buffer current-buffer
                   (funcall cb result))))
             :error-fn (lambda (error))))))))))

Request: eglot-ensure in an async manner

I am using KotlinLanguageServer (https://github.com/fwcd/KotlinLanguageServer) and using

(push '(kotlin-mode . ("kotlin-language-server")) eglot-server-programs)
(add-hook 'kotlin-mode-hook #'eglot-ensure)

kotlin-language-server takes a very long time to start up (upwards of 20-30 seconds) which blocks emacs from opening the file until the server is done starting up.

I've tried with/without eglot-ensure along with that server to narrow it down to this language server. (O f course there could be some other interactions between different packages).

Could provide a smaller emacs -Q repo if that would help but I think the main challenge is compiling the server.

Request: Auto installing/building language server

Trying out VsCode's integration of https://github.com/fwcd/KotlinLanguageServer, the install experience is very seemless. Upon entering a .kt (kotlin file), VsCode will open a small popup that asks to look up existing Kotlin extensions on the marketplace. Pressing 'install' on the list of available kotlin extensions 'installs' the extension/language server into a .vscode/extensions directory where the language server client then knows to point to that server.

It might be cool to try to provide some kind of auto-install/building which builds in some kind of custom user directory emacs users can set which eglot can then look for when trying to start the language server. I think there are a couple of other emacs packages that do auto install (or provide a command to do an install) (maybe rtags, irony-mode, meghanada, anaconda?, etc).

This might be out of scope for eglot but I thought I'd put a request in anyways.

Thanks!

Workspace configuration example?

I'm trying to use eglot-workspace-configuration and eglot-signal-didChangeConfiguration to configure pyls as described here

Could you give an example of how to translate the setting pyls.configurationSources set to ['flake8'] to a valid config alist?

Issue when trying to complete

without company-mode:

eglot--error: [eglot] Ooops: -32001: ~/**/**/node_modules/@types/react/package.json is not an absolute path

with company-mode:

Company: An error occurred in auto-begin
Company: backend company-capf error "[eglot] Ooops: -32001: ~/**/**/node_modules/@types/react/package.json is not an absolute path" with args (candidates im)

workspace path as lsp server command line option

Hi,

I'm trying to use java lsp and all is working great, but I need to pass a command line argument for the workspace path when starting the lsp server.

I do not see a way to do it with the current options, is there anyway I can accomplish that ?

(add-to-list 'eglot-server-programs '(java-mode . ("java"
                                                      "-Declipse.application=org.eclipse.jdt.ls.core.id1"
                                                      "-Dosgi.bundles.defaultStartLevel=4"
                                                      "-Declipse.product=org.eclipse.jdt.ls.core.product"
                                                      "-Dlog.protocol=true"
                                                      "-Dlog.level=ALL"
                                                      "-noverify"
                                                      "-Xmx1G"
                                                      "-jar" "plugins/org.eclipse.equinox.launcher_1.5.100.v20180611-1436.jar"
                                                      "-configuration" "config_mac")))

I should ad "-data" as the last option with project root. If I add a hardcoded path all works fine but I need this to be dynamic, ideally using (projectile-project-root) or something similar.

Thnx in advance and keep up the good work, eglot is really great!

Company doc buffer should be cleared between invocations

In eglot-completion-at-point at :company-doc-buffer, eglot appends the documentation to the same buffer. Which means that company help and company-quickhelp will display increasingly large documentation which is shared between all eglot servers.

For example if I get documentation in a Javascript project and then in a Python project. The documentation shows a large buffer of both.

company-mode has a helper function company-doc-buffer which can be used to create a documentation buffer, which is erased. Or the current implementation should just call erase-buffer when showing completions.

Eglot performance issues

Eglot slows down after a while, with each request taking a while to respond. This is happening with python language server. I am not sure if it is an issue with the flymake or eglot.

I would appreciate any tips on how to debug this issue.

Diagnostics error

I'm getting an error which seems to be caused by this line where eglot--make-diag is invoked with an extra argument.

Turn off message in new buffer

Every time I open a new file in a project with eglot running I get this message. Is there an option to disable it ?

`[eglot]` Automatically started `rustfmt' to manage `rustic-mode' buffers in project `rustfmt'

server died for c++-mode

[eglot] Ooops: -1: Server died

content in stderr buffer:

Process EGLOT (vbox_server/c++-mode) stderr finished
Assertion failed: (IsObject()), function FindMember, file ../../third_party/rapidjson/include/rapidjson/document.h, line 1233.
Assertion failed: (IsObject()), function FindMember, file ../../third_party/rapidjson/include/rapidjson/document.h, line 1233.

content in event buffer:

client-request (id:13):
(:jsonrpc "2.0" :id 13 :method :initialize :params
		  (:processId 74296 :capabilities
					  (:workspace
					   (:applyEdit t :workspaceEdit
								   (:documentChanges :json-false)
								   :didChangeWatchesFiles
								   (:dynamicRegistration t)
								   :symbol
								   (:dynamicRegistration :json-false))
					   :textDocument
					   (:synchronization
						(:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t)
						:completion
						(:dynamicRegistration :json-false)
						:hover
						(:dynamicRegistration :json-false)
						:signatureHelp
						(:dynamicRegistration :json-false)
						:references
						(:dynamicRegistration :json-false)
						:definition
						(:dynamicRegistration :json-false)
						:documentSymbol
						(:dynamicRegistration :json-false)
						:documentHighlight
						(:dynamicRegistration :json-false)
						:rename
						(:dynamicRegistration :json-false)
						:publishDiagnostics
						(:relatedInformation :json-false))
					   :experimental nil)
					  :rootPath "/Users/jun/Projects/repo1/vbox_server/" :rootUri "file:///Users/jun/work/share/linux/Projects/repo1/vbox_server/" :initializationOptions
					  [:cacheDirectory "/Users/jun/Projects/repo1/vbox_server/.cquery_cached_index/" :progressReportFrequencyMs -1]))

server-notification:
(:jsonrpc "2.0" :method "$cquery/progress" :params
		  (:indexRequestCount 0 :doIdMapCount 0 :loadPreviousIndexCount 0 :onIdMappedCount 0 :onIndexedCount 0 :activeThreads 0))

:internal-message:
(:message "Process state changed: (abort trap: 6\n)")


----------b---y---e---b---y---e----------

eglot-ensure throws error in post-command-hook

This doesn't happen everytime for me (50%?) but I am getting an error around eglot-ensure. After the error pops up, if I run eglot manually, eglot will connect fine.

configuration

(use-package eglot
  :ensure t
  :commands (eglot eglot-ensure)
  :init
  (defun eglot-disable-other-modes ()
    "Disable other modes that would conflict with `eglot'."
    (flycheck-mode -1) ;; Use `flymake' instead.
    (ggtags-mode -1)
    (ycmd-mode -1))
  (add-hook 'eglot--managed-mode-hook #'eglot-disable-other-modes)

  (add-hook 'c-mode-hook #'eglot-ensure)
  (add-hook 'c++-mode-hook #'eglot-ensure))

messages

[eglot] (warning) Server sent unknown notification method `$cquery/progress'
[eglot] Asking EGLOT (emacs/c-mode) politely to terminate
[jsonrpc] Server exited with status 0
Error in post-command-hook 

 [#<buffer window.c> (#0) eglot--managed-mode major-mode remove-hook post-command-hook nil buffer-live-p apply eglot--connect eglot--guess-contact eglot--message "Automatically started `%s' to manage `%s' buffers in project `%s'" jsonrpc-name eglot--project-nickname] 8]): (error "Selecting deleted buffer")

I'm opening window.c in emacs' codebase after generating a compile_commands.json (for use with cquery) file with:

make clean; bear make;

wrong-type-argument flymake--diag

Debugger entered--Lisp error: (wrong-type-argument flymake--diag #s(eglot--diag #<buffer utils.rs> 494 502 eglot-warning "rustc: unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" nil ((eglot-lsp-diag :code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc"))))
  signal(wrong-type-argument (flymake--diag #s(eglot--diag #<buffer utils.rs> 494 502 eglot-warning "rustc: unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" nil ((eglot-lsp-diag :code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc")))))
  flymake--highlight-line(#s(eglot--diag #<buffer utils.rs> 494 502 eglot-warning "rustc: unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" nil ((eglot-lsp-diag :code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc"))))
  #f(compiled-function (diag) #<bytecode 0x20d53ad>)(#s(eglot--diag #<buffer utils.rs> 494 502 eglot-warning "rustc: unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" nil ((eglot-lsp-diag :code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc"))))
  mapc(#f(compiled-function (diag) #<bytecode 0x20d53ad>) (#s(eglot--diag #<buffer utils.rs> 494 502 eglot-warning "rustc: unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" nil ((eglot-lsp-diag :code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc")))))
  flymake--handle-report(eglot-flymake-backend backend-token82 (#s(eglot--diag #<buffer utils.rs> 494 502 eglot-warning "rustc: unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" nil ((eglot-lsp-diag :code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc")))))
  apply(flymake--handle-report eglot-flymake-backend backend-token82 (#s(eglot--diag #<buffer utils.rs> 494 502 eglot-warning "rustc: unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" nil ((eglot-lsp-diag :code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc")))))
  #f(compiled-function (&rest args) #<bytecode 0x1f765b9>)((#s(eglot--diag #<buffer utils.rs> 494 502 eglot-warning "rustc: unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" nil ((eglot-lsp-diag :code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc")))))
  #f(compiled-function (arg1 arg2 &rest rest) "Handle notification publishDiagnostics" #<bytecode 0x18a9381>)(#<eglot-rls: EGLOT (rustfmt/rustic-mode)> :textDocument/publishDiagnostics :diagnostics [(:code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc")] :uri "file:///home/brotzeit/git/rustfmt/src/utils.rs")
  apply(#f(compiled-function (arg1 arg2 &rest rest) "Handle notification publishDiagnostics" #<bytecode 0x18a9381>) #<eglot-rls: EGLOT (rustfmt/rustic-mode)> (:textDocument/publishDiagnostics :diagnostics [(:code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc")] :uri "file:///home/brotzeit/git/rustfmt/src/utils.rs"))
  #f(compiled-function (arg &rest args) #<bytecode 0x1aab485>)(#<eglot-rls: EGLOT (rustfmt/rustic-mode)> :textDocument/publishDiagnostics :diagnostics [(:code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc")] :uri "file:///home/brotzeit/git/rustfmt/src/utils.rs")
  apply(#f(compiled-function (arg &rest args) #<bytecode 0x1aab485>) #<eglot-rls: EGLOT (rustfmt/rustic-mode)> :textDocument/publishDiagnostics (:diagnostics [(:code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc")] :uri "file:///home/brotzeit/git/rustfmt/src/utils.rs"))
  eglot-handle-notification(#<eglot-rls: EGLOT (rustfmt/rustic-mode)> :textDocument/publishDiagnostics :diagnostics [(:code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc")] :uri "file:///home/brotzeit/git/rustfmt/src/utils.rs")
  apply(eglot-handle-notification #<eglot-rls: EGLOT (rustfmt/rustic-mode)> :textDocument/publishDiagnostics (:diagnostics [(:code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc")] :uri "file:///home/brotzeit/git/rustfmt/src/utils.rs"))
  eglot--server-receive(#<eglot-rls: EGLOT (rustfmt/rustic-mode)> (:jsonrpc "2.0" :method "textDocument/publishDiagnostics" :params (:diagnostics [(:code "unused_imports" :message "unused import: `std::fmt`\n\nnote: #[warn(unused_imports)] on by default" :range (:end (:character 12 :line 11) :start (:character 4 :line 11)) :severity 2 :source "rustc")] :uri "file:///home/brotzeit/git/rustfmt/src/utils.rs")))
  eglot--process-filter(#<process EGLOT (rustfmt/rustic-mode)> "Content-Length: 93\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"window/progress\",\"params\":{\"id\":\"progress_10\",\"title\":\"Indexing\"}}Content-Length: 468\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"diagnostics\":[{\"code\":\"unused_parens\",\"message\":\"unnecessary parentheses around `if` condition\\n\\nnote: #[warn(unused_parens)] on by default\\nhelp: remove these parentheses: `self.len() == 1 || first_group_len == self.len()`\",\"range\":{\"end\":{\"character\":61,\"line\":312},\"start\":{\"character\":11,\"line\":312}},\"severity\":2,\"source\":\"rustc\"}],\"uri\":\"file:///home/brotzeit/git/rustfmt/src/attr.rs\"}}Content-Length: 364\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"diagnostics\":[{\"code\":\"unused_imports\",\"message\":\"unused import: `std::fmt`\\n\\nnote: #[warn(unused_imports)] on by default\",\"range\":{\"end\":{\"character\":12,\"line\":11},\"start\":{\"character\":4,\"line\":11}},\"severity\":2,\"source\":\"rustc\"}],\"uri\":\"file:///home/brotzeit/git/rustfmt/src/utils.rs\"}}")

This happens sometimes when I'm using xref-find-definitions with flymake turned off.

eglot + cquery: Killing buffer doesn't kill cquery

emacs -Q # emacs 27

(add-to-list 'load-path "/Users/james/.emacs.d/elpa/27/company-20180802.1207")
(require 'company)
(add-hook 'c-mode-hook 'company-mode)

(add-to-list 'load-path "/Users/james/.emacs.d/elpa/27/eglot-20180817.2356")
(require 'eglot)
(add-hook 'c-mode-hook 'eglot-ensure)

Visit a c file in home directory: (~/a.c) with find-file.

// Random c file with scratch code.

static void
pixel_window_scroll (Lisp_Object window, EMACS_INT n, bool whole, bool noerror)
{
  ptrdiff_t count = SPECPDL_INDEX ();

  n = clip_to_bounds (INT_MIN, n, INT_MAX);

  wset_redisplay (XWINDOW (window));

  if (whole && Vfast_but_imprecise_scrolling)
    specbind (Qfontification_functions, Qnil);

  /* If we must, use the pixel-based version which is much slower than
     the line-based one but can handle varying line heights.  */
  window_scroll_pixel_based (window, n, whole, noerror);

  unbind_to (count, Qnil);

  /* Bug#15957.  */
  XWINDOW (window)->window_end_valid = false;
}

static void
pixel_scroll_command (Lisp_Object window, Lisp_Object n, int direction)
{
  struct window *w;
  bool other_window;
  ptrdiff_t count = SPECPDL_INDEX ();

  eassert (eabs (direction) == 1);

  w = XWINDOW (window);
  other_window = !EQ (window, selected_window);

  /* If given window's buffer isn't current, make it current for the
     moment.  If the window's buffer is the same, but it is not the
     selected window, we need to save-excursion to avoid affecting
     point in the selected window (which would cause the selected
     window to scroll).  Don't screw up if window_scroll gets an
     error.  */
  if (other_window || XBUFFER (w->contents) != current_buffer)
    {
      record_unwind_protect_excursion ();
      if (XBUFFER (w->contents) != current_buffer)
        Fset_buffer (w->contents);
    }

  if (other_window)
    {
      SET_PT_BOTH (marker_position (w->pointm),
                   marker_byte_position (w->pointm));
      SET_PT_BOTH (marker_position (w->old_pointm),
                   marker_byte_position (w->old_pointm));
    }

  if (NILP (n))
    pixel_window_scroll (window, direction, true, false);
  else if (EQ (n, Qminus))
    pixel_window_scroll (window, -direction, true, false);
  else
    {
      n = Fprefix_numeric_value (n);
      pixel_window_scroll (window, XINT (n) * direction, false, false);
    }

  if (other_window)
    {
      set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
      set_marker_both (w->old_pointm, Qnil, PT, PT_BYTE);
    }

  unbind_to (count, Qnil);
}

DEFUN ("pixel-scroll-up", Fscroll_up, Sscroll_up, 0, 1, "^P",
       doc: /* Scroll text of selected window upward ARG lines.
If ARG is omitted or nil, scroll upward by a near full screen.
A near full screen is `next-screen-context-lines' less than a full screen.
Negative ARG means scroll downward.
If ARG is the atom `-', scroll downward by nearly full screen.
When calling from a program, supply as argument a number, nil, or `-'.  */)
(Lisp_Object arg)
{
  pixel_scroll_command (selected_window, arg, 1);
  return Qnil;
}

DEFUN ("pixel-scroll-down", Fscroll_down, Sscroll_down, 0, 1, "^P",
       doc: /* Scroll text of selected window down ARG lines.
If ARG is omitted or nil, scroll down by a near full screen.
A near full screen is `next-screen-context-lines' less than a full screen.
Negative ARG means scroll upward.
If ARG is the atom `-', scroll upward by nearly full screen.
When calling from a program, supply as argument a number, nil, or `-'.  */)
(Lisp_Object arg)
{
  pixel_scroll_command (selected_window, arg, -1);
  return Qnil;
}

{
  {
    {
      {
	{
	  {
	    {
	      
	    }
	  }
	}
      }
    }
  }
}

asdfsdffffffffffffsssssssssssssasdfasdfasdfasdffff

C-x k (kill-buffer) to kill buffer a.c.
screenshot 2018-08-18 09 52 39
screenshot 2018-08-18 09 52 42

~~

Second problem I encounter is if I kill cquery from the Activity Monitor (using 'Force Quit'), eglot will automatically restart cquery and reconnect to it, even though no buffer exists with eglot enabled (only one having been a.c which was killed earlier.)

screenshot 2018-08-18 09 53 16

eglot--mode-line-format is really slow

CPU profiling data:

- command-execute                                               30611  89%
 - call-interactively                                           30611  89%
  - apply                                                       30611  89%
   - call-interactively@ido-cr+-record-current-command              30611  89%
    - apply                                                     30611  89%
     - #<subr call-interactively>                               30611  89%
      - funcall-interactively                                   30611  89%
       - mwheel-scroll                                          27291  80%
        - pixel-scroll-down                                     21930  64%
         - pixel-point-at-bottom-p                              19179  56%
          - pixel-posn-y-at-point                               11808  34%
           - posn-at-point                                       8218  24%
            - eval                                               8213  24%
             - eglot--mode-line-format                           7896  23%
              - eglot--current-server                            7865  23%
               - project-current                                 7863  23%
                - project--find-in-directory                     7863  23%
                 - run-hook-with-args-until-success               7862  23%
                  - project-try-vc                               7862  23%
                   - vc-responsible-backend                      7859  23%
                    - vc-call-backend                            6243  18%
                     - apply                                     6243  18%
                      + vc-svn-responsible-p                     3282   9%
                      + vc-bzr-responsible-p                     2267   6%
                        vc-sccs-responsible-p                     385   1%
                        vc-src-responsible-p                      117   0%
                        vc-cvs-responsible-p                      103   0%
                        vc-rcs-responsible-p                       89   0%
                    + file-directory-p                              3   0%
                   + vc-call-backend                                2   0%
               + cl-find                                            1   0%
              + eglot--mode-line-props                             20   0%
              + jsonrpc-last-error                                  4   0%
              + eglot--spinner                                      1   0%
             + mode-line-auto-compile-control                     299   0%
               if                                                   6   0%
             + replace-regexp-in-string                             5   0%
               format                                               1   0%
             + mode-line-eol-desc                                   1   0%
               unless                                               1   0%
              file-remote-p                                         5   0%
             beginning-of-visual-line                             166   0%
          - pixel-visual-line-height                             7367  21%
           - pixel-visible-pos-in-window                         7236  21%
            - pos-visible-in-window-p                            5087  14%
             - eval                                              5080  14%
              + eglot--mode-line-format                          4772  14%
              + mode-line-auto-compile-control                    280   0%
                if                                                 16   0%
              + replace-regexp-in-string                            4   0%
                mode-line-eol-desc                                  1   0%
               file-remote-p                                        5   0%
              end-of-visual-line                                  191   0%
              beginning-of-visual-line                            184   0%
              delete-dups                                          11   0%
            + window-inside-pixel-edges                             6   0%
          + window-inside-pixel-edges                               3   0%
         + pixel-scroll-pixel-down                               1170   3%
         + pixel-line-height                                      569   1%
         + scroll-down                                            307   0%
           pixel-eob-at-top-p                                      12   0%
        - pixel-scroll-up                                        5358  15%
         - pixel-line-height                                     3625  10%
          - pixel-visual-line-height                             3625  10%
           - pixel-visible-pos-in-window                         3615  10%
            - pos-visible-in-window-p                            3556  10%
             - eval                                              3556  10%
              + eglot--mode-line-format                          3419  10%
              + mode-line-auto-compile-control                    133   0%
                if                                                  4   0%
              end-of-visual-line                                   25   0%
              beginning-of-visual-line                             17   0%
              delete-dups                                           3   0%
            + window-inside-pixel-edges                             1   0%
         + pixel-scroll-pixel-up                                  783   2%
         + pixel-point-at-top-p                                   585   1%
         + scroll-up                                              266   0%
          cancel-timer                                              3   0%
       + amx                                                     1717   5%
       + previous-line                                           1303   3%
       + next-line                                                237   0%
       + purpose-friendly-switch-buffer                            36   0%
       + windmove-up                                               14   0%
       + windmove-down                                             12   0%
       + file-notify-handle-event                                   1   0%
+ ...                                                            1482   4%
+ redisplay_internal (C function)                                1052   3%
+ timer-event-handler                                             689   2%
+ #<compiled 0x44c7c1ed>                                          110   0%
+ sp--save-pre-command-state                                       38   0%
+ ibuffer-auto-update-changed                                      26   0%
+ winner-save-old-configurations                                    4   0%
+ jit-lock-function                                                 3   0%
+ global-hl-line-maybe-unhighlight                                  1   0%
+ purpose-x-code1-debounced-update-changed                          1   0%
  company-post-command                                              1   0%

The cause appears to be eglot--current-server is calling project-current rather excessively under pixel-scroll-mode. project-current is a rather expensive operation because it does IO into the file system to find out the project boundary. Is there a way to cache the project data?

hover by cursor instead of mouse?

I wonder if there is the option to show errors in echo area when the cursor is on a piece of troublesome code? I searched for related code but didn't find any.

Support for snippet based completion

LSP servers support snippet based completion which can insert template arguments of the functions while completion.

Example of snippet based completion: https://i.stack.imgur.com/4gKHP.gif

The capability of snippet completion can be registered by setting TextDocumentClientCapabilities.completion.completionItem.snippetSupport to true, which is false by default.

Whether the completion item is plaintext or snippet is given by CompletionItem.kind field.

Yasnippet can be used to manage completion snippets. The support can be conditionally enabled if user has yasnippet installed so that package doesn't have hard dependency on yasnippet.

Events buffer constantly grows

Thanks for an awesome package!

Looks like there is no cleanup implemented for event buffer yet?

Or am I missing something?

Split the JSON-RPC API into a separate library

It would make the codebase simpler if JSON-RPC part is split into a separate library. I have an implementation of JSON-RPC for elisp which can be used. It uses native JSON functionality of Emacs 27 which can be backported with json.el for Emacs 26. If you are looking for contributions, I can modify the library and add it here.

"Terrible hack" in Emacs 27.0.50

Hi I'm using Emacs:

GNU Emacs 27.0.50 (build 1, x86_64-apple-darwin17.5.0, NS appkit-1561.40 Version 10.13.4 (Build 17E202)) of 2018-06-01

I noticed bug in eglot using flymake-make-diagnostics. It seems that eglot provides wrong number of arguments.

I also noticed your "horrible hack" for Emacs 26. After I changed condition to (when (version< emacs-version "27.1") (from "27.0") - it works fine.

Was this hack merged into Emacs master? Maybe I just need pull it and recompile?

Run environment aware language server instances

Right now it looks like running servers are not aware of environment variables of the emacs instance. This causes some problems, for example Python modules installed in project's virtual environment will not be available for auto-completion or documentation. Virtualenv switchers like pyvenv will set VIRTUAL_ENV variable and pyls reflects to its value. But when eglot loads pyls directly, modules installed in virtualenv are not available.

Error thrown when eglot called from hook

Hiya! I was trying to setup eglot like so:

(def-package! eglot
  :commands (eglot)
  :when EMACS26+
  :init
  (add-hook 'python-mode-hook #'eglot)
  :config
  (set! :company-backend 'eglot--managed-mode '(company-capf)))

Yet whenever I open a python file, this error is thrown:

Debugger entered--Lisp error: (wrong-number-of-arguments (4 . 5) 0)
  eglot()
  run-hooks(change-major-mode-after-body-hook prog-mode-hook python-mode-hook)
  apply(run-hooks (change-major-mode-after-body-hook prog-mode-hook python-mode-hook))
  run-mode-hooks(python-mode-hook)
  python-mode()

Funnily enough, once that error pops up, M-x eglot works fine.
This also happens in sh-mode, and that's the only other mode I've tested.

Completion error when there are multiple candidates

When there are multiple completion candidates,
with company-mode enabled:

Company: An error occurred in post-command
Company: frontend company-pseudo-tooltip-unless-just-one-frontend error "Company: backend company-capf error "Wrong type argument: stringp, nil" with args (annotation React)" on command post-command

without company-mode enabled and M-x completion-at-point:

Making completion list...
concat: Wrong type argument: stringp, nil

but with single completion candidate, it works fine:
screen shot 2018-07-06 at 3 42 19 pm

Enabling eglot in files outside current project after following xrefs

When I find a definition outside current project, eglot is either not enabled or enabled, but using a different server. I'd like to have it enabled and using the same server where it came from, unless I explicitly started it with eglot or there was already a server managing this buffer started with eglot-ensure, but not in a transient project.

Can't guess which server to use for `js2-mode` (and `rjsx-mode`)

js2-mode is very common, if not the most common mode to use for JavaScript development in emacs, and if you're using React, then rjsx-mode (derived from js2-mode) is also a very common.

However, eglot can't figure out which language server to use for these protocols.

2018-06-20 11 41 12

rls restart loop takes down emacs

I just tried eglot, and it seems quite reasonable! Unfortunately as soon as RLS crashed the first time (I used M-. on an identifier I probably shouldn't have), eglot restarted it, causing RLS to crash again, and so on - now my emacs window is empty and the minibuffer displays error in process sentinel: Lisp nesting exceeds 'max-lisp-eval-depth', which seems to indicate that there's infinite recursion going on.

I guess the retry logic may need an escape hatch & abort if the server crashes when running the command, say, twice?

error: (json-string-format "?\\C-@")

Debugger entered--Lisp error: (json-string-format "?\\C-@")
  signal(json-string-format ("?\\C-@"))
  json-read-string()
  json-read()
  json-read-object()
  json-read()
  json-read-object()
  json-read()
  (let* ((json-object-type 'plist) (json-message (json-read))) (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (eglot--server-receive (process-get proc 'eglot-server) json-message)) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))))
  (save-restriction (narrow-to-region (point) message-end) (let* ((json-object-type 'plist) (json-message (json-read))) (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (eglot--server-receive (process-get proc ...) json-message)) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))))
  (unwind-protect (save-restriction (narrow-to-region (point) message-end) (let* ((json-object-type 'plist) (json-message (json-read))) (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (eglot--server-receive ... json-message)) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))))) (goto-char message-end) (delete-region (point-min) (point)) (setq expected-bytes nil))
  (let* ((message-end (byte-to-position (+ (position-bytes (point)) expected-bytes)))) (unwind-protect (save-restriction (narrow-to-region (point) message-end) (let* ((json-object-type 'plist) (json-message (json-read))) (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn ...) (and ... ...)))))) (goto-char message-end) (delete-region (point-min) (point)) (setq expected-bytes nil)))
  (cond ((>= available-bytes expected-bytes) (let* ((message-end (byte-to-position (+ (position-bytes ...) expected-bytes)))) (unwind-protect (save-restriction (narrow-to-region (point) message-end) (let* ((json-object-type ...) (json-message ...)) (let (...) (save-current-buffer ... ...)))) (goto-char message-end) (delete-region (point-min) (point)) (setq expected-bytes nil)))) (t (setq done :waiting-for-more-bytes-in-this-message)))
  (let ((available-bytes (- (position-bytes (process-mark proc)) (position-bytes (point))))) (cond ((>= available-bytes expected-bytes) (let* ((message-end (byte-to-position (+ ... expected-bytes)))) (unwind-protect (save-restriction (narrow-to-region (point) message-end) (let* (... ...) (let ... ...))) (goto-char message-end) (delete-region (point-min) (point)) (setq expected-bytes nil)))) (t (setq done :waiting-for-more-bytes-in-this-message))))
  (cond ((not expected-bytes) (setq expected-bytes (and (search-forward-regexp "\\(?:.*: .*\15\n\\)*Content-Length: *\\([[:digit:]]+\\)\15\n\\(?:.*: .*\15\n\\)*\15\n" (+ (point) 100) t) (string-to-number (match-string 1)))) (if expected-bytes nil (setq done :waiting-for-new-message))) (t (let ((available-bytes (- (position-bytes (process-mark proc)) (position-bytes (point))))) (cond ((>= available-bytes expected-bytes) (let* ((message-end ...)) (unwind-protect (save-restriction ... ...) (goto-char message-end) (delete-region ... ...) (setq expected-bytes nil)))) (t (setq done :waiting-for-more-bytes-in-this-message))))))
  (while (not done) (cond ((not expected-bytes) (setq expected-bytes (and (search-forward-regexp "\\(?:.*: .*\15\n\\)*Content-Length: *\\([[:digit:]]+\\)\15\n\\(?:.*: .*\15\n\\)*\15\n" (+ (point) 100) t) (string-to-number (match-string 1)))) (if expected-bytes nil (setq done :waiting-for-new-message))) (t (let ((available-bytes (- (position-bytes ...) (position-bytes ...)))) (cond ((>= available-bytes expected-bytes) (let* (...) (unwind-protect ... ... ... ...))) (t (setq done :waiting-for-more-bytes-in-this-message)))))))
  (unwind-protect (while (not done) (cond ((not expected-bytes) (setq expected-bytes (and (search-forward-regexp "\\(?:.*: .*\15\n\\)*Content-Length: *\\([[:digit:]]+\\)\15\n\\(?:.*: .*\15\n\\)*\15\n" (+ ... 100) t) (string-to-number (match-string 1)))) (if expected-bytes nil (setq done :waiting-for-new-message))) (t (let ((available-bytes (- ... ...))) (cond ((>= available-bytes expected-bytes) (let* ... ...)) (t (setq done :waiting-for-more-bytes-in-this-message))))))) (process-put proc 'eglot-expected-bytes expected-bytes))
  (let ((expected-bytes (process-get proc 'eglot-expected-bytes)) (inhibit-read-only t) done) (save-excursion (goto-char (process-mark proc)) (insert string) (set-marker (process-mark proc) (point))) (unwind-protect (while (not done) (cond ((not expected-bytes) (setq expected-bytes (and (search-forward-regexp "\\(?:.*: .*\15\n\\)*Content-Length: *\\([[:digit:]]+\\)\15\n\\(?:.*: .*\15\n\\)*\15\n" ... t) (string-to-number ...))) (if expected-bytes nil (setq done :waiting-for-new-message))) (t (let ((available-bytes ...)) (cond (... ...) (t ...)))))) (process-put proc 'eglot-expected-bytes expected-bytes)))
  (save-current-buffer (set-buffer G2206) (let ((expected-bytes (process-get proc 'eglot-expected-bytes)) (inhibit-read-only t) done) (save-excursion (goto-char (process-mark proc)) (insert string) (set-marker (process-mark proc) (point))) (unwind-protect (while (not done) (cond ((not expected-bytes) (setq expected-bytes (and ... ...)) (if expected-bytes nil (setq done :waiting-for-new-message))) (t (let (...) (cond ... ...))))) (process-put proc 'eglot-expected-bytes expected-bytes))))
  (if (buffer-live-p G2206) (save-current-buffer (set-buffer G2206) (let ((expected-bytes (process-get proc 'eglot-expected-bytes)) (inhibit-read-only t) done) (save-excursion (goto-char (process-mark proc)) (insert string) (set-marker (process-mark proc) (point))) (unwind-protect (while (not done) (cond ((not expected-bytes) (setq expected-bytes ...) (if expected-bytes nil ...)) (t (let ... ...)))) (process-put proc 'eglot-expected-bytes expected-bytes)))))
  (let ((G2206 (process-buffer proc))) (if (buffer-live-p G2206) (save-current-buffer (set-buffer G2206) (let ((expected-bytes (process-get proc 'eglot-expected-bytes)) (inhibit-read-only t) done) (save-excursion (goto-char (process-mark proc)) (insert string) (set-marker (process-mark proc) (point))) (unwind-protect (while (not done) (cond (... ... ...) (t ...))) (process-put proc 'eglot-expected-bytes expected-bytes))))))
  eglot--process-filter(#<process EGLOT (rustfmt/rust-mode)> "Content-Length: 93\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"window/progress\",\"params\":{\"id\":\"progress_20\",\"title\":\"Indexing\"}}Content-Length: 1173\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"diagnostics\":[{\"code\":\"E0425\",\"message\":\"cannot find function `\303\266rewrite_doc_comment` in this scope\\n\\ndid you mean `rewrite_doc_comment`?\",\"range\":{\"end\":{\"character\":32,\"line\":142},\"start\":{\"character\":12,\"line\":142}},\"severity\":1,\"source\":\"rustc\"},{\"code\":\"E0658\",\"message\":\"non-ascii idents are not fully supported. (see issue #28979)\\n\\nhelp: add #![feature(non_ascii_idents)] to the crate attributes to enable\",\"range\":{\"end\":{\"character\":32,\"line\":142},\"start\":{\"character\":12,\"line\":142}},\"severity\":1,\"source\":\"rustc\"},{\"code\":\"E0425\",\"message\":\"cannot find function `\303\266rewrite_doc_comment` in this scope\\n\\ndid you mean `rewrite_doc_comment`?\",\"range\":{\"end\":{\"character\":32,\"line\":142},\"start\":{\"character\":12,\"line\":142}},\"severity\":1,\"source\":\"rustc\"},{\"code\":\"E0658\",\"message\":\"non-ascii idents are not fully supported. (see issue #28979)\\n\\nhelp: add #![feature(non_ascii_idents)] to the crate attributes to enable\",\"range\":{\"end\":{\"character\":32,\"line\":142},\"start\":{\"character\":12,\"line\":142}},\"severity\":1,\"source\":\"rustc\"}],\"uri\":\"file:///home/brotzeit/tmp/git/rustfmt/src/attr.rs\"}}Content-Length: 149\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"diagnostics\":[],\"uri\":\"file:///home/brotzeit/tmp/git/rustfmt/src/comment.rs\"}}Content-Length: 147\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"diagnostics\":[],\"uri\":\"file:///home/brotzeit/tmp/git/rustfmt/src/utils.rs\"}}Content-Length: 146\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"diagnostics\":[],\"uri\":\"file:///home/brotzeit/tmp/git/rustfmt/src/expr.rs\"}}Content-Length: 147\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"diagnostics\":[],\"uri\":\"file:///home/brotzeit/tmp/git/rustfmt/src/shape.rs\"}}Content-Length: 149\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"diagnostics\":[],\"uri\":\"file:///home/brotzeit/tmp/git/rustfmt/src/matches.rs\"}}")

I think I used eglot-code-actions before this error occured.

Applying TextEdits fails

In a buffer with these contents:
void foo(){}
Calling eglot-format-buffer when using clangd server results in:
void foo {}
Expected result is:
void foo() {}

This is because eglot--apply-text-edits calls eglot--range-region which returns wrong results when it's argument is an empty range (empty ranges are valid in LSP). This bug was introduced in 142cc5e.

Snippet based completion inserts text twice

When snippet based completion is triggered, the completion text is inserted twice with snippets enabled on second text.

I think the part of (delete-region (car bounds) (point)) in :exit-function is the culprit. I locally replaced it with (delete-backward-char (length obj)) and it works fine.

An API function for displaying list of xrefs

Some servers like eclipse.jdt.ls and cquery provide with code lens information where a symbol is referenced etc. I wonder if we could have an API function that all servers could use, for example eglot-show-xrefs which would take a list of locations and display them in a buffer, like M-.. There already is xref--show-xrefs, but it's xref's internal. Having such a function would make it easier to extend servers and would also make the UI consistent for all servers.

How to configure eglot to use flycheck?

I think eglot is great, but the default integration with flymake is lacking quite a bit, I was wondering if you could give a few pointers for those of us who prefer flycheck, or better yet, integrate with flycheck in eglot?

Problems changing major modes of eglot-managed buffers

Steps to reproduce:

  1. Visit a C header (in c-mode)
  2. M-x eglot
  3. M-x c++-mode
  4. Try to kill current buffer
  5. Buffer is not killed, error is signaled:

Debugger entered--Lisp error: (jsonrpc-error "No current JSON-RPC connection" (jsonrpc-error-code . 32603) (jsonrpc-error-message . "No current JSON-RPC connection"))

This is because kill-buffer-hook (which calls eglot--signal-textDocument/didClose) is a permanent local variable, which means it isn't cleared after changing major modes.

Start LSP server from project root

Currently, the language server is started in the working directory of the current file. The initializerequest sends the correct rootPath and rootUri.

Ideally, this should work, but some language servers (eg. metals scala lsp) have issues if not started in the project root. It would be better if we could start the server the project folder as we already know the folder in eglot--connect when initiating a connection.

eglot should flush recent changes before didSave notification

When I make a change in the buffer, and then immediately save it, didChange events are ran after didSave notifications. This leads to eglot and some servers having different document versions. This happens to me with eclipse.jdt.ls LSP server. Other servers that I tested simply ignore TextDocument/didSave notifications so it will never happen. Here is an example with eclipse.jdt.ls:

package com.frog.test;

public class App
{
    public static void main(String[] args)
    {
	int a;
    }
}
  1. Go to 7th line.
  2. M-x kill-whole-line
  3. Quickly do C-x C-s (before recent changes are sent)
client-notification Sat Aug  4 11:36:16 2018:
(:jsonrpc "2.0" :method "textDocument/didSave" :params
	  (:text "package com.frog.test;\n\npublic class App\n{\n    public static void main(String[] args)\n    {\n    }\n}\n" :textDocument
		 (:uri "file:///home/michal/src/eclipse-workspace/test/src/main/java/com/frog/test/App.java")))

server-notification Sat Aug  4 11:36:16 2018:
(:jsonrpc "2.0" :method "window/logMessage" :params
	  (:type 3 :message "Aug 4, 2018 11:36:16 AM >> document/didSave"))

client-notification Sat Aug  4 11:36:17 2018:
(:jsonrpc "2.0" :method "textDocument/didChange" :params
	  (:textDocument
	   (:uri "file:///home/michal/src/eclipse-workspace/test/src/main/java/com/frog/test/App.java" :version 2)
	   :contentChanges
	   [(:range
	     (:start
	      (:line 6 :character 0)
	      :end
	      (:line 6 :character 7))
	     :rangeLength 7 :text "")
	    (:range
	     (:start
	      (:line 6 :character 0)
	      :end
	      (:line 7 :character 0))
	     :rangeLength 1 :text "")]))

One solution to it is to ensure recent changes are flushed before every notification.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.