Skip to content

Multi-server support ​

One of the most frequently requested features for Eglot in close to a decade of existence is the ability to use more than one LSP server in a single buffer. This is distinct from using multiple servers in a project, where each server manages a disjoint set of files written in different languages.

The latter case—multiple servers for different files—is intrinsically supported by Eglot. For example, in a web project with JavaScript, CSS, and Python files, Eglot can seamlessly manage separate language servers for each file type within the same project (see Starting Eglot). Each buffer communicates with its appropriate server, and this works out-of-the-box.

However, there are several scenarios where multiple servers per buffer are useful:

  • Combining a spell-checking language server like codebook-lsp with language-specific servers for C++, Go, or Python files. The spell-checker provides diagnostics for comments and strings, while the language server handles syntax and semantics.
  • One might want multiple servers to cover different aspects of the same language. For Python, you might combine ty for type checking with ruff for linting and formatting. For JavaScript, you might use typescript-language-server for language features together with eslint for linting.
  • When working on multi-language files like Vue .vue files, which contain JavaScript, CSS, and HTML embedded in a single file, multiple servers can manage the different areas of the buffer.

These use cases are not directly supported by Eglot’s architecture, however, you can use a language-agnostic LSP server multiplexer that sits between Eglot and the actual language servers. Eglot still communicates with a single LSP server process in each buffer, but that process mediates communication to multiple language-specific servers, meaning that for practical purposes, it’s as if Eglot was connected to them directly.

This approach is more powerful and user-friendly than current workarounds that combine one LSP server in a buffer with additional non-LSP mechanisms such as extra Flymake backends (see GNU Flymake manual) for the same buffer.