     [file docstyle.texi not included]

Eglot
*****

Eglot is the Emacs client for the Language Server Protocol (LSP).  The name ``Eglot'' is an acronym that stands for ``Emacs polyGLOT''. (A 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.

This manual is for Eglot, the Emacs LSP client.

Copyright © 2022--2024 Free Software Foundation, Inc.

     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.''

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, see Eglot and LSP Servers.  See Using Eglot, for detailed description of using Eglot, and see Customizing Eglot, for adapting Eglot to less common use patterns.

Here's how to start using Eglot with your programming project:

 1. Select and install a language server.

     Eglot comes pre-configured with many popular language servers, see the value of 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.  Alternatively, install one or more servers of your choice and add them to the value of eglot-server-programs, as described in Setting Up LSP Servers.

 2. Turn on Eglot for your project.

     To start using Eglot for a project, type M-x eglot 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 managing all the files of the project which use the same programming language.  The notion of a ``project'' used by Eglot is the same Emacs uses (see Projects (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.

     Alternatively, you can start Eglot automatically from the major-mode hook of the mode used for the programming language; see Starting Eglot.

 3. 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 M-x eglot-rename (to rename an identifier across the entire project), M-x eglot-format (to reformat and reindent code), and some others.  See Eglot Commands, for the detailed list of Eglot commands.

 4. That's it!

Eglot and LSP Servers
*********************

This chapter describes how to set up Eglot for your needs, and how to start it.

Setting Up LSP Servers
======================

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 (see Processes (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 provided by the variable eglot-server-programs.

 -- Variable: 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 (MAJOR-MODE . SERVER).

     The MAJOR-MODE of the alist elements can be either a symbol of an Emacs major mode or a list of the form (MODE :language-id ID), with MODE being a major-mode symbol and 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, 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 SERVER part of the alist elements can be one of the following:

     (PROGRAM ARGS...)
          This says to invoke PROGRAM with zero or more arguments ARGS; the program is expected to communicate with Emacs via the standard input and standard output streams.

     (PROGRAM ARGS... :initializationOptions OPTIONS...)
          PROGRAM is invoked with ARGS but OPTIONS specifies how to construct the :initializationOptions JSON object to pass the server on during the LSP handshake (see Advanced server configuration).

     (HOST PORT ARGS...)
          Here HOST is a string and PORT is a positive integer specifying a TCP connection to a remote server.  The ARGS are passed to open-network-stream, e.g. if the connection needs to use encryption or other non-default parameters (see Network (GNU Emacs Lisp Reference Manual)).

     (PROGRAM ARGS... :autoport MOREARGS...)
          PROGRAM is started with a command line constructed from ARGS followed by an available server port and the rest of arguments in MOREARGS; Eglot then establishes a TCP connection with the server via that port on the local host.

     FUNCTION
          This should be a function of a single argument: non-nil if the connection was requested interactively (e.g., by the eglot command), otherwise 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.

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 add-to-list.  For example, if there is a hypothetical language server program fools for the language Foo which is supported by an Emacs major-mode foo-mode, you can add it to the alist like this:

     (with-eval-after-load 'eglot
       (add-to-list 'eglot-server-programs
                    '(foo-mode . ("fools" "--stdio"))))

This will invoke the program fools with the command-line argument --stdio in support of editing source files for which Emacs turns on foo-mode, and will communicate with the program via the standard streams.  As usual with invoking programs, the executable file fools should be in one of the directories mentioned by the exec-path variable (see Subprocess Creation (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 eglot-alternatives with the functional form of eglot-server-programs.

     (with-eval-after-load 'eglot
       (add-to-list 'eglot-server-programs
                    `(foo-mode . ,(eglot-alternatives
                                    '(("fools" "--stdio")
                                      ("phewls" "--fast"))))))

If you have fools and phewls installed, the function produced by eglot-alternatives will prompt for the server to use in foo-mode buffers.  Else it will use whichever is available.

Starting Eglot
==============

The most common way to start Eglot is to simply visit a source file of a given language and use the command 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 [eglot: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 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 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 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 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.

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 foo-mode:

      (add-hook 'foo-mode-hook 'eglot-ensure)

The function eglot-ensure will start an Eglot session for each buffer in which 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.

When Eglot connects to a language server for the first time in an Emacs session, it runs the hook eglot-connect-hook (see Eglot Variables).

Shutting Down LSP Servers
=========================

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.  See Eglot and Buffers, for more details of what Eglot management of a buffer entails.

You can also shut down a language server manually, by using the command 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 (see Troubleshooting Eglot), but a prefix argument prevents that.

Alternatively, you can customize the variable eglot-autoshutdown to a non-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 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.

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.

Eglot Features
==============

Once Eglot is enabled in a buffer, it uses LSP and the language-server capabilities to activate, enable, and enhance modern IDE features in Emacs.  The features themselves are usually provided via other Emacs packages.  Here's the list of the main features that Eglot enables and provides:

  * At-point documentation: when point is at or near a symbol or an identifier, the information about the symbol/identifier, such as the signature of a function or class method and server-generated diagnostics, is made available via the ElDoc package (see Programming Language Doc (GNU Emacs Manual)).  This allows major modes to provide extensive help and documentation about the program identifiers.

  * On-the-fly diagnostic annotations with server-suggested fixes, via the Flymake package (see GNU Flymake manual).  This improves and enhances the Flymake diagnostics, replacing the other Flymake backends.

  * Finding definitions and uses of identifiers, via Xref (see Xref (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 (see Tags tables (GNU Emacs Manual)) for languages which are only supported by the etags backend.

  * Buffer navigation by name of function, class, method, etc., via Imenu (see Imenu (GNU Emacs Manual)).  Eglot provides its own variant of imenu-create-index-function, which generates the index for the buffer based on language-server program source analysis.

  * Enhanced completion of symbol at point by the completion-at-point command (see Symbol Completion (GNU Emacs Manual)).  This uses the language-server's parser data for the completion candidates.

  * Automatic reformatting of source code as you type it.  This is similar to what the eglot-format command does (see below), but is activated automatically as you type.

  * If a completion package such as company-mode, a popular third-party completion package (or any other completion package), is installed, Eglot enhances it by providing completion candidates based on the language-server analysis of the source code. (company-mode can be installed from GNU ELPA.)

  * 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.)

  * If the popular third-party package 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.

  * 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 eglot-rename and asking to automatically correct problems with eglot-code-actions.  See Eglot Commands.

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.

Buffers, Projects, and Eglot
============================

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 workspace.  The Emacs equivalent of a workspace is a project (see Projects (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:

  * A single-directory project: several source files in a single common directory.

  * A VC project: source files in a directory hierarchy under some VCS, e.g. a VCS repository (see Version Control (GNU Emacs Manual)).

  * An EDE project: source files in a directory hierarchy managed via the Emacs Development Environment (see EDE (GNU Emacs Manual)).

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 ~/projects/fooey/lib/x.foo and x.foo belongs to a project rooted at ~/projects/fooey (perhaps because a .git directory exists there), then 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 lib/x.foo you visited, but likely also all the other *.foo files under the ~/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 eglot-workspace-configuration (see 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, it performs several background activities on behalf of the project and its buffers:

  * 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 [eglot:PROJECT] indication to the mode line of each such buffer, where SERVER is the name of the server and PROJECT identifies the project by its root directory.  Clicking the mouse on the Eglot mode-line indication activates a menu with server-specific items.

  * For each buffer in which Eglot is active, it notifies the language server that Eglot is 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.

  * Eglot turns on a special minor mode in each buffer it manages.  This minor mode ensures the server is notified about files Eglot manages, and also arranges for other Emacs features supported by Eglot (see Eglot Features) to receive information from the language server, by changing the settings of these features.  Unlike other minor-modes, this special minor mode is not activated manually by the user, but automatically, as the result of starting an Eglot session for the buffer.  However, this minor mode provides a hook variable eglot-managed-mode-hook that can be used to customize the Eglot management of the buffer.  This hook is run both when the minor mode is turned on and when it's turned off; use the variable eglot-managed-p to tell if current buffer is still being managed or not.  When Eglot stops managing the buffer, this minor mode is turned off, and all the settings that Eglot changed are restored to their original values.

  * 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 /home/joe/projects/fooey/lib/y.foo in the above example will notify the server of the *.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.

Eglot Commands
==============

This section provides a reference for the most commonly used Eglot commands:

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 major-mode (see Major Modes (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 C-u, it always prompts for the server program, and if invoked with 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 (see 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 eglot-stay-out-of option (see Customizing Eglot).

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.

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 (see 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 C-u, the command doesn't kill those buffers, allowing them to be used for diagnostics and problem reporting (see Troubleshooting Eglot).

M-x eglot-shutdown-all
     This command shuts down all the language servers active in the current Emacs session.  As with eglot-shutdown, invoking this command with a prefix argument avoids killing the buffers used for communications with the language servers.

M-x eglot-rename
     This command renames the program symbol (a.k.a. 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.

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.

M-x eglot-format-buffer
     This command reformats the current buffer, in the same manner as eglot-format does.

M-x eglot-code-actions
M-x eglot-code-action-organize-imports
M-x eglot-code-action-quickfix
M-x eglot-code-action-extract
M-x eglot-code-action-inline
M-x eglot-code-action-rewrite
     These commands allow you to invoke the so-called 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 eglot-code-actions asks the server if there 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 (see GNU Flymake manual). Clicking on a diagnostic with mouse-2 invokes eglot-code-actions-at-mouse which pops up a menu of available code actions.  The variable eglot-diagnostics-map can be used to control the mouse binding.

     Other commands execute a specific code action.  For example, eglot-code-action-organize-imports rearranges the program's imports---declarations of modules whose capabilities the program uses.

M-x eglot-inlay-hints-mode
     This command toggles LSP 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.

The following Eglot commands are used less commonly, mostly for diagnostic and troubleshooting purposes:

M-x eglot-events-buffer
     This command pops up the events buffer used for communication with the language server of the current buffer.

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.

M-x eglot-forget-pending-continuations
     Forget pending requests for the server of the current buffer.

M-x eglot-signal-didChangeConfiguration
     This command updates the language server configuration according to the current value of the variable eglot-workspace-configuration (see Customizing Eglot).

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 (see Troubleshooting Eglot).  If the situation is deemed uninteresting or temporary, this command can be used to ``forget'' the error.  Note that the command M-x eglot-reconnect can sometimes be used to unclog a temporarily malfunctioning server.

As described in 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:

M-x eldoc
     Ask the ElDoc system for help at point.

M-x flymake-show-buffer-diagnostics
     Ask Flymake system to display diagnostics for the current buffer.

M-x flymake-show-project-diagnostics
     Ask Flymake to list diagnostics for all the files in the current project.

M-x xref-find-definitions
     Ask Xref to go the definition of the identifier at point.

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.

M-x completion-at-point
     Request completion of the symbol at point.

Eglot Variables
===============

This section provides a reference for the Eglot user options.

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 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 t means always reconnect automatically, and nil means never reconnect (in which case you will need to reconnect manually using M-x eglot).

eglot-connect-timeout
     This specifies the number of seconds before connection attempt to a language server times out.  The value of nil means never time out.  The default is 30 seconds.

eglot-sync-connect
     This setting is mainly important for connections which are slow to establish.  Whereas the variable 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 3; a positive value means block for that many seconds, then wait for the connection in the background.  The value of t means block during the whole waiting period.  The value of nil or 0 means don't block at all during the waiting period.

eglot-events-buffer-size
     This determines the size of the Eglot events buffer.  See eglot-events-buffer, for how to display that buffer.  If the value is changed, for it to take effect the connection should be restarted using M-x eglot-reconnect. See Troubleshooting Eglot, for when this could be useful.

eglot-autoshutdown
     If this is non-nil, Eglot shuts down a language server when the last buffer managed by it is killed.  See Shutting Down LSP Servers. The default is nil; if you want to shut down a server, use M-x eglot-shutdown (see Eglot Commands).

eglot-confirm-server-initiated-edits
     Various Eglot commands and code actions result in the language server sending editing commands to Emacs.  If this option's value is non-nil (the default), Eglot will ask for confirmation before performing edits initiated by the server or edits whose scope affects buffers other than the one where the user initiated the request.

eglot-ignored-server-capabilities
     This variable's value is a list of language server capabilities that Eglot should not use.  The default is nil: Eglot uses all of the capabilities supported by each server.

eglot-extend-to-xref
     If this is non-nil, and M-. (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. project-find-file won't find it), but Eglot and the server will consider it to be part of the workspace.  The default is nil.

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: C-h . is remapped to invoke eldoc-doc-buffer.  You can bind additional commands in this map.  For example:

            (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)

Additional variables, which are relevant for customizing the server connections, are documented in Customizing Eglot.

Customizing Eglot
*****************

Eglot itself has a relatively small number of customization options. A large part of customizing Eglot to your needs and preferences should actually be done via options of the Emacs packages and features which Eglot supports and enhances (see Eglot Features).  For example:

  * To configure the face used for server-derived errors and warnings, customize the Flymake faces flymake-error and flymake-warning.

  * To configure the amount of space taken up by documentation in the echo area, customize the ElDoc variable eldoc-echo-area-use-multiline-p.

  * To completely change how ElDoc displays the at-point documentation destination, customize the ElDoc variable eldoc-display-functions.

For this reason, this manual describes only how to customize Eglot's own operation, which mainly has to do with the server connections and the server features to be used by Eglot.

eglot-server-programs
     This variable determines which language server to start for each supported major mode, and how to invoke that server's program. See Setting Up LSP Servers, for the details.

eglot-strict-mode
     This is nil by default, meaning that Eglot is generally lenient about non-conforming servers.  If you need to debug a server, set this to (disallow-non-standard-keys enforce-required-keys).

eglot-server-initialized-hook
     A hook run after the server object is successfully initialized.

eglot-connect-hook
     A hook run after connection to the server is successfully established.  See Starting Eglot.

eglot-managed-mode-hook
     A hook run after Eglot started or stopped managing a buffer. See Eglot and Buffers, for details of its usage.

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 xref to leave Xref alone, or the string company to stay away from your Company customizations.  Here's an example:

          (add-to-list 'eglot-stay-out-of 'flymake)

     Note that you can still configure the excluded Emacs features manually to use Eglot in your eglot-managed-mode-hook or via some other mechanism.

eglot-report-progress
     Set this variable to true if you'd like progress notifications coming from the language server to be handled as Emacs's progress reporting facilities.

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 eglot-server-programs (see 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:

  * Project-specific, applying to a specific project;

  * User-specific, applying to all projects the server is used for.

When you have decided which kind you need, the following sections teach how Eglot's user variables can be used to achieve it:

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 HOME directory or in a project's directory.  For example, the pylsp Python server reads the file ~/.config/pycodestyle for user configuration.  The clangd C/C++ server reads both ~/.config/clangd/config.yaml for user configuration and .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.

Project-specific configuration
==============================

To set project-specific settings, which the LSP specification calls workspace configuration, the variable eglot-workspace-configuration may be used.

This variable is a directory-local variable (see Per-directory Local Variables (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 eglot-workspace-configuration  is using a .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 dir-locals-set-class-variables function.  (see Directory Local Variables (GNU Emacs Lisp Reference Manual)).

However you choose to set it, the variable's value is a plist (see Property Lists (GNU Emacs Lisp Reference Manual)) with the following format:

      (:SERVER1 PLIST1 :SERVER2 PLIST2 ...)

Here, :SERVER1 and :SERVER2 are keywords whose names identify the LSP language servers to target.  Consult server documentation to find out what name to use.  PLIST1 and PLIST2 are plists of options, possibly nesting other plists.

When experimenting with workspace settings, you can use the command 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 (see 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 M-x eglot-signal-didChangeConfiguration which notifies the server during an ongoing Eglot session.

Examples
--------

For some users, setting 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 (see Association Lists (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 pylsp and 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:

     pylsp.plugins.jedi_completion.include_params: true
     pylsp.plugins.jedi_completion.fuzzy: true
     pylsp.pylint.enabled: false
     gopls.usePlaceholders: true

To apply this to Eglot, and assuming you chose the .dir-locals.el file method, the contents of that file could be:

     ((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))))

This sets the value of eglot-workspace-configuration in all the buffers inside the project; each server will use only the section of the parameters intended for that server, and ignore the rest.  Note how alists are used for associating Emacs mode names with alists associating variable names with variable values.  Then notice how plists are used inside the value of eglot-workspace-configuration.

This following form may also be used:

     ((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))))

This sets up the value of eglot-workspace-configuration separately depending on the major mode of each of that project's buffers.  python-base-mode buffers will have the variable set to (:pylsp (:plugins ...)).  go-mode buffers will have the variable set to (:gopls (:usePlaceholders t)).

Some servers will issue workspace configuration for specific files inside your project.  For example, if you know gopls is asking about specific files in the src/imported subdirectory and you want to set a different option for gopls.usePlaceholders , you may use something like:

     ((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))))))

Finally, if one needs to determine the workspace configuration based on some dynamic context, eglot-workspace-configuration can be set to a function.  The function is called with the eglot-lsp-server instance of the connected server (if any) and with default-directory set to the root of the project.  The function should return a plist suitable for use as the variable's value.

User-specific configuration
===========================

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 eglot-server-programs.  Let's say we want to configure where the clangd server reads its compile_commands.json from.  This can be done like so:

     (with-eval-after-load 'eglot
       (add-to-list 'eglot-server-programs
                    `(c++-mode . ("clangd" "--compile-commands-dir=/tmp"))))

Another way is to have Eglot pass a JSON object to the server during the LSP handshake.  This is done using the :initializationOptions syntax of eglot-server-programs:

     (with-eval-after-load 'eglot
       (add-to-list 'eglot-server-programs
                    `(c++-mode . ("clangd" :initializationOptions
                                           (:compilationDatabasePath "/tmp")))))

The argument (:compilationDatabasePath "/tmp") is Emacs's representation in plist format of a simple JSON object {"compilationDatabasePath": "/tmp"}.  To learn how to represent more deeply nested options in this format, see 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.

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 globally setting 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 Project-specific configuration.  Here is an example:

     (setq-default eglot-workspace-configuration
                   '(:pylsp (:plugins (:jedi_completion (:include_params t
                                                         :fuzzy t)
                                       :pylint (:enabled :json-false)))
                     :gopls (:usePlaceholders t)))

Note that the global value of eglot-workspace-configuration is always overridden if a directory-local value is detected.

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 (see Property Lists (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 true, false, null and {}, you can use the Lisp values t, :json-false, nil, and eglot-{}, respectively. JSON arrays are represented as Elisp vectors surrounded by square brackets (see Vectors (GNU Emacs Lisp Reference Manual)).

For example, the plist

     (:pylsp (:plugins (:jedi_completion (:include_params t
                                          :fuzzy t
                                          :cache_for ["pandas" "numpy"])
                        :pylint (:enabled :json-false)))
      :gopls (:usePlaceholders t))

is serialized by Eglot to the following JSON text:

     {
       "pylsp": {
         "plugins": {
           "jedi_completion": {
             "include_params": true,
             "fuzzy": true,
             "cache_for": [ "pandas", "numpy" ]
           },
           "pylint": {
             "enabled": false
           }
         }
       },
       "gopls": {
         "usePlaceholders": true
       }
     }

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 M-x eglot-events-buffer and 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.

Performance
===========

A common and easy-to-fix cause of performance problems is the length of the Eglot events buffer because it represent additional work that Eglot must do.  After verifying Eglot is operating correctly but slowly, try to customize the variable eglot-events-buffer-size (see Eglot Variables) to 0.  This will disable any debug logging 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 (see Advanced server configuration).

Getting the latest version
==========================

To install the latest Eglot in an Emacs version that does not bundle Eglot, use 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 M-x eglot-upgrade-eglot.  This will replace any currently installed version with the newest one available from the ELPA archives configured in package-archives.

You can also update Eglot through other methods, such as use-package (see Installing packages (use-package User Manual)), package-install, list-packages or the newer package-upgrade (see Packages (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.

Reporting bugs
==============

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 difficult and absolutely essential that the maintainers reproduce bugs exactly as they happened to you, the user.

To report an Eglot bug, send e-mail to bug-gnu-emacs@gnu.org.

To understand how to write this email, get acquainted with Emacs's bug reporting guidelines (see Bugs (GNU Emacs Manual)).  Then, follow this Eglot-specific checklist:

 1. Include the transcript of JSONRPC events obtained from the buffer popped up by 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.

 2. If Emacs signaled an error (an error message was seen or heard), make sure to repeat the process after turning on debug-on-error via M-x toggle-debug-on-error.  This normally produces a backtrace of the error that should also be attached to the bug report.

 3. 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++ or Python servers, as these are very easy to install.

 4. Describe how to setup a 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.

 5. Include versions of the software used.  The Emacs version can be obtained with 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 (see 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 ~/.emacs.d/elpa (or what is in package-user-dir).  Including a listing of files in that directory is a way to tell the maintainers about ELPA package versions.

 6. Include a recipe to replicate the problem with a clean Emacs run.  The invocation emacs -Q -f package-initialize starts Emacs with no configuration and initializes the ELPA packages.  A very minimal .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 require statements in the recipe, as Eglot's functionality uses autoloads.

     Likewise, there is rarely the need to use things like use-package or eglot-ensure.  This just makes the recipe harder to follow.  Prefer setting variables with setq and adding to hooks with add-hook.  Prefer starting Eglot with M-x eglot.

 7. 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.

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.

GNU Free Documentation License
******************************

     [file doclicense.texi not included]