mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-05 22:20:24 -08:00
* doc/misc/eglot.texi (Eglot Features): Add comma after @xref. * msdos/sed2v2.inp (GNULIB_ISSYMLINK): Define to 1. * msdos/sedlibmk.inp (HAVE_RANDOM_H): Undefine, in line with its deletion from gnulib.mk. (GL_GNULIB_STRINGEQ): Define to 1. * src/msdos.c (careadlinkat): NULL terminate at the end of the data written, not one character beyond the same.
1771 lines
72 KiB
Text
1771 lines
72 KiB
Text
\input texinfo @c -*-texinfo-*-
|
|
@c %**start of header
|
|
@setfilename ../../eglot.info
|
|
@settitle Eglot: The Emacs Client for the Language Server Protocol
|
|
@include docstyle.texi
|
|
@syncodeindex vr cp
|
|
@syncodeindex fn cp
|
|
@c %**end of header
|
|
|
|
@copying
|
|
This manual is for Eglot, the Emacs LSP client.
|
|
|
|
Copyright @copyright{} 2022--2025 Free Software Foundation, Inc.
|
|
|
|
@quotation
|
|
Permission is granted to copy, distribute and/or modify this document
|
|
under the terms of the GNU Free Documentation License, Version 1.3 or
|
|
any later version published by the Free Software Foundation; with no
|
|
Invariant Sections, with the Front-Cover Texts being ``A GNU Manual'',
|
|
and with the Back-Cover Texts as in (a) below. A copy of the license is
|
|
included in the section entitled ``GNU Free Documentation License''.
|
|
|
|
(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and
|
|
modify this GNU manual.''
|
|
@end quotation
|
|
@end copying
|
|
|
|
@dircategory Emacs misc features
|
|
@direntry
|
|
* Eglot: (eglot). Language Server Protocol client for Emacs.
|
|
@end direntry
|
|
|
|
@titlepage
|
|
@sp 4
|
|
@c The title is printed in a large font.
|
|
@center @titlefont{User's Guide}
|
|
@sp 1
|
|
@center @titlefont{to}
|
|
@sp 1
|
|
@center @titlefont{Eglot: The Emacs LSP Client}
|
|
@ignore
|
|
@sp 2
|
|
@center release 1.8
|
|
@c -release-
|
|
@end ignore
|
|
@sp 3
|
|
@center Jo@~ao T@'avora & Eli Zaretskii
|
|
@c -date-
|
|
|
|
@page
|
|
@vskip 0pt plus 1filll
|
|
@insertcopying
|
|
@end titlepage
|
|
|
|
@contents
|
|
|
|
@ifnottex
|
|
@node Top
|
|
@top Eglot
|
|
|
|
@cindex LSP
|
|
@cindex language server protocol
|
|
Eglot is the Emacs client for the @dfn{Language Server Protocol}
|
|
(@acronym{LSP}). The name ``Eglot'' is an acronym that stands for
|
|
@ifhtml
|
|
``@emph{E}macs Poly@emph{glot}''.
|
|
@end ifhtml
|
|
@ifnothtml
|
|
``Emacs polyGLOT''.
|
|
@end ifnothtml
|
|
@footnote{ A @dfn{polyglot} is a person who is able to use several
|
|
languages. } Eglot provides infrastructure and a set of commands for
|
|
enriching the source code editing capabilities of Emacs via LSP@. LSP
|
|
is a standardized communications protocol between source code editors
|
|
(such as Emacs) and language servers---programs external to Emacs which
|
|
analyze the source code on behalf of Emacs. The protocol allows Emacs
|
|
to receive various source code services from the server, such as
|
|
description and location of function calls, types of variables, class
|
|
definitions, syntactic errors, etc. This way, Emacs doesn't need to
|
|
implement the language-specific parsing and analysis capabilities in its
|
|
own code, but is still capable of providing sophisticated editing
|
|
features that rely on such capabilities, such as automatic code
|
|
completion, go-to definition of function/class, documentation of symbol
|
|
at-point, refactoring, on-the-fly diagnostics, and more.
|
|
|
|
Eglot itself is completely language-agnostic, but it can support any
|
|
programming language for which there is a language server and an Emacs
|
|
major mode.
|
|
|
|
This manual documents how to configure, use, and customize Eglot.
|
|
|
|
@insertcopying
|
|
|
|
@menu
|
|
* Quick Start:: For the impatient.
|
|
* Eglot and LSP Servers:: How to work with language servers.
|
|
* Using Eglot:: Important Eglot commands and variables.
|
|
* Customizing Eglot:: Eglot customization and advanced features.
|
|
* Advanced server configuration:: Fine-tune a specific language server
|
|
* Extending Eglot:: Writing Eglot extensions in Elisp
|
|
* Troubleshooting Eglot:: Troubleshooting and reporting bugs.
|
|
* GNU Free Documentation License:: The license for this manual.
|
|
* Index::
|
|
@end menu
|
|
@end ifnottex
|
|
|
|
@node Quick Start
|
|
@chapter Quick Start
|
|
@cindex quick start
|
|
|
|
This chapter provides concise instructions for setting up and using
|
|
Eglot with your programming project in common usage scenarios. For more
|
|
detailed instructions regarding Eglot setup, @pxref{Eglot and LSP
|
|
Servers}. @xref{Using Eglot}, for detailed description of using Eglot,
|
|
and see @ref{Customizing Eglot}, for adapting Eglot to less common use
|
|
patterns.
|
|
|
|
Here's how to start using Eglot with your programming project:
|
|
|
|
@enumerate
|
|
@item
|
|
Select and install a language server.
|
|
|
|
Eglot comes pre-configured for many popular language servers, see the
|
|
value of @code{eglot-server-programs}. If the server(s) mentioned there
|
|
satisfy your needs for the programming language(s) with which you want
|
|
to use Eglot, you just need to make sure those servers are installed on
|
|
your system and Eglot can find them.
|
|
|
|
Alternatively, install one or more servers of your choice and tell Eglot
|
|
where to find them. To do that, you may add to the value of
|
|
@code{eglot-server-programs}, as described in @ref{Setting Up LSP
|
|
Servers} or have Eglot prompt you about it (@pxref{Eglot Commands}).
|
|
|
|
@item
|
|
Turn on Eglot for your project.
|
|
|
|
To start using Eglot for a project, type @kbd{M-x eglot @key{RET}} in a
|
|
buffer visiting any file that belongs to the project. This starts the
|
|
language server configured for the programming language of that buffer,
|
|
and causes Eglot to start @dfn{managing} file-visiting buffers related
|
|
to that programming language. This includes files that are already
|
|
visited at the time the @code{eglot} command is invoked, as well as any
|
|
files visited after this invocation.
|
|
|
|
The notion of a ``project'' used by Eglot is the same Emacs uses
|
|
(@pxref{Projects,,, emacs, GNU Emacs Manual}): in the simplest case, the
|
|
``project'' is the single file you are editing, but it can also be all
|
|
the files in a single directory or a directory tree under some version
|
|
control system, such as Git.
|
|
|
|
There are alternate ways of starting Eglot; see @ref{Starting Eglot}
|
|
for details.
|
|
|
|
@item
|
|
Use Eglot.
|
|
|
|
Most Eglot facilities are integrated into Emacs features, such as ElDoc,
|
|
Flymake, Xref, and Imenu. However, Eglot also provides commands of its
|
|
own, mainly to perform tasks by the language server, such as @kbd{M-x
|
|
eglot-rename} (to rename an identifier across the entire project),
|
|
@kbd{M-x eglot-format} (to reformat and reindent code), and some others.
|
|
@xref{Eglot Commands}, for the detailed list of Eglot commands.
|
|
|
|
@item
|
|
That's it!
|
|
@end enumerate
|
|
|
|
@node Eglot and LSP Servers
|
|
@chapter Eglot and LSP Servers
|
|
|
|
This chapter describes how to set up Eglot for your needs, and how to
|
|
start it.
|
|
|
|
@menu
|
|
* Setting Up LSP Servers:: How to configure LSP servers for your needs.
|
|
* Starting Eglot:: Ways of starting Eglot for your project.
|
|
* Shutting Down LSP Servers::
|
|
@end menu
|
|
|
|
@node Setting Up LSP Servers
|
|
@section Setting Up LSP Servers
|
|
@cindex setting up LSP server for Eglot
|
|
@cindex LSP server for Eglot, setting up
|
|
@cindex language server for Eglot
|
|
|
|
For Eglot to be useful, it must first be combined with a suitable
|
|
language server. Usually, that means running the server program locally
|
|
as a child process of Emacs (@pxref{Processes,,, elisp, GNU Emacs Lisp
|
|
Reference Manual}) and communicating with it via the standard input and
|
|
output streams.
|
|
|
|
The language server program must be installed separately, and is not
|
|
further discussed in this manual; refer to the documentation of the
|
|
particular server(s) you want to install.
|
|
|
|
To use a language server, Eglot must know how to start it and which
|
|
programming languages each server supports. This information is
|
|
commonly provided by the variable @code{eglot-server-programs}.
|
|
|
|
@defvar eglot-server-programs
|
|
This variable associates major modes with names and command-line
|
|
arguments of the language server programs corresponding to the
|
|
programming language of each major mode. It provides all the
|
|
information that Eglot needs to know about the programming language of
|
|
the source you are editing.
|
|
|
|
The value of the variable is an alist, whose elements are of the form
|
|
@w{@code{(@var{major-mode} . @var{server})}}.
|
|
|
|
The @var{major-mode} of the alist elements can be either a symbol of an
|
|
Emacs major mode or a list of the form @w{@code{(@var{mode} :language-id
|
|
@var{id})}}, with @var{mode} being a major-mode symbol and @var{id} a
|
|
string that identifies the language to the server (if Eglot cannot by
|
|
itself convert the major-mode to the language identifier string required
|
|
by the server). In addition, @var{major-mode} can be a list of several
|
|
major modes specified in one of the above forms -- this means a running
|
|
instance of the associated server is responsible for files of multiple
|
|
major modes or languages in the project.
|
|
|
|
The @var{server} part of the alist elements can be one of the following:
|
|
|
|
@table @code
|
|
@item (@var{program} @var{args}@dots{})
|
|
This says to invoke @var{program} with zero or more arguments
|
|
@var{args}; the program is expected to communicate with Emacs via the
|
|
standard input and standard output streams.
|
|
|
|
@item (@var{program} @var{args}@dots{} :initializationOptions @var{options}@dots{})
|
|
@var{program} is invoked with @var{args} but @var{options} specifies how
|
|
to construct the @samp{:initializationOptions} JSON object to pass the
|
|
server on during the LSP handshake (@pxref{Advanced server
|
|
configuration}).
|
|
|
|
@item (@var{host} @var{port} @var{args}@dots{})
|
|
Here @var{host} is a string and @var{port} is a positive integer
|
|
specifying a TCP connection to a remote server. The @var{args} are
|
|
passed to @code{open-network-stream}, e.g.@: if the connection needs to
|
|
use encryption or other non-default parameters (@pxref{Network,,, elisp,
|
|
GNU Emacs Lisp Reference Manual}).
|
|
|
|
@item (@var{program} @var{args}@dots{} :autoport @var{moreargs}@dots{})
|
|
@var{program} is started with a command line constructed from @var{args}
|
|
followed by an available server port and the rest of arguments in
|
|
@var{moreargs}; Eglot then establishes a TCP connection with the server
|
|
via that port on the local host.
|
|
|
|
@item @var{function}
|
|
This should be a function of a single argument: non-@code{nil} if the
|
|
connection was requested interactively (e.g., by the @code{eglot}
|
|
command), otherwise @code{nil}. The function should return a value of
|
|
any of the forms described above. This allows interaction with the user
|
|
for determining the program to start and its command-line arguments.
|
|
@end table
|
|
|
|
@end defvar
|
|
|
|
Eglot comes with a fairly complete set of associations of major-modes to
|
|
popular language servers predefined. If you need to add server
|
|
associations to the default list, use @code{add-to-list}. For example,
|
|
if there is a hypothetical language server program @command{fools} for
|
|
the language @code{Foo} which is supported by an Emacs major-mode
|
|
@code{foo-mode}, you can add it to the alist like this:
|
|
|
|
@lisp
|
|
(with-eval-after-load 'eglot
|
|
(add-to-list 'eglot-server-programs
|
|
'(foo-mode . ("fools" "--stdio"))))
|
|
@end lisp
|
|
|
|
This will invoke the program @command{fools} with the command-line
|
|
argument @option{--stdio} in support of editing source files for which
|
|
Emacs turns on @code{foo-mode}, and will communicate with the program
|
|
via the standard streams. As usual with invoking programs, the
|
|
executable file @file{fools} should be in one of the directories
|
|
mentioned by the @code{exec-path} variable (@pxref{Subprocess
|
|
Creation,,, elisp, GNU Emacs Lisp Reference Manual}), for Eglot to be
|
|
able to find it.
|
|
|
|
Sometimes, multiple servers are acceptable alternatives for handling a
|
|
given major-mode. In those cases, you may combine the helper function
|
|
@code{eglot-alternatives} with the functional form of
|
|
@code{eglot-server-programs}.
|
|
|
|
@lisp
|
|
(with-eval-after-load 'eglot
|
|
(add-to-list 'eglot-server-programs
|
|
`(foo-mode . ,(eglot-alternatives
|
|
'(("fools" "--stdio")
|
|
("phewls" "--fast"))))))
|
|
@end lisp
|
|
|
|
If you have @command{fools} and @command{phewls} installed, the function
|
|
produced by @code{eglot-alternatives} will prompt for the server to use
|
|
in @code{foo-mode} buffers. Else it will use whichever is available.
|
|
|
|
@node Starting Eglot
|
|
@section Starting Eglot
|
|
@cindex starting Eglot
|
|
@cindex activating Eglot for a project
|
|
|
|
@findex eglot
|
|
The most common way to start Eglot is to simply visit a source file of a
|
|
given language and use the command @kbd{M-x eglot}. This starts the
|
|
language server suitable for the visited file's major-mode, and attempts
|
|
to connect to it. If the connection to the language server is
|
|
successful, you will see the @code{[eglot:@var{project}]} indicator on
|
|
the mode line which reflects the server that was started. If the server
|
|
program couldn't be started or connection to it failed, you will see an
|
|
error message; in that case, try to troubleshoot the problem as
|
|
described in @ref{Troubleshooting Eglot}. Once a language server was
|
|
successfully started and Eglot connected to it, you can immediately
|
|
start using the Emacs features supported by Eglot, as described in
|
|
@ref{Eglot Features}.
|
|
|
|
A single Eglot session for a certain major-mode usually serves all the
|
|
buffers under that mode which visit files from the same project, so you
|
|
don't need to invoke @kbd{M-x eglot} again when you visit another file
|
|
from the same project which is edited using the same major-mode. This
|
|
is because Eglot uses the Emacs project infrastructure, as described in
|
|
@ref{Eglot and Buffers}, and this knows about files that belong to the
|
|
same project. Thus, after starting an Eglot session for some buffer,
|
|
that session is automatically reused when visiting files in the same
|
|
project with the same major-mode.
|
|
|
|
@findex eglot-ensure
|
|
Alternatively, you could configure Eglot to start automatically for one
|
|
or more major-modes from the respective mode hooks. Here's an example
|
|
for a hypothetical @code{foo-mode}:
|
|
|
|
@lisp
|
|
(add-hook 'foo-mode-hook 'eglot-ensure)
|
|
@end lisp
|
|
|
|
@noindent
|
|
The function @code{eglot-ensure} will start an Eglot session for each
|
|
buffer in which @code{foo-mode} is turned on, if there isn't already an
|
|
Eglot session that handles the buffer. Note that this variant of
|
|
starting an Eglot session is non-interactive, so it should be used only
|
|
when you are confident that Eglot can be started reliably for any file
|
|
which may be visited with the major-mode in question.
|
|
|
|
Note that it's often difficult to establish this confidence fully, so it
|
|
may be wise to use the interactive command @code{eglot} instead. You
|
|
only need to invoke it once per project, as all other files visited
|
|
within the same project will automatically be managed with no further
|
|
user intervention needed.
|
|
|
|
When Eglot connects to a language server for the first time in an Emacs
|
|
session, it runs the hook @code{eglot-connect-hook} (@pxref{Other
|
|
Variables}).
|
|
|
|
@node Shutting Down LSP Servers
|
|
@section Shutting Down LSP Servers
|
|
@cindex shutting down LSP server
|
|
|
|
When Eglot is turned on, it arranges for turning itself off
|
|
automatically if the language server process terminates. Turning off
|
|
Eglot means that it shuts down the server connection, ceases its
|
|
management of all the buffers that use the server connection which was
|
|
terminated, deactivates its minor mode, and restores the original values
|
|
of the Emacs variables that Eglot changed when it was turned on.
|
|
@xref{Eglot and Buffers}, for more details of what Eglot management of a
|
|
buffer entails.
|
|
|
|
@findex eglot-shutdown
|
|
You can also shut down a language server manually, by using the command
|
|
@kbd{M-x eglot-shutdown}. This prompts for the server (unless there's
|
|
only one connection and it's used in the current buffer), and then shuts
|
|
it down. By default, it also kills the server's events buffer
|
|
(@pxref{Troubleshooting Eglot}), but a prefix argument prevents that.
|
|
|
|
Alternatively, you can customize the variable @code{eglot-autoshutdown}
|
|
to a non-@code{nil} value, in which case Eglot will automatically shut
|
|
down the language server process when the last buffer served by that
|
|
language server is killed. The default of this variable is @code{nil},
|
|
so that visiting another file would automatically activate Eglot even
|
|
when the project which started Eglot with the server no longer has any
|
|
buffer associated with it. This default allows you to start a server
|
|
only once in each Emacs session.
|
|
|
|
@node Using Eglot
|
|
@chapter Using Eglot
|
|
|
|
This chapter describes in detail the features that Eglot provides and
|
|
how it does that. It also provides reference sections for Eglot
|
|
commands and variables.
|
|
|
|
@menu
|
|
* Eglot Features::
|
|
* Eglot and Buffers::
|
|
* Eglot Commands::
|
|
@end menu
|
|
|
|
@node Eglot Features
|
|
@section Eglot Features
|
|
@cindex features in buffers supported by Eglot
|
|
|
|
While Eglot is enabled in a buffer, it is said to be @dfn{managing} it,
|
|
using LSP and the specific capabilities of the language server to
|
|
activate and enhance modern IDE features in Emacs. Some of these
|
|
features are provided via other Emacs packages, and some via Eglot
|
|
directly (@pxref{Eglot Commands}).
|
|
|
|
Here's an overview of the main features that Eglot provides:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
At-point documentation: when point is near a symbol or an identifier,
|
|
information about the identifier's significance in the program (its
|
|
function or method signature, its type, its custom documentation string,
|
|
etc.) is made available via the ElDoc package (@pxref{Programming
|
|
Language Doc,,, emacs, GNU Emacs Manual}).
|
|
|
|
@item
|
|
On-the-fly diagnostic annotations, via the Flymake package
|
|
(@pxref{Top,,, Flymake, GNU Flymake manual}). Eglot's Flymake backend
|
|
replaces other Flymake backends while it is managing a buffer, and
|
|
enhances diagnostics with interactive server-suggested fixes (so-called
|
|
@dfn{code actions}, @pxref{Eglot Commands}).
|
|
|
|
@item
|
|
Finding definitions and uses of identifiers, via Xref (@pxref{Xref,,,
|
|
emacs, GNU Emacs Manual}). Eglot provides a backend for the Xref
|
|
capabilities which uses the language-server understanding of the program
|
|
source. In particular, it eliminates the need to generate tags tables
|
|
(@pxref{Tags tables,,, emacs, GNU Emacs Manual}) for languages which are
|
|
only supported by the @code{etags} backend.
|
|
|
|
@item
|
|
Buffer navigation by name of function, class, method, etc., via Imenu
|
|
(@pxref{Imenu,,, emacs, GNU Emacs Manual}). Eglot provides its own
|
|
variant of @code{imenu-create-index-function}, which generates the index
|
|
for the buffer based on language-server program source analysis.
|
|
|
|
@item
|
|
Enhanced completion of symbol at point by the @code{completion-at-point}
|
|
command (@pxref{Symbol Completion,,, emacs, GNU Emacs Manual}). This
|
|
uses the language-server's parser data for the completion candidates.
|
|
|
|
@item
|
|
Server-suggested code refactorings. The ElDoc package is also leveraged
|
|
to retrieve so-called @dfn{code actions} nearby point. When such
|
|
suggestions are available they are annotated with a special indication
|
|
and can be easily invoked by the user with the @code{eglot-code-action}
|
|
command (@pxref{Eglot Commands}).
|
|
|
|
@item
|
|
On-the-fly succinct informative annotations, so-called @dfn{inlay
|
|
hints}. Eglot adds special intangible text nearby certain identifiers,
|
|
be it the type of a variable, or the name of a formal parameter in a
|
|
function call. @xref{Eglot Commands}, and the
|
|
@code{eglot-inlay-hints-mode} minor mode.
|
|
|
|
@item
|
|
Display of function call and type hierarchies via the
|
|
@code{eglot-show-call-hierarchy} and @code{eglot-show-type-hierarchy}
|
|
commands (@pxref{Eglot Commands}).
|
|
|
|
@item
|
|
Code reformatting via the @code{eglot-format} and related commands
|
|
(@pxref{Eglot Commands}). Automatic reformatting of source code is also
|
|
supported and is activated automatically as you type.
|
|
|
|
@item
|
|
If a completion package such as the Company package (a popular
|
|
third-party completion package providing @code{company-mode}), is
|
|
installed, Eglot enhances it by providing completion candidates based on
|
|
the language-server analysis of the source code. (Company can be
|
|
installed from GNU ELPA.)
|
|
|
|
@item
|
|
If YASnippet, a popular third-party package for automatic insertion of
|
|
code templates (snippets), is installed, and the language server
|
|
supports snippet completion candidates, Eglot arranges for the
|
|
completion package to instantiate these snippets using YASnippet.
|
|
(YASnippet can be installed from GNU ELPA.)
|
|
|
|
@item
|
|
If the popular third-party package @code{markdown-mode} is installed,
|
|
and the server provides at-point documentation formatted as Markdown in
|
|
addition to plain text, Eglot arranges for the ElDoc package to enrich
|
|
this text with fontifications and other nice formatting before
|
|
displaying it to the user. This makes the documentation shown by ElDoc
|
|
look nicer on display.
|
|
|
|
@item
|
|
In addition to enabling and enhancing other features and packages, Eglot
|
|
also provides a number of user commands based on the capabilities of
|
|
language servers. Examples include renaming symbols with
|
|
@kbd{eglot-rename} and asking to automatically correct problems with
|
|
@kbd{eglot-code-actions}. @xref{Eglot Commands}.
|
|
@end itemize
|
|
|
|
Not all servers support the full set of LSP capabilities, but most of
|
|
them support enough to enable the basic set of features mentioned above.
|
|
|
|
Conversely, some servers offer capabilities for which no equivalent
|
|
Emacs package exists yet, and so Eglot cannot (yet) expose these
|
|
capabilities to Emacs users. However, @xref{Extending Eglot}.
|
|
|
|
Finally, it's worth noting that, by default, Eglot generally turns on
|
|
all features that it @emph{can} turn on. It's possible to opt out of
|
|
some features via user options (@pxref{Customizing Eglot}) and a hook
|
|
that runs after Eglot starts managing a buffer (@pxref{Eglot and
|
|
Buffers}).
|
|
|
|
@node Eglot and Buffers
|
|
@section Buffers, Projects, and Eglot
|
|
@cindex buffers managed by Eglot
|
|
@cindex projects and Eglot
|
|
|
|
@cindex workspace
|
|
One of the main strong points of using a language server is that a
|
|
language server has a broad view of the program: it considers more than
|
|
just the single source file you are editing. Ideally, the language
|
|
server should know about all the source files of your program which are
|
|
written in the language supported by the server. In the language-server
|
|
parlance, the set of the source files of a program is known as a
|
|
@dfn{workspace}. The Emacs equivalent of a workspace is a @dfn{project}
|
|
(@pxref{Projects,,, emacs, GNU Emacs Manual}). Eglot fully supports
|
|
Emacs projects, and considers the file in whose buffer Eglot is turned
|
|
on as belonging to a project. In the simplest case, that file is the
|
|
entire project, i.e.@: your project consists of a single file. But
|
|
there are other more complex projects:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
A single-directory project: several source files in a single common
|
|
directory.
|
|
|
|
@item
|
|
A VC project: source files in a directory hierarchy under some VCS,
|
|
e.g.@: a VCS repository (@pxref{Version Control,,, emacs, GNU Emacs
|
|
Manual}).
|
|
|
|
@item
|
|
An EDE project: source files in a directory hierarchy managed via the
|
|
Emacs Development Environment (@pxref{EDE,,, emacs, GNU Emacs
|
|
Manual}).
|
|
@end itemize
|
|
|
|
Eglot uses Emacs's project management infrastructure to figure out which
|
|
files and buffers belong to what project, so any kind of project
|
|
supported by that infrastructure is automatically supported by Eglot.
|
|
|
|
When Eglot starts a server program, it does so in the project's root
|
|
directory, which is usually the top-level directory of the project's
|
|
directory hierarchy. This ensures the language server has the same
|
|
comprehensive view of the project's files as you do.
|
|
|
|
For example, if you visit the file @file{~/projects/fooey/lib/x.foo} and
|
|
@file{x.foo} belongs to a project rooted at @file{~/projects/fooey}
|
|
(perhaps because a @file{.git} directory exists there), then @kbd{M-x
|
|
eglot} causes the server program to start with that root as the current
|
|
working directory. The server then will analyze not only the file
|
|
@file{lib/x.foo} you visited, but likely also all the other @file{*.foo}
|
|
files under the @file{~/projects/fooey} directory.
|
|
|
|
In some cases, additional information specific to a given project will
|
|
need to be provided to the language server when starting it. The
|
|
variable @code{eglot-workspace-configuration} (@pxref{Customizing
|
|
Eglot}) exists for that purpose. It specifies the parameters and their
|
|
values to communicate to each language server which needs that.
|
|
|
|
When Eglot is active for a project, the project's buffers are treated
|
|
specially in several ways:
|
|
|
|
@itemize @bullet
|
|
@cindex mode-line indication of language server
|
|
@cindex mouse clicks on mode-line, and Eglot
|
|
@vindex eglot-menu
|
|
@item
|
|
All of the project's file-visiting buffers under the same major-mode are
|
|
served by a single language-server connection. (If the project uses
|
|
several programming languages, there will usually be a separate server
|
|
connection for each group of files written in the same language and
|
|
using the same Emacs major-mode.) Eglot adds the
|
|
@samp{[eglot:@var{project}]} indication to the mode line of each such
|
|
buffer, where @var{server} is the name of the server and @var{project}
|
|
identifies the project by its root directory. Clicking the mouse on the
|
|
Eglot mode-line indication activates a menu with server-specific items.
|
|
The layout of the Eglot mode-line can be changed by customizing
|
|
@code{eglot-mode-line-format} (@pxref{Customization Variables}).
|
|
|
|
@item
|
|
For each buffer in which Eglot is active, it notifies the language
|
|
server that Eglot is @dfn{managing} the file visited by that buffer.
|
|
This tells the language server that the file's contents on disk may no
|
|
longer be up-to-date due to unsaved edits. Eglot reports to the server
|
|
any changes in the text of each managed buffer, to make the server aware
|
|
of unsaved changes. This includes your editing of the buffer and also
|
|
changes done automatically by other Emacs features and commands.
|
|
Killing a buffer relinquishes its management by Eglot and notifies the
|
|
server that the file on disk is up-to-date.
|
|
|
|
@item
|
|
When you visit a file under the same project, whether an existing or a
|
|
new file, its buffer is automatically added to the set of buffers
|
|
managed by Eglot, and the server which supports the buffer's major-mode
|
|
is notified about that. Thus, visiting a non-existent file
|
|
@file{/home/joe/projects/fooey/lib/y.foo} in the above example will
|
|
notify the server of the @file{*.foo} files' language that a new file
|
|
was added to the project, even before the file appears on disk. The
|
|
special Eglot minor mode is also turned on automatically in the buffer
|
|
visiting the file.
|
|
|
|
@item
|
|
Eglot turns on a special minor mode in each buffer it manages. This
|
|
minor mode ensures the server is notified about files Eglot manages.
|
|
Unlike other minor-modes, this special minor mode is @emph{not}
|
|
activated manually by the user, but automatically, as the result of
|
|
starting an Eglot session for the buffer. When Eglot stops managing the
|
|
buffer, the minor mode is turned off, and all the settings that Eglot
|
|
changed are restored to their original values.
|
|
|
|
@vindex eglot-managed-mode-hook
|
|
@vindex eglot-managed-p
|
|
@item
|
|
The minor mode's main job is to ``hook up'' Eglot to other Emacs
|
|
functionality, i.e. arrange for these features to receive information
|
|
from the language server, by changing special variables controlling
|
|
these features. @xref{Eglot Features}.
|
|
|
|
@item
|
|
To customize this, Eglot's special minor mode provides a hook variable
|
|
@code{eglot-managed-mode-hook} specifically to alter Eglot's interaction
|
|
with these variables in each buffer. This hook is run both when the
|
|
minor mode is turned on and when it's turned off; use the function
|
|
@code{eglot-managed-p} to tell if current buffer is still being managed
|
|
or not.
|
|
@end itemize
|
|
|
|
@node Eglot Commands
|
|
@section Eglot Commands
|
|
@cindex commands, Eglot
|
|
|
|
This section provides a reference for the most commonly used Eglot
|
|
commands:
|
|
|
|
@ftable @code
|
|
@item M-x eglot
|
|
This command adds the current buffer and the file it visits to the group
|
|
of buffers and files managed by Eglot on behalf of a suitable language
|
|
server. If a language server for the buffer's @code{major-mode}
|
|
(@pxref{Major Modes,,, emacs, GNU Emacs Manual}) is not yet running, it
|
|
will be started; otherwise the buffer and its file will be added to
|
|
those managed by an existing server session.
|
|
|
|
The command attempts to figure out the buffer's major mode and the
|
|
suitable language server; in case it fails, it might prompt for the
|
|
major mode to use and for the server program to start. If invoked with
|
|
@kbd{C-u}, it always prompts for the server program, and if invoked with
|
|
@kbd{C-u C-u}, it also prompts for the major mode.
|
|
|
|
If the language server is successfully started and contacted, this
|
|
command arranges for any other buffers belonging to the same project and
|
|
using the same major mode to use the same language-server session. That
|
|
includes any buffers created by visiting files after this command
|
|
succeeds to connect to a language server.
|
|
|
|
All the Emacs features that are capable of using Eglot services
|
|
(@pxref{Eglot Features}) are automatically configured by this command to
|
|
start using the language server via Eglot. To customize which Emacs
|
|
features will be configured to use Eglot, use the
|
|
@code{eglot-stay-out-of} option (@pxref{Customizing Eglot}).
|
|
|
|
@item M-x eglot-reconnect
|
|
This command shuts down the current connection to the language server
|
|
and immediately restarts it using the same options used originally.
|
|
This can sometimes be useful to unclog a partially malfunctioning server
|
|
connection.
|
|
|
|
@item M-x eglot-shutdown
|
|
This command shuts down a language server. It prompts for a language
|
|
server to shut down (unless there's only one server session, and it
|
|
manages the current buffer). Then the command shuts down the server and
|
|
stops managing the buffers the server was used for. Emacs features
|
|
(@pxref{Eglot Features}) that Eglot configured to work with the language
|
|
server are restored back to their original configuration.
|
|
|
|
Normally, this command kills the buffers used for communicating with the
|
|
language server, but if invoked with a prefix argument @kbd{C-u}, the
|
|
command doesn't kill those buffers, allowing them to be used for
|
|
diagnostics and problem reporting (@pxref{Troubleshooting Eglot}).
|
|
|
|
@item M-x eglot-shutdown-all
|
|
This command shuts down all the language servers active in the current
|
|
Emacs session. As with @code{eglot-shutdown}, invoking this command
|
|
with a prefix argument avoids killing the buffers used for
|
|
communications with the language servers.
|
|
|
|
@item M-x eglot-rename
|
|
This command renames the program symbol (a.k.a.@: @dfn{identifier}) at
|
|
point to another name. It prompts for the new name of the symbol, and
|
|
then modifies all the files in the project which are managed by the
|
|
language server of the current buffer to implement the renaming.
|
|
|
|
@item M-x eglot-format
|
|
This command reformats the active region according to the
|
|
language-server rules. If no region is active, it reformats the entire
|
|
current buffer.
|
|
|
|
@item M-x eglot-format-buffer
|
|
This command reformats the current buffer, in the same manner as
|
|
@code{eglot-format} does.
|
|
|
|
@cindex code actions
|
|
@item M-x eglot-code-actions
|
|
@itemx M-x eglot-code-action-organize-imports
|
|
@itemx M-x eglot-code-action-quickfix
|
|
@itemx M-x eglot-code-action-extract
|
|
@itemx M-x eglot-code-action-inline
|
|
@itemx M-x eglot-code-action-rewrite
|
|
These commands allow you to invoke the so-called @dfn{code actions}:
|
|
requests for the language server to provide editing commands for
|
|
correcting, refactoring or beautifying your code. These commands may
|
|
affect more than one visited file belonging to the project.
|
|
|
|
The command @code{eglot-code-actions} asks the server if there are any
|
|
code actions for any point in the buffer or contained in the active
|
|
region. If there are, you have the choice to execute one of them via
|
|
the minibuffer.
|
|
|
|
A common use of code actions is fixing the Flymake error diagnostics
|
|
issued by Eglot (@pxref{Top,,, Flymake, GNU Flymake manual}). Clicking
|
|
on a diagnostic with @kbd{mouse-2} invokes
|
|
@code{eglot-code-actions-at-mouse} which pops up a menu of available
|
|
code actions. The variable @code{eglot-diagnostics-map} can be used to
|
|
control the mouse binding.
|
|
|
|
Other commands execute a specific code action. For example,
|
|
@code{eglot-code-action-organize-imports} rearranges the program's
|
|
@dfn{imports}---declarations of modules whose capabilities the program
|
|
uses.
|
|
|
|
@cindex inlay hints
|
|
@item M-x eglot-inlay-hints-mode
|
|
This command toggles LSP @dfn{inlay hints} on and off for the current
|
|
buffer. Inlay hints are small text annotations to specific parts of the
|
|
whole buffer, not unlike diagnostics, but designed to help readability
|
|
instead of indicating problems. For example, a C++ language server can
|
|
serve hints about positional parameter names in function calls and a
|
|
variable's automatically deduced type. Inlay hints help the user not
|
|
have to remember these things by heart.
|
|
|
|
@cindex type hierarchy
|
|
@item M-x eglot-show-type-hierarchy
|
|
Pop up a special buffer showing a interactive tree which represents a
|
|
hierarchy of subtypes and supertypes for the symbol at point.
|
|
|
|
@cindex call hierarchy
|
|
@item M-x eglot-call-type-hierarchy
|
|
Pop up a special buffer showing a interactive tree which represents a
|
|
hierarchy of callers and callee for the symbol at point.
|
|
@end ftable
|
|
|
|
The following Eglot commands are used less commonly, mostly for
|
|
diagnostic and troubleshooting purposes:
|
|
|
|
@ftable @code
|
|
@item M-x eglot-events-buffer
|
|
This command pops up the events buffer used for communication with the
|
|
language server of the current buffer.
|
|
|
|
@item M-x eglot-stderr-buffer
|
|
This command pops up the buffer with the debug info printed by the
|
|
language server to its standard error stream.
|
|
|
|
@item M-x eglot-forget-pending-continuations
|
|
Forget pending requests for the server of the current buffer.
|
|
@c FIXME: Better description of the need.
|
|
|
|
@item M-x eglot-signal-didChangeConfiguration
|
|
This command updates the language server configuration according to the
|
|
current value of the variable @code{eglot-workspace-configuration}
|
|
(@pxref{Customizing Eglot}).
|
|
|
|
@item M-x eglot-clear-status
|
|
Clear the last JSONRPC error for the server of the current buffer.
|
|
Eglot keeps track of erroneous situations encountered by the server in
|
|
its mode-line indication so that the user may inspect the communication
|
|
leading up to it (@pxref{Troubleshooting Eglot}). If the situation is
|
|
deemed uninteresting or temporary, this command can be used to
|
|
``forget'' the error. Note that the command @code{M-x eglot-reconnect}
|
|
can sometimes be used to unclog a temporarily malfunctioning server.
|
|
@end ftable
|
|
|
|
As described in @ref{Eglot Features} most features associated with Eglot
|
|
are actually provided by other Emacs packages and features, and Eglot
|
|
only enhances them by allowing them to use the information coming from
|
|
the language servers. For completeness, here's the list of commands of
|
|
those other packages that are very commonly used in Eglot-managed
|
|
buffers:
|
|
|
|
@c Not @ftable, because the index entries should mention Eglot
|
|
@table @code
|
|
@cindex ElDoc, and Eglot
|
|
@cindex documentation using Eglot
|
|
@item M-x eldoc
|
|
Ask the ElDoc system for help at point.
|
|
|
|
@cindex Flymake, and Eglot
|
|
@cindex on-the-fly diagnostics using Eglot
|
|
@item M-x flymake-show-buffer-diagnostics
|
|
Ask Flymake system to display diagnostics for the current buffer.
|
|
|
|
@item M-x flymake-show-project-diagnostics
|
|
Ask Flymake to list diagnostics for all the files in the current
|
|
project.
|
|
|
|
@cindex xref, and Eglot
|
|
@cindex finding definitions of identifiers using Eglot
|
|
@item M-x xref-find-definitions
|
|
Ask Xref to go the definition of the identifier at point.
|
|
|
|
@cindex imenu navigation using Eglot
|
|
@item M-x imenu
|
|
Let the user navigate the program source code using buffer index,
|
|
categorizing program elements by syntactic class (class, method,
|
|
variable, etc.) and offering completion.
|
|
|
|
@cindex symbol completion using Eglot
|
|
@item M-x completion-at-point
|
|
Request completion of the symbol at point.
|
|
@end table
|
|
|
|
@node Customizing Eglot
|
|
@chapter Customizing Eglot
|
|
@cindex customizing Eglot
|
|
|
|
To have Eglot behave like you want it, sometimes it suffices to
|
|
customize Emacs packages and features that Eglot uses but to do so for
|
|
all of Emacs (regardless of Eglot) . For example, to configure the
|
|
amount of space taken up by documentation in the echo area, customize
|
|
the ElDoc variable @code{eldoc-echo-area-use-multiline-p}. To configure
|
|
Flymake faces used for errors and warnings, customize the
|
|
@code{flymake-error} and @code{flymake-warning} faces.
|
|
|
|
Compared to the breadth of its functionality, Eglot itself has a
|
|
relatively small number of customization variables. There is
|
|
additionally a set of variables that are usually set from Elisp snippets
|
|
(@pxref{Init File,,, emacs, The GNU Emacs Manual}).
|
|
|
|
Other times, it's necessary to have finer control of Eglot's interaction
|
|
with these features. @xref{More Customization}.
|
|
|
|
@menu
|
|
* Customization Variables::
|
|
* Other Variables::
|
|
* More Customization::
|
|
@end menu
|
|
|
|
@node Customization Variables
|
|
@section Customization Variables
|
|
@cindex variables, Eglot
|
|
|
|
This section provides a reference for the Eglot user options.
|
|
|
|
@vtable @code
|
|
@item eglot-autoreconnect
|
|
This option controls the ability to reconnect automatically to the
|
|
language server when Eglot detects that the server process terminated
|
|
unexpectedly. The default value @code{3} means to attempt reconnection
|
|
only if the previous successful connection lasted for more than that
|
|
number of seconds; a different positive value changes the minimal length
|
|
of the connection to trigger reconnection. A value of @code{t} means
|
|
always reconnect automatically, and @code{nil} means never reconnect (in
|
|
which case you will need to reconnect manually using @kbd{M-x eglot}).
|
|
|
|
@item eglot-connect-timeout
|
|
This specifies the number of seconds before connection attempt to a
|
|
language server times out. The value of @code{nil} means never time
|
|
out. The default is 30 seconds.
|
|
|
|
@item eglot-sync-connect
|
|
This setting is mainly important for connections which are slow to
|
|
establish. Whereas the variable @code{eglot-connect-timeout} controls
|
|
how long to wait for, this variable controls whether to block Emacs's
|
|
user interface while waiting. The default value is @code{3}; a positive
|
|
value means block for that many seconds, then wait for the connection in
|
|
the background. The value of @code{t} means block during the whole
|
|
waiting period. The value of @code{nil} or @code{0} means don't block
|
|
at all during the waiting period.
|
|
|
|
@item eglot-events-buffer-config
|
|
This configures the size and format of the Eglot events buffer.
|
|
@xref{Eglot Commands, eglot-events-buffer}, for how to access that
|
|
buffer. If the value is changed, the connection should be restarted
|
|
using @kbd{M-x eglot-reconnect} for the new value to take effect.
|
|
@c FIXME: Shouldn't the defcustom do this by itself using the :set
|
|
@c attribute? Maybe not because reconnecting is a complex task.
|
|
@xref{Troubleshooting Eglot}, for when this could be useful.
|
|
|
|
@item eglot-autoshutdown
|
|
If this is non-@code{nil}, Eglot shuts down a language server when the
|
|
last buffer managed by it is killed. @xref{Shutting Down LSP Servers}.
|
|
The default is @code{nil}; if you want to shut down a server, use
|
|
@kbd{M-x eglot-shutdown} (@pxref{Eglot Commands}).
|
|
|
|
@item eglot-confirm-server-edits
|
|
Various Eglot commands and code actions result in the language server
|
|
sending editing commands to Emacs. If this option's value is
|
|
non-@code{nil}, Eglot will ask for confirmation before performing edits
|
|
proposed by the language server. This option's value can be crafted to
|
|
require this confirmation for specific commands or only when the edit
|
|
affects files not yet visited by the user. Consult this option's
|
|
docstring for more information.
|
|
|
|
@item eglot-ignored-server-capabilities
|
|
This variable's value is a list of language server capabilities that
|
|
Eglot should not use. The default is @code{nil}: Eglot uses all of the
|
|
capabilities supported by each server.
|
|
|
|
@item eglot-extend-to-xref
|
|
If this is non-@code{nil}, and @kbd{M-.} (@code{xref-find-definitions})
|
|
lands you in a file outside of your project, such as a system-installed
|
|
library or header file, transiently consider that file as managed by the
|
|
same language server. That file is still outside your project
|
|
(i.e. @code{project-find-file} won't find it), but Eglot and the server
|
|
will consider it to be part of the workspace. The default is
|
|
@code{nil}.
|
|
|
|
@item eglot-mode-map
|
|
This variable is the keymap for binding Eglot-related command. It is in
|
|
effect only as long as the buffer is managed by Eglot. By default, it
|
|
is empty, with the single exception: @kbd{C-h .} is remapped to invoke
|
|
@code{eldoc-doc-buffer}. You can bind additional commands in this map.
|
|
For example:
|
|
|
|
@lisp
|
|
(define-key eglot-mode-map (kbd "C-c r") 'eglot-rename)
|
|
(define-key eglot-mode-map (kbd "C-c o") 'eglot-code-action-organize-imports)
|
|
(define-key eglot-mode-map (kbd "C-c h") 'eldoc)
|
|
(define-key eglot-mode-map (kbd "<f6>") 'xref-find-definitions)
|
|
@end lisp
|
|
|
|
@cindex progress
|
|
@item eglot-report-progress
|
|
Set this variable to non-nil if you'd like progress notifications coming
|
|
from the language server to be handled by Emacs's progress reporting
|
|
facilities. If the value is the symbol @code{messages} the message
|
|
buffer is used, else the progress is reported in the mode line.
|
|
|
|
@cindex request cancellation
|
|
@item eglot-advertise-cancellation
|
|
Setting this variable to true causes Eglot to send special cancellation
|
|
notification for certain stale client request. This may help some LSP
|
|
servers avoid doing costly but ultimately useless work on behalf of the
|
|
client, improving overall performance.
|
|
|
|
@item eglot-code-action-indications
|
|
This variable controls the indication of code actions available at
|
|
point. Value is a list of symbols, more than one can be specified:
|
|
|
|
@itemize @minus
|
|
@item
|
|
@code{eldoc-hint}: ElDoc is used to hint about at-point actions.
|
|
@item
|
|
@code{margin}: A special indicator appears in the margin of the line
|
|
that point is currently on.
|
|
@item
|
|
@code{nearby}: An interactive special indicator appears near point.
|
|
@item
|
|
@code{mode-line}: An interactive special indicator appears in the mode
|
|
line.
|
|
@end itemize
|
|
|
|
@code{margin} and @code{nearby} are incompatible. If the list is empty,
|
|
ElDoc will not hint about at-point actions.
|
|
|
|
@item eglot-code-action-indicator
|
|
This variable is a string determining what the special indicator looks
|
|
like.
|
|
|
|
@item eglot-mode-line-format
|
|
This variables controls the shape and look of Eglot's mode line. Its
|
|
value is a mode line ``construct'', generally a list of symbols and
|
|
strings. The following symbols are meaningful and useful for Eglot's
|
|
mode line:
|
|
@itemize @minus
|
|
@item
|
|
@code{eglot-mode-line-menu}: access Eglot's main menu. See also
|
|
@code{eglot-menu-string};
|
|
@item
|
|
@code{eglot-mode-line-session}: indicate current project and access
|
|
current session's menu;
|
|
@item
|
|
@code{eglot-mode-line-error}: an indication of recent LSP errors;
|
|
@item
|
|
@code{eglot-mode-line-pending-requests}: number of pending LSP requests;
|
|
@item
|
|
@code{eglot-mode-line-progress}: progress reporter widgets;
|
|
@item
|
|
@code{eglot-mode-line-action-suggestion}: LSP code actions at point.
|
|
@end itemize
|
|
@end vtable
|
|
|
|
@node Other Variables
|
|
@section Other Variables
|
|
|
|
This section provides a reference for Eglot variables that are meant to
|
|
be changed from Elisp snippets.
|
|
|
|
@c @table, not @vtable, because some of the variables are indexed
|
|
@c elsewhere
|
|
@table @code
|
|
@item eglot-server-programs
|
|
This variable determines which language server to start for each
|
|
supported major mode, and how to invoke that server's program.
|
|
@xref{Setting Up LSP Servers}, for the details.
|
|
|
|
@vindex eglot-strict-mode
|
|
@item eglot-strict-mode
|
|
This is @code{nil} by default, meaning that Eglot is generally lenient
|
|
about non-conforming servers. If you need to debug a server, set this
|
|
to @w{@code{(disallow-non-standard-keys enforce-required-keys)}}.
|
|
|
|
@vindex eglot-server-initialized-hook
|
|
@item eglot-server-initialized-hook
|
|
A hook run after the server object is successfully initialized (which
|
|
includes launching the process) but before any LSP communication is
|
|
attempted. Each function receives a @code{eglot-lsp-server} instance as
|
|
argument.
|
|
|
|
@vindex eglot-connect-hook
|
|
@item eglot-connect-hook
|
|
A hook run after the LSP connection to the server is successfully
|
|
established. Each function receives a @code{eglot-lsp-server} instance
|
|
as argument. @xref{Starting Eglot}.
|
|
|
|
@item eglot-managed-mode-hook
|
|
A hook run after Eglot started or stopped managing a buffer.
|
|
@xref{Eglot and Buffers}, for details of its usage.
|
|
|
|
@vindex eglot-stay-out-of
|
|
@item eglot-stay-out-of
|
|
This variable's value lists Emacs features that Eglot shouldn't
|
|
automatically try to manage on the user's behalf. It is useful, for
|
|
example, when you need to use non-LSP Flymake or Company back-ends. To
|
|
have Eglot stay away from some Emacs feature, add that feature's symbol
|
|
or a regexp that will match a symbol's name to the list: for example,
|
|
the symbol @code{xref} to leave Xref alone, or the string @samp{company}
|
|
to stay away from your Company customizations. Here's an example:
|
|
|
|
@lisp
|
|
(add-to-list 'eglot-stay-out-of 'flymake)
|
|
@end lisp
|
|
|
|
Note that you can still configure the excluded Emacs features manually
|
|
to use Eglot in your @code{eglot-managed-mode-hook} or via some other
|
|
mechanism.
|
|
@end table
|
|
|
|
@node More Customization
|
|
@section More Customization
|
|
|
|
As explained earlier (@pxref{Eglot and Buffers}), Eglot hooks onto
|
|
existing Emacs packages and features by setting special variables in its
|
|
special minor mode. To gain finer control of Eglot's operation, the
|
|
@code{eglot-managed-mode-hook} should be used to tweak, subdue or
|
|
completely override Eglot's setting of these variables.
|
|
|
|
@itemize @bullet
|
|
@item
|
|
Eglot hooks onto ElDoc's @code{eldoc-documentation-functions} variable,
|
|
adding a number of functions to it:
|
|
@itemize @minus
|
|
@item @code{eglot-hover-eldoc-function}, to display general information
|
|
about an identifier.
|
|
@item @code{eglot-signature-eldoc-function}, to display function
|
|
signature information.
|
|
@item @code{eglot-highlight-eldoc-function}, to highlight nearby
|
|
manifestations of an identifier.
|
|
@item @code{eglot-code-action-suggestion}, to retrieve relevant code
|
|
actions at point.
|
|
@end itemize
|
|
|
|
A simple tweak to remove at-point identifier information for
|
|
hypothetical language @code{Foo} may look like:
|
|
|
|
@lisp
|
|
(add-hook 'foo-mode-hook
|
|
(lambda ()
|
|
(add-hook 'eglot-managed-mode-hook
|
|
(lambda ()
|
|
(remove-hook 'eldoc-documentation-functions
|
|
'eglot-hover-eldoc-function
|
|
nil t))
|
|
nil t)))
|
|
@end lisp
|
|
|
|
For more sophisticated changes, we can take advantage of ElDoc's
|
|
well-defined protocols. @xref{Programming Language Doc,,, emacs, GNU
|
|
Emacs Manual}. For instance, the functions in
|
|
@code{eldoc-display-functions} control displays of the at-point
|
|
documentation produced by @code{eldoc-documentation-functions}. As an
|
|
example, to ensure that hover documentation specifically is never output
|
|
into the Echo area (in all programming modes):
|
|
|
|
@lisp
|
|
(require 'cl-lib)
|
|
|
|
(defun my/special-eglot-hover-function (cb &rest _ignored)
|
|
"Same as `eglot-hover-eldoc-function`, but skip the echo area."
|
|
(eglot-hover-eldoc-function (lambda (info &rest _ignore)
|
|
(funcall cb info :echo 'skip))))
|
|
|
|
;; substitute 'eldoc-hover-eldoc-function with our "fixed" variant.
|
|
(add-hook
|
|
'eglot-managed-mode-hook
|
|
(lambda ()
|
|
(setq-local eldoc-documentation-functions
|
|
(cl-substitute #'my/special-eglot-hover-function
|
|
'eglot-hover-eldoc-function
|
|
eldoc-documentation-functions))))
|
|
@end lisp
|
|
|
|
@item
|
|
Eglot hooks onto Flymake's @code{flymake-diagnostic-functions} variable,
|
|
completely replacing its value with Eglot's own
|
|
@code{eglot-flymake-backend} function. Additional backends may be added
|
|
to work alongside Eglot's.
|
|
|
|
@lisp
|
|
(add-hook 'foo-mode-hook
|
|
(lambda ()
|
|
(add-hook 'eglot-managed-mode-hook
|
|
(lambda ()
|
|
(add-hook 'flymake-diagnostic-functions
|
|
#'my/special-foo-mode-backend
|
|
nil t))
|
|
nil t)))
|
|
@end lisp
|
|
|
|
@item
|
|
Eglot hooks onto Xref's @code{xref-backend-functions} variable, adding
|
|
its own @code{eglot-xref-backend} function to it.
|
|
|
|
@item
|
|
Eglot hooks onto Imenu's @code{imenu-create-index-function}.
|
|
|
|
@item
|
|
Eglot hooks onto Emacs's @code{completion-at-point-functions}.
|
|
|
|
@item
|
|
Eglot hooks onto Company's @code{company-backends} variable, ensuring
|
|
only the @code{company-capf} backend lives there. This ensures the same
|
|
set of completions as regular @code{completion-at-point}.
|
|
|
|
@item
|
|
Eglot hooks onto YASnippet by automatically activating
|
|
@code{yas-minor-mode} when needed to expand server-provided snippets.
|
|
@end itemize
|
|
|
|
@node Advanced server configuration
|
|
@chapter Advanced server configuration
|
|
|
|
Though many language servers work well out-of-the-box, most allow
|
|
fine-grained control of their operation via specific configuration
|
|
options that are transmitted over the LSP protocol and vary from server
|
|
to server. A small number of servers require such special configuration
|
|
to work acceptably, or even to work at all.
|
|
|
|
After having setup a server executable program in
|
|
@code{eglot-server-programs} (@pxref{Setting Up LSP Servers}) and
|
|
ensuring Eglot can invoke it, you may want to take advantage of some of
|
|
these options. You should first distinguish two main kinds of server
|
|
configuration:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
Project-specific, applying to a specific project;
|
|
|
|
@item
|
|
User-specific, applying to all projects the server is used for.
|
|
@end itemize
|
|
|
|
When you have decided which kind you need, the following sections
|
|
teach how Eglot's user variables can be used to achieve it:
|
|
|
|
@menu
|
|
* Project-specific configuration::
|
|
* User-specific configuration::
|
|
* JSONRPC objects in Elisp::
|
|
@end menu
|
|
|
|
It's important to note that not all servers allow both kinds of
|
|
configuration, nor is it guaranteed that user options can be copied over
|
|
to project options, and vice-versa. When in doubt, consult your
|
|
language server's documentation.
|
|
|
|
It's also worth noting that some language servers can read these
|
|
settings from configuration files in the user's @code{HOME} directory or
|
|
in a project's directory. For example, the @command{pylsp} Python
|
|
server reads the file @file{~/.config/pycodestyle} for user
|
|
configuration. The @command{clangd} C/C++ server reads both
|
|
@file{~/.config/clangd/config.yaml} for user configuration and
|
|
@file{.clangd} for project configuration. It may be advantageous to use
|
|
these mechanisms instead of Eglot's, as this will probably work with
|
|
other LSP clients and may be easier to debug than options riding on the
|
|
LSP wire.
|
|
|
|
@node Project-specific configuration
|
|
@section Project-specific configuration
|
|
@vindex eglot-workspace-configuration
|
|
@cindex workspace configuration
|
|
|
|
To set project-specific settings, which the LSP specification calls
|
|
@dfn{workspace configuration}, the variable
|
|
@code{eglot-workspace-configuration} may be used.
|
|
|
|
This variable is a directory-local variable (@pxref{Directory Variables,
|
|
, Per-directory Local Variables, emacs, The GNU Emacs Manual}). It's
|
|
important to recognize that this variable really only makes sense when
|
|
set directory-locally. It usually does not make sense to set it
|
|
file-locally or in a major-mode hook.
|
|
|
|
The most common way to set @code{eglot-workspace-configuration } is
|
|
using a @file{.dir-locals.el} file in the root of your project. If you
|
|
can't do that, you may also set it from Elisp code via the
|
|
@code{dir-locals-set-class-variables} function. (@pxref{Directory Local
|
|
Variables,,, elisp, GNU Emacs Lisp Reference Manual}).
|
|
|
|
However you choose to set it, the variable's value is a plist
|
|
(@pxref{Property Lists,,, elisp, GNU Emacs Lisp Reference Manual}) with
|
|
the following format:
|
|
|
|
@lisp
|
|
(@var{:server1} @var{plist1} @var{:server2} @var{plist2} @dots{})
|
|
@end lisp
|
|
|
|
@noindent
|
|
Here, @var{:server1} and @var{:server2} are keywords whose names
|
|
identify the LSP language servers to target. Consult server
|
|
documentation to find out what name to use. @var{plist1} and
|
|
@var{plist2} are plists of options, possibly nesting other plists.
|
|
|
|
@findex eglot-show-workspace-configuration
|
|
When experimenting with workspace settings, you can use the command
|
|
@kbd{M-x eglot-show-workspace-configuration} to inspect and debug the
|
|
value of this variable in its final JSON form, ready to be sent to the
|
|
server (@pxref{JSONRPC objects in Elisp}). This helper command works
|
|
even before actually connecting to the server.
|
|
|
|
These variable's value doesn't take effect immediately. That happens
|
|
upon establishing the connection, in response to an explicit query from
|
|
the server, or when issuing the command @kbd{M-x
|
|
eglot-signal-didChangeConfiguration} which notifies the server during an
|
|
ongoing Eglot session.
|
|
|
|
@subsection Examples
|
|
|
|
For some users, setting @code{eglot-workspace-configuration} is a
|
|
somewhat daunting task. One of the reasons is having to manage the
|
|
general Elisp syntax of per-mode directory-local variables, which uses
|
|
alists (@pxref{Association Lists,,, elisp, GNU Emacs Lisp Reference
|
|
Manual}), and the specific syntax of Eglot's variable, which uses
|
|
plists. Some examples are useful.
|
|
|
|
Let's say you want to configure two language servers to be used in a
|
|
project written in a combination of the Python and Go languages. You
|
|
want to use the @command{pylsp} and @command{gopls} languages servers.
|
|
In the documentation of the servers in question (or in some other
|
|
editor's configuration file, or in some blog article), you find the
|
|
following configuration options in informal dotted-notation syntax:
|
|
|
|
@example
|
|
pylsp.plugins.jedi_completion.include_params: true
|
|
pylsp.plugins.jedi_completion.fuzzy: true
|
|
pylsp.pylint.enabled: false
|
|
gopls.usePlaceholders: true
|
|
@end example
|
|
|
|
To apply this to Eglot, and assuming you chose the
|
|
@file{.dir-locals.el} file method, the contents of that file could be:
|
|
|
|
@lisp
|
|
((nil
|
|
. ((eglot-workspace-configuration
|
|
. (:pylsp (:plugins (:jedi_completion (:include_params t
|
|
:fuzzy t)
|
|
:pylint (:enabled :json-false)))
|
|
:gopls (:usePlaceholders t)))))
|
|
(python-base-mode . ((indent-tabs-mode . nil)))
|
|
(go-mode . ((indent-tabs-mode . t))))
|
|
@end lisp
|
|
|
|
@noindent
|
|
Note how alists are used for associating Emacs mode names with other
|
|
alists, associating variable names with variable values. Then, pay
|
|
special attention to how the value of
|
|
@code{eglot-workspace-configuration} is a plist and @emph{not} an alist.
|
|
|
|
The above form sets the value of @code{eglot-workspace-configuration} in
|
|
all the buffers inside the project; each language server will then use
|
|
only the section of the parameters intended for it, and ignore the rest.
|
|
In our example, @command{pylsp} and @command{gopls} are solely
|
|
interested in the @code{:pylsp} and @code{:gopls} parameter section
|
|
names, respectively. However, section names don't have to match the
|
|
server name and some servers may be even interested in multiple
|
|
sections: the @command{typescript-language-server} server is known to be
|
|
interested in the @code{:javascript} and @code{:typescript} section
|
|
names.
|
|
|
|
To avoid sending whole configuration sections to servers who are
|
|
decidedly not interested in them, the following form may also be used:
|
|
|
|
@lisp
|
|
((python-base-mode
|
|
. ((eglot-workspace-configuration
|
|
. (:pylsp (:plugins (:jedi_completion (:include_params t
|
|
:fuzzy t)
|
|
:pylint (:enabled :json-false)))))
|
|
(indent-tabs-mode . nil)))
|
|
(go-mode
|
|
. ((eglot-workspace-configuration
|
|
. (:gopls (:usePlaceholders t)))
|
|
(indent-tabs-mode . t))))
|
|
@end lisp
|
|
|
|
@noindent
|
|
This sets up the value of @code{eglot-workspace-configuration}
|
|
separately depending on the major mode of each of that project's
|
|
buffers. @code{python-base-mode} buffers will have the variable set to
|
|
@code{(:pylsp (:plugins ...))}. @code{go-mode} buffers will have the
|
|
variable set to @code{(:gopls (:usePlaceholders t))}.
|
|
|
|
Some servers will issue workspace configuration for specific source
|
|
files inside your project. For example, if you know @code{gopls} is
|
|
asking about specific files in the @code{src/imported} subdirectory and
|
|
you want to set a different option for @code{gopls.usePlaceholders} ,
|
|
you may use something like:
|
|
|
|
@lisp
|
|
((python-base-mode
|
|
. ((eglot-workspace-configuration
|
|
. (:pylsp (:plugins (:jedi_completion (:include_params t
|
|
:fuzzy t)
|
|
:pylint (:enabled :json-false)))))
|
|
(indent-tabs-mode nil)))
|
|
(go-mode
|
|
. ((eglot-workspace-configuration
|
|
. (:gopls (:usePlaceholders t)))
|
|
(indent-tabs-mode t)))
|
|
("src/imported"
|
|
. ((eglot-workspace-configuration
|
|
. (:gopls (:usePlaceholders nil))))))
|
|
@end lisp
|
|
|
|
Finally, if one needs to determine the workspace configuration based on
|
|
some dynamic context, @code{eglot-workspace-configuration} can be set to
|
|
a function instead of a plist. The function is called with the
|
|
@code{eglot-lsp-server} instance of the connected server (if any) and
|
|
with @code{default-directory} set to the root of the project. The
|
|
function should return a plist suitable for use as the variable's value.
|
|
|
|
@node User-specific configuration
|
|
@section User-specific configuration
|
|
@cindex initializationOptions
|
|
@cindex command-line arguments
|
|
|
|
This kind of configuration applies to all projects the server is used
|
|
for. Here, there are a number of ways to do this inside Eglot.
|
|
|
|
A common way is to pass command-line options to the server invocation
|
|
via @code{eglot-server-programs}. Let's say we want to configure where
|
|
the @command{clangd} server reads its @code{compile_commands.json} from.
|
|
This can be done like so:
|
|
|
|
@lisp
|
|
(with-eval-after-load 'eglot
|
|
(add-to-list 'eglot-server-programs
|
|
`(c++-mode . ("clangd" "--compile-commands-dir=/tmp"))))
|
|
|
|
@end lisp
|
|
|
|
@noindent
|
|
Another way is to have Eglot pass a JSON object to the server during the
|
|
LSP handshake. This is done using the @code{:initializationOptions}
|
|
syntax of @code{eglot-server-programs}:
|
|
|
|
@lisp
|
|
(with-eval-after-load 'eglot
|
|
(add-to-list 'eglot-server-programs
|
|
`(c++-mode . ("clangd" :initializationOptions
|
|
(:compilationDatabasePath "/tmp")))))
|
|
@end lisp
|
|
|
|
@noindent
|
|
The argument @code{(:compilationDatabasePath "/tmp")} is Emacs's
|
|
representation in plist format of a simple JSON object
|
|
@code{@{"compilationDatabasePath": "/tmp"@}}. To learn how to represent
|
|
more deeply nested options in this format, @pxref{JSONRPC objects in
|
|
Elisp}.
|
|
|
|
In this case, the two examples achieve exactly the same, but notice how
|
|
the option's name has changed between them.
|
|
|
|
@vindex eglot-workspace-configuration
|
|
Finally there is another way to do user-specific configuration of
|
|
language servers, which may be used if the methods above are not
|
|
supported. It consists of @emph{globally} setting
|
|
@code{eglot-workspace-configuration}, a variable originally intended for
|
|
project-specific configuration. This has the same effect as giving all
|
|
your projects a certain default configuration, as described in
|
|
@ref{Project-specific configuration}. Here is an example:
|
|
|
|
@lisp
|
|
(setq-default eglot-workspace-configuration
|
|
'(:pylsp (:plugins (:jedi_completion (:include_params t
|
|
:fuzzy t)
|
|
:pylint (:enabled :json-false)))
|
|
:gopls (:usePlaceholders t)))
|
|
@end lisp
|
|
|
|
Note that the global value of @code{eglot-workspace-configuration} is
|
|
always overridden if a directory-local value is detected.
|
|
|
|
@node JSONRPC objects in Elisp
|
|
@section JSONRPC objects in Elisp
|
|
|
|
Emacs's preferred way of representing JSON is via Lisp lists. In Eglot,
|
|
the syntax of this list is the simplest possible (the one with fewer
|
|
parenthesis), a plist (@pxref{Property Lists,,, elisp, GNU Emacs Lisp
|
|
Reference Manual}).
|
|
|
|
The plist may be arbitrarily complex, and generally containing other
|
|
keyword-value property sub-plists corresponding to JSON sub-objects.
|
|
|
|
For representing the JSON leaf values @code{true}, @code{false},
|
|
@code{null} and @code{@{@}}, you can use the Lisp values @code{t},
|
|
@code{:json-false}, @code{nil}, and @code{eglot-@{@}}, respectively.
|
|
JSON arrays are represented as Elisp vectors surrounded by square
|
|
brackets (@pxref{Vectors,,,elisp,GNU Emacs Lisp Reference Manual}).
|
|
|
|
For example, the plist
|
|
|
|
@lisp
|
|
(:pylsp (:plugins (:jedi_completion (:include_params t
|
|
:fuzzy t
|
|
:cache_for ["pandas" "numpy"])
|
|
:pylint (:enabled :json-false)))
|
|
:gopls (:usePlaceholders t))
|
|
@end lisp
|
|
|
|
@noindent
|
|
is serialized by Eglot to the following JSON text:
|
|
|
|
@example
|
|
@{
|
|
"pylsp": @{
|
|
"plugins": @{
|
|
"jedi_completion": @{
|
|
"include_params": true,
|
|
"fuzzy": true,
|
|
"cache_for": [ "pandas", "numpy" ]
|
|
@},
|
|
"pylint": @{
|
|
"enabled": false
|
|
@}
|
|
@}
|
|
@},
|
|
"gopls": @{
|
|
"usePlaceholders": true
|
|
@}
|
|
@}
|
|
@end example
|
|
|
|
@node Extending Eglot
|
|
@chapter Extending Eglot
|
|
|
|
Sometimes it may be useful to extend existing Eglot functionality using
|
|
Elisp its public methods. A good example of when this need may arise is
|
|
adding support for a custom LSP protocol extension only implemented by a
|
|
specific server.
|
|
|
|
The best source of documentation for this is probably Eglot source code
|
|
itself, particularly the section marked ``API''.
|
|
|
|
Most of the functionality is implemented with Common-Lisp style generic
|
|
functions (@pxref{Generics,,,eieio,EIEIO}) that can be easily extended
|
|
or overridden. The Eglot code itself is an example on how to do this.
|
|
|
|
The following is a relatively simple example that adds support for the
|
|
@code{inactiveRegions} experimental feature introduced in version 17 of
|
|
the @command{clangd} C/C++ language server++.
|
|
|
|
Summarily, the feature works by first having the server detect the
|
|
Eglot's advertisement of the @code{inactiveRegions} client capability
|
|
during startup, whereupon the language server will report a list of
|
|
regions of inactive code for each buffer. This is usually code
|
|
surrounded by C/C++ @code{#ifdef} macros that the preprocessor removes
|
|
based on compile-time information.
|
|
|
|
The language server reports the regions by periodically sending a
|
|
@code{textDocument/inactiveRegions} notification for each managed buffer
|
|
(@pxref{Eglot and Buffers}). Normally, unknown server notifications are
|
|
ignored by Eglot, but we're going change that.
|
|
|
|
Both the announcement of the client capability and the handling of the
|
|
new notification is done by adding methods to generic functions.
|
|
|
|
@itemize @bullet
|
|
@item
|
|
The first method extends @code{eglot-client-capabilities} using a simple
|
|
heuristic to detect if current server is @command{clangd} and enables
|
|
the @code{inactiveRegion} capability.
|
|
|
|
@lisp
|
|
(cl-defmethod eglot-client-capabilities :around (server)
|
|
(let ((base (cl-call-next-method)))
|
|
(when (cl-find "clangd" (process-command
|
|
(jsonrpc--process server))
|
|
:test #'string-match)
|
|
(setf (cl-getf (cl-getf base :textDocument)
|
|
:inactiveRegionsCapabilities)
|
|
'(:inactiveRegions t)))
|
|
base))
|
|
@end lisp
|
|
|
|
Notice we use an internal function of the @code{jsonrpc.el} library, and
|
|
a regexp search to detect @command{clangd}. An alternative would be to
|
|
define a new EIEIO subclass of @code{eglot-lsp-server}, maybe called
|
|
@code{eglot-clangd}, so that the method would be simplified:
|
|
|
|
@lisp
|
|
(cl-defmethod eglot-client-capabilities :around ((_s eglot-clangd))
|
|
(let ((base (cl-call-next-method)))
|
|
(setf (cl-getf (cl-getf base :textDocument)
|
|
:inactiveRegionsCapabilities)
|
|
'(:inactiveRegions t))))
|
|
@end lisp
|
|
|
|
However, this would require that users tweak @code{eglot-server-program}
|
|
to tell Eglot instantiate such sub-classes instead of the generic
|
|
@code{eglot-lsp-server} (@pxref{Setting Up LSP Servers}). For the
|
|
purposes of this particular demonstration, we're going to use the more
|
|
hacky regexp route which doesn't require that.
|
|
|
|
Note, however, that detecting server versions before announcing new
|
|
capabilities is generally not needed, as both server and client are
|
|
required by LSP to ignore unknown capabilities advertised by their
|
|
counterparts.
|
|
|
|
@item
|
|
The second method implements @code{eglot-handle-notification} to process
|
|
the server notification for the LSP method
|
|
@code{textDocument/inactiveRegions}. For each region received it
|
|
creates an overlay applying the @code{shadow} face to the region.
|
|
Overlays are recreated every time a new notification of this kind is
|
|
received.
|
|
|
|
To learn about how @command{clangd}'s special JSONRPC notification
|
|
message is structured in detail you could consult that server's
|
|
documentation. Another possibility is to evaluate the first
|
|
capability-announcing method, reconnect to the server and peek in the
|
|
events buffer (@pxref{Eglot Commands, eglot-events-buffer}). You could
|
|
find something like:
|
|
|
|
@lisp
|
|
[server-notification] Mon Sep 4 01:10:04 2023:
|
|
(:jsonrpc "2.0" :method "textDocument/inactiveRegions" :params
|
|
(:textDocument
|
|
(:uri "file:///path/to/file.cpp")
|
|
:regions
|
|
[(:start (:character 0 :line 18)
|
|
:end (:character 58 :line 19))
|
|
(:start (:character 0 :line 36)
|
|
:end (:character 1 :line 38))]))
|
|
@end lisp
|
|
|
|
This reveals that the @code{textDocument/inactiveRegions} notification
|
|
contains a @code{:textDocument} property to designate the managed buffer
|
|
and an array of LSP regions under the @code{:regions} property. Notice
|
|
how the message (originally in JSON format), is represented as Elisp
|
|
plists (@pxref{JSONRPC objects in Elisp}).
|
|
|
|
The Eglot generic function machinery will automatically destructure the
|
|
incoming message, so these two properties can simply be added to the new
|
|
method's lambda list as @code{&key} arguments. Also, the
|
|
@code{eglot-uri-to-path} and @code{eglot-range-region} may be used to
|
|
easily parse the LSP @code{:uri} and @code{:start ... :end ...} objects
|
|
to obtain Emacs objects for file names and positions.
|
|
|
|
The remainder of the implementation consists of standard Elisp
|
|
techniques to loop over arrays, manage buffers and overlays.
|
|
|
|
@lisp
|
|
(cl-defmethod eglot-handle-notification
|
|
(_server (_method (eql textDocument/inactiveRegions))
|
|
&key regions textDocument &allow-other-keys)
|
|
(if-let* ((path (expand-file-name (eglot-uri-to-path
|
|
(cl-getf textDocument :uri))))
|
|
(buffer (find-buffer-visiting path)))
|
|
(with-current-buffer buffer
|
|
(remove-overlays nil nil 'inactive-code t)
|
|
(cl-loop
|
|
for r across regions
|
|
for (beg . end) = (eglot-range-region r)
|
|
for ov = (make-overlay beg end)
|
|
do
|
|
(overlay-put ov 'face 'shadow)
|
|
(overlay-put ov 'inactive-code t)))))
|
|
@end lisp
|
|
|
|
@end itemize
|
|
|
|
After evaluating these two additions and reconnecting to the
|
|
@command{clangd} language server (version 17), the result will be that
|
|
all the inactive code in the buffer will be nicely grayed out using the
|
|
LSP server knowledge about current compile time preprocessor defines.
|
|
|
|
@node Troubleshooting Eglot
|
|
@chapter Troubleshooting Eglot
|
|
@cindex troubleshooting Eglot
|
|
|
|
This chapter documents commands and variables that can be used to
|
|
troubleshoot Eglot problems. It also provides guidelines for
|
|
reporting Eglot bugs in a way that facilitates their resolution.
|
|
|
|
When you encounter problems with Eglot, try first using the commands
|
|
@kbd{M-x eglot-events-buffer} and @kbd{M-x eglot-stderr-buffer}. They
|
|
pop up special buffers that can be used to inspect the communications
|
|
between the Eglot and language server. In many cases, this will
|
|
indicate the problems or at least provide a hint.
|
|
|
|
@menu
|
|
* Performance::
|
|
* Getting the latest version::
|
|
* Reporting bugs::
|
|
@end menu
|
|
|
|
@node Performance
|
|
@section Performance
|
|
@cindex performance problems, with Eglot
|
|
A common and easy-to-fix cause of performance problems in Eglot
|
|
(especially in older versions) is its events buffer, since it represents
|
|
additional work that Eglot must do (@pxref{Eglot Commands,
|
|
eglot-events-buffer}). If you find Eglot is operating correctly but
|
|
slowly, try to customize the variable @code{eglot-events-buffer-config}
|
|
(@pxref{Customization Variables}) and set its @code{:size} property to
|
|
0. This will disable recording any events and may speed things up.
|
|
|
|
In other situations, the cause of poor performance lies in the language
|
|
server itself. Servers use aggressive caching and other techniques to
|
|
improve their performance. Often, this can be tweaked by changing the
|
|
server configuration (@pxref{Advanced server configuration}).
|
|
|
|
@node Getting the latest version
|
|
@section Getting the latest version
|
|
@cindex upgrading Eglot
|
|
|
|
To install the latest Eglot in an Emacs version that does not bundle
|
|
Eglot, use @kbd{M-x package-install}.
|
|
|
|
Often, a newer Eglot version exists that has fixed a longstanding bug,
|
|
has more LSP features, or just better supports a particular language
|
|
server. Recent Eglot versions can self-update via the command @kbd{M-x
|
|
eglot-upgrade-eglot}. This will replace any currently installed version
|
|
with the newest one available from the ELPA archives configured in
|
|
@code{package-archives}.
|
|
|
|
You can also update Eglot through other methods, such as
|
|
@code{use-package} (@pxref{Installing packages,,, use-package,
|
|
use-package User Manual}), @code{package-install}, @code{list-packages}
|
|
or the newer @code{package-upgrade} (@pxref{Packages,,, emacs, GNU Emacs
|
|
Manual}). However, do read the docstrings of the command you intend to
|
|
use before you use it, as some of them may not work in exactly the same
|
|
way across Emacs versions, meaning your configuration may be not
|
|
portable.
|
|
|
|
@node Reporting bugs
|
|
@section Reporting bugs
|
|
@cindex bug reports
|
|
|
|
If you think you have found a bug, we want to hear about it. Before
|
|
reporting a bug, keep in mind that interaction with language servers
|
|
represents a large quantity of unknown variables. Therefore, it is
|
|
generally both @emph{difficult} and @emph{absolutely essential} that the
|
|
maintainers reproduce bugs exactly as they happened to you, the user.
|
|
|
|
To report an Eglot bug, send e-mail to @email{bug-gnu-emacs@@gnu.org}.
|
|
|
|
To understand how to write this email, get acquainted with Emacs's bug
|
|
reporting guidelines (@pxref{Bugs,,, emacs, GNU Emacs Manual}). Then,
|
|
follow this Eglot-specific checklist:
|
|
|
|
@enumerate
|
|
@item
|
|
Include the transcript of JSONRPC events obtained from the buffer popped
|
|
up by @kbd{M-x eglot-events-buffer}. You may narrow down the transcript
|
|
if you are sure of where the problematic exchange is, but it's safer to
|
|
include the whole transcript, either attached or inline.
|
|
|
|
@item
|
|
If Emacs signaled an error (an error message was seen or heard), make
|
|
sure to repeat the process after turning on @code{debug-on-error} via
|
|
@kbd{M-x toggle-debug-on-error}. This normally produces a backtrace of
|
|
the error that should also be attached to the bug report.
|
|
|
|
@item
|
|
Include a description of how the maintainer should obtain, install, and
|
|
configure the language server you used. Maintainers usually have access
|
|
to GNU/Linux systems, though not necessarily the distribution that you
|
|
may be using. If possible, try to replicate the problem with the
|
|
C/C@t{++} or Python servers, as these are very easy to install.
|
|
|
|
@item
|
|
Describe how to setup a @emph{minimal} project directory where Eglot
|
|
should be started for the problem to happen. Describe each file's name
|
|
and its contents. Alternatively, you can supply the address of a public
|
|
Git repository.
|
|
|
|
@item
|
|
Include versions of the software used. The Emacs version can be
|
|
obtained with @kbd{M-x emacs-version}.
|
|
|
|
We welcome bug reports about all Eglot versions, but it is helpful to
|
|
first check if the problem isn't already fixed in the latest version
|
|
(@pxref{Getting the latest version}).
|
|
|
|
It's also essential to include the version of ELPA packages that are
|
|
explicitly or implicitly loaded. The optional but popular Company or
|
|
Markdown packages are distributed as GNU ELPA packages, not to mention
|
|
Eglot itself in some situations. Some major modes (Go, Rust, etc.) are
|
|
provided by ELPA packages. It's sometimes easy to miss these, since
|
|
they are usually implicitly loaded when visiting a file in that
|
|
language.
|
|
|
|
ELPA packages usually live in @code{~/.emacs.d/elpa} (or what is in
|
|
@code{package-user-dir}). Including a listing of files in that
|
|
directory is a way to tell the maintainers about ELPA package versions.
|
|
|
|
@item
|
|
Include a recipe to replicate the problem with @emph{a clean Emacs run}.
|
|
The invocation @code{emacs -Q -f package-initialize} starts Emacs with
|
|
no configuration and initializes the ELPA packages. A very minimal
|
|
@file{.emacs} initialization file (10 lines or less) is also acceptable
|
|
and good means to describe changes to variables.
|
|
|
|
There is usually no need to include @code{require} statements in the
|
|
recipe, as Eglot's functionality uses autoloads.
|
|
|
|
Likewise, there is rarely the need to use things like @code{use-package}
|
|
or @code{eglot-ensure}. This just makes the recipe harder to follow.
|
|
Prefer setting variables with @code{setq} and adding to hooks with
|
|
@code{add-hook}. Prefer starting Eglot with @code{M-x eglot}.
|
|
|
|
@item
|
|
Make sure to double check all the above elements and re-run the recipe
|
|
to see that the problem is reproducible. Following the recipe should
|
|
produce event transcript and error backtraces that are very similar to
|
|
the ones you included. If the problem only happens sometimes, mention
|
|
this in your report.
|
|
@end enumerate
|
|
|
|
Please keep in mind that some problems reported against Eglot may
|
|
actually be bugs in the language server or the Emacs feature/package
|
|
that used Eglot to communicate with the language server. Eglot is, in
|
|
many cases, just a frontend to that functionality.
|
|
|
|
@node GNU Free Documentation License
|
|
@appendix GNU Free Documentation License
|
|
@include doclicense.texi
|
|
|
|
@node Index
|
|
@unnumbered Index
|
|
@printindex cp
|
|
|
|
@bye
|