3.2 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 in 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 in GNU Emacs
Manual).
- An EDE project: source files in a directory hierarchy managed via the
Emacs Development Environment (see EDE in 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.