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, 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. - 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-hookthat 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 functioneglot-managed-pto 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.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.