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 LSP 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, the project’s buffers are treated specially in several ways:
- 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, whereserveris the name of the server andprojectidentifies 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 customizingeglot-mode-line-format(see Customization Variables). - 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.
- 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.fooin the above example will notify the server of the*.foofiles’ 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 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 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.
- 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. See Eglot Features.
- To customize this, Eglot’s special minor mode provides a hook variable
eglot-managed-mode-hookspecifically 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 functioneglot-managed-pto tell if current buffer is still being managed or not.
For example, to turn off inlay hints and semantic tokens by default but still retain the ability to turn them on again interactively use this: