dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

README.md (24279B)


      1 [![Build Status](https://travis-ci.org/joaotavora/eglot.png?branch=master)](https://travis-ci.org/joaotavora/eglot)
      2 [![GNU ELPA](https://elpa.gnu.org/packages/eglot.svg)](https://elpa.gnu.org/packages/eglot.html)
      3 [![MELPA](https://melpa.org/packages/eglot-badge.svg)](https://melpa.org/#/eglot)
      4 
      5 # M-x Eglot
      6 
      7 *E*macs Poly*glot*: an Emacs [LSP][lsp] client that stays out of your
      8 way:
      9 
     10 * 📽 Scroll down this README for some [pretty gifs](#animated_gifs)
     11 * 📚 Read about [servers](#connecting), [commands and
     12   keybindings](#commands), and [customization](#customization)
     13 * 📣 Read the [NEWS][news] file
     14 * 🏆 Folks over at Google [seem to like it][gospb].  Thanks!
     15 
     16 # _1-2-3_
     17 
     18 Install from [GNU ELPA][gnuelpa] or [MELPA][melpa].  Just type `M-x
     19 package-install RET eglot RET` into Emacs 26.1+.
     20 
     21 Now find some source file, any source file, and type `M-x eglot`.
     22 
     23 *That's it*. If you're lucky, this guesses the LSP program to start
     24 for the language you're using. Otherwise, it prompts you to enter one.
     25 
     26 ### _1-2-3-pitfall!_
     27 
     28 By design, Eglot doesn't depend on anything but Emacs.  But there
     29 _are_ ELPA dependencies to newer versions of so-called "core packages"
     30 developed _in the Emacs mainline_.  So unless you're using a
     31 bleeding-edge Emacs, where loading `eglot.el` is all you'd need to do,
     32 make sure your package system pulls in and loads the newest
     33 `project.el`, `xref.el`, `eldoc.el`, etc...  In case of trouble `M-x
     34 find-library` can help you tell if that happened.
     35 
     36 <a name="connecting"></a>
     37 # Connecting to a server
     38 
     39 `M-x eglot` can guess and work out-of-the-box with these servers:
     40 
     41 * Javascript's [TS & JS Language Server ][typescript-language-server]
     42 * Rust's [rls][rls]
     43 * Python's [pylsp][pylsp], [pyls][pyls] or [pyright][pyright]
     44 * Ruby's [solargraph][solargraph]
     45 * Java's [Eclipse JDT Language Server][eclipse-jdt]
     46 * Bash's [bash-language-server][bash-language-server]
     47 * PHP's [php-language-server][php-language-server]
     48 * C/C++'s [clangd][clangd] or [ccls][ccls]
     49 * Haskell's [haskell-language-server][haskell-language-server]
     50 * Elm's [elm-language-server][elm-language-server]
     51 * Mint's [mint-ls][mint-ls]
     52 * Kotlin's [kotlin-language-server][kotlin-language-server]
     53 * Go's [gopls][gopls]
     54 * Ocaml's [ocaml-lsp][ocaml-lsp]
     55 * R's [languageserver][r-languageserver]
     56 * Dart's [dart_language_server][dart_language_server]
     57 * Elixir's [elixir-ls][elixir-ls]
     58 * Erlang's [erlang_ls][erlang_ls]
     59 * Ada's [ada_language_server][ada_language_server]
     60 * Scala's [metals][metals]
     61 * TeX/LaTeX's [Digestif][digestif]
     62 * Nix's [rnix-lsp][rnix-lsp]
     63 * Godot Engine's [built-in LSP][godot]
     64 * Fortran's [fortls][fortls]
     65 * Zig's [zls][zls]
     66 * FSharp's [fsharp-mode][fsharp-mode] (Needs to `(require 'eglot-fsharp)` first)
     67 * YAML's [yaml-language-server][yaml-language-server]
     68 * Lua's [lua-lsp][lua-lsp]
     69 * HTML [html-languageserver][html-languageserver]
     70 * CSS's [css-languageserver][css-languageserver]
     71 * JSON's [vscode-json-languageserver][vscode-json-languageserver]
     72 * Dockerfile's [docker-langserver][docker-langserver]
     73 * CMake's [cmake-language-server][cmake-language-server]
     74 * VimScript's [vim-language-server][vim-language-server]
     75 
     76 I'll add to this list as I test more servers. In the meantime you can
     77 customize `eglot-server-programs`:
     78 
     79 ```lisp
     80 (add-to-list 'eglot-server-programs '(foo-mode . ("foo-language-server" "--args")))
     81 ```
     82 
     83 Let me know how well it works and we can add it to the list.  
     84 
     85 To skip the guess and always be prompted use `C-u M-x eglot`.
     86 
     87 ## Connecting automatically
     88 
     89 You can also do:
     90 
     91 ```lisp
     92   (add-hook 'foo-mode-hook 'eglot-ensure)
     93 ```
     94 
     95 , to attempt to start an eglot session automatically every time a
     96 `foo-mode` buffer is visited.
     97 
     98 ## Connecting via TCP
     99 
    100 The examples above use a "pipe" to talk to the server, which works
    101 fine on Linux and OSX but in some cases
    102 [*may not work on Windows*][windows-subprocess-hang].
    103 
    104 To circumvent this limitation, or if the server doesn't like pipes,
    105 you can use `C-u M-x eglot` and give it `server:port` pattern to
    106 connect to a previously started TCP server serving LSP information.
    107 
    108 If you don't want to start it manually every time, you can configure
    109 Eglot to start it and immediately connect to it.  Ruby's
    110 [solargraph][solargraph] server already works this way out-of-the-box.
    111 
    112 For another example, suppose you also wanted start Python's `pyls`
    113 this way:
    114 
    115 ```lisp
    116 (add-to-list 'eglot-server-programs
    117              `(python-mode . ("pyls" "-v" "--tcp" "--host"
    118                               "localhost" "--port" :autoport)))
    119 ```
    120 
    121 You can see that the element associated with `python-mode` is now a
    122 more complicated invocation of the `pyls` program, which requests that
    123 it be started as a server.  Notice the `:autoport` symbol in there: it
    124 is replaced dynamically by a local port believed to be vacant, so that
    125 the ensuing TCP connection finds a listening server.
    126 
    127 ## Per-project server configuration
    128 
    129 Most servers can guess good defaults and will operate nicely
    130 out-of-the-box, but some need to be configured specially via LSP
    131 interfaces.  Additionally, in some situations, you may also want a
    132 particular server to operate differently across different projects.
    133 
    134 Per-project settings are realized with Emacs's _directory variables_
    135 and the Elisp variable `eglot-workspace-configuration`.  To make a
    136 particular Python project always enable Pyls's snippet support, put a
    137 file named `.dir-locals.el` in the project's root:
    138 
    139 ```lisp
    140 ((python-mode
    141   . ((eglot-workspace-configuration
    142       . ((:pyls . (:plugins (:jedi_completion (:include_params t)))))))))
    143 ```
    144 
    145 This tells Emacs that any `python-mode` buffers in that directory
    146 should have a particular buffer-local value of
    147 `eglot-workspace-configuration`.  That variable's value should be
    148 _association list_ of _parameter sections_ which are presumably
    149 understood by the server.  In this example, we associate section
    150 `pyls` with the parameters object `(:plugins (:jedi_completion
    151 (:include_params t)))`.
    152 
    153 Now, supposing that you also had some Go code in the very same
    154 project, you can configure the Gopls server in the same file.  Adding
    155 a section for `go-mode`, the file's contents become:
    156 
    157 ```lisp
    158 ((python-mode
    159   . ((eglot-workspace-configuration
    160       . ((:pyls . (:plugins (:jedi_completion (:include_params t))))))))
    161  (go-mode
    162   . ((eglot-workspace-configuration
    163       . ((:gopls . (:usePlaceholders t)))))))
    164 ```
    165 
    166 If you can't afford an actual `.dir-locals.el` file, or if managing
    167 these files becomes cumbersome, the Emacs manual teaches you
    168 programmatic ways to leverage per-directory local variables.
    169 
    170 ## Handling quirky servers
    171 
    172 Some servers need even more special hand-holding to operate correctly.
    173 If your server has some quirk or non-conformity, it's possible to
    174 extend Eglot via Elisp to adapt to it.  Here's an example on how to
    175 get [cquery][cquery] working:
    176 
    177 ```lisp
    178 (add-to-list 'eglot-server-programs '((c++ mode c-mode) . (eglot-cquery "cquery")))
    179 
    180 (defclass eglot-cquery (eglot-lsp-server) ()
    181   :documentation "A custom class for cquery's C/C++ langserver.")
    182 
    183 (cl-defmethod eglot-initialization-options ((server eglot-cquery))
    184   "Passes through required cquery initialization options"
    185   (let* ((root (car (project-roots (eglot--project server))))
    186          (cache (expand-file-name ".cquery_cached_index/" root)))
    187     (list :cacheDirectory (file-name-as-directory cache)
    188           :progressReportFrequencyMs -1)))
    189 ```
    190 
    191 See `eglot.el`'s section on Java's JDT server for an even more
    192 sophisticated example.
    193 
    194 Similarly, some servers require the language identifier strings they
    195 are sent by `eglot` to match the exact strings used by VSCode. `eglot`
    196 usually guesses these identifiers from the major mode name
    197 (e.g. `elm-mode` → `"elm"`), but the mapping can be overridden using
    198 the `:LANGUAGE-ID` element in the syntax of `eglot-server-programs` if
    199 necessary.
    200 
    201 ## TRAMP support
    202 
    203 Should just work.  Try `M-x eglot` in a buffer visiting a remote file
    204 on a server where you've also installed the language server.  Only
    205 supported on Emacs 27.1 or later.
    206 
    207 Emacs 27 users may find some language servers [fail to start up over
    208 TRAMP](https://github.com/joaotavora/eglot/issues/662).  If you experience this
    209 issue, update TRAMP to 2.5.0.4 or later.
    210 
    211 <a name="reporting bugs"></a>
    212 # Reporting bugs
    213 
    214 Having trouble connecting to a server?  Expected to have a certain
    215 capability supported by it (e.g. completion) but nothing happens?  Or
    216 do you get spurious and annoying errors in an otherwise smooth
    217 operation?  We may have help, so open a [new
    218 issue](https://github.com/joaotavora/eglot/issues) and try to be as
    219 precise and objective about the problem as you can:
    220 
    221 1. Include the invaluable **events transcript**.  You can display that
    222    buffer with `M-x eglot-events-buffer`.  It contains the JSONRPC
    223    messages exchanged between client and server, as well as the
    224    messages the server prints to stderr.
    225     
    226 2. If Emacs errored (you saw -- and possibly heard -- an error
    227    message), make sure you repeat the process using `M-x
    228    toggle-debug-on-error` so you **get a backtrace** of the error that
    229    you should also attach to the bug report.
    230    
    231 3. Try to replicate the problem with **as clean an Emacs run as
    232    possible**.  This means an empty `.emacs` init file or close to it
    233    (just loading `eglot.el`, `company.el` and `yasnippet.el` for
    234    example, and you don't even need `use-package.el` to do that).
    235        
    236 Some more notes: it is often the case the you will have to report the
    237 problem to the LSP server's developers, too, though it's
    238 understandable that you report it Eglot first, since it is the
    239 user-facing frontend first.  If the problem is indeed on Eglot's side,
    240 we _do_ want to fix it, but because Eglot's developers have limited
    241 resources and no way to test all the possible server combinations,
    242 you'll sometimes have to do most of the testing.
    243 
    244 <a name="commands"></a>
    245 # Commands and keybindings
    246 
    247 Here's a summary of available commands:
    248 
    249 - `M-x eglot`, as described above;
    250 
    251 - `M-x eglot-reconnect` reconnects to current server;
    252 
    253 - `M-x eglot-shutdown` says bye-bye to server of your choice;
    254 
    255 - `M-x eglot-shutdown-all` says bye-bye to every server;
    256 
    257 - `M-x eglot-rename` ask the server to rename the symbol at point;
    258 
    259 - `M-x eglot-format` asks the server to format buffer or the active
    260   region;
    261 
    262 - `M-x eglot-code-actions` asks the server for any "code actions" at
    263   point. Can also be invoked by `mouse-1`-clicking some diagnostics.
    264   Also `M-x eglot-code-action-<TAB>` for shortcuts to specific actions.
    265 
    266 - `M-x eldoc` asks the Eldoc system for help at point (this command
    267   isn't specific to Eglot, by the way, it works in other contexts).
    268 
    269 - `M-x eglot-events-buffer` jumps to the events buffer for debugging
    270   communication with the server.
    271 
    272 - `M-x eglot-stderr-buffer` if the LSP server is printing useful debug
    273 information in stderr, jumps to a buffer with these contents.
    274 
    275 - `M-x eglot-signal-didChangeConfiguration` updates the LSP server
    276 configuration according to the value of the variable
    277 `eglot-workspace-configuration`, which you may be set in a
    278 `.dir-locals` file, for example.
    279 
    280 There are *no keybindings* specific to Eglot, but you can bind stuff
    281 in `eglot-mode-map`, which is active as long as Eglot is managing a
    282 file in your project. The commands don't need to be Eglot-specific,
    283 either:
    284 
    285 ```lisp
    286 (define-key eglot-mode-map (kbd "C-c r") 'eglot-rename)
    287 (define-key eglot-mode-map (kbd "C-c o") 'eglot-code-action-organize-imports)
    288 (define-key eglot-mode-map (kbd "C-c h") 'eldoc)
    289 (define-key eglot-mode-map (kbd "<f6>") 'xref-find-definitions)
    290 ```
    291 
    292 <a name="customization"></a>
    293 # Customization
    294 
    295 Here's a quick summary of the customization options.  In Eglot's
    296 customization group (`M-x customize-group`) there is more
    297 documentation on what these do.
    298 
    299 - `eglot-autoreconnect`: Control ability to reconnect automatically to
    300   the LSP server;
    301 
    302 - `eglot-connect-timeout`: Number of seconds before timing out LSP
    303   connection attempts;
    304 
    305 - `eglot-sync-connect`: Control blocking of LSP connection attempts;
    306 
    307 - `eglot-events-buffer-size`: Control the size of the Eglot events
    308   buffer;
    309 
    310 - `eglot-ignored-server-capabilities`: LSP server capabilities that
    311   Eglot could use, but won't;
    312 
    313 - `eglot-confirm-server-initiated-edits`: If non-nil, ask for confirmation 
    314   before allowing server to edit the source buffer's text;
    315 
    316 There are a couple more variables that you can customize via Emacs
    317 lisp:
    318 
    319 - `eglot-server-programs`: as described [above](#connecting);
    320 
    321 - `eglot-strict-mode`: Set to `nil` by default, meaning Eglot is
    322   generally lenient about non-conforming servers.  Set this to
    323   `(disallow-non-standard-keys enforce-required-keys)` when debugging
    324   servers.
    325 
    326 - `eglot-server-initialized-hook`: Hook run after server is
    327   successfully initialized;
    328 
    329 - `eglot-managed-mode-hook`: Hook run after Eglot started or stopped
    330   managing a buffer.  Use `eglot-managed-p` to tell if current buffer
    331   is still being managed.
    332 
    333 - `eglot-stay-out-of`: List of Emacs features that Eglot shouldn't
    334   automatically try to manage on users' behalf.  Useful when you need
    335   non-LSP Flymake or Company backends.  See docstring for examples.
    336   
    337 - `eglot-extend-to-xref`: If non-nil and `xref-find-definitions` lands
    338   you in a file outside your project -- like a system-installed
    339   library or header file -- transiently consider it managed by the
    340   same LSP server.  That file is still outside your project
    341   (i.e. `project-find-file` won't find it).
    342 
    343 # How does Eglot work?
    344 
    345 `M-x eglot` starts a server via a shell-command guessed from
    346 `eglot-server-programs`, using the current major-mode (for whatever
    347 language you're programming in) as a hint.
    348 
    349 If the connection is successful, you see an `[eglot:<server>]`
    350 indicator pop up in your mode-line.  More importantly, this means
    351 current *and future* file buffers of that major mode *inside your
    352 current project* automatically become \"managed\" by the LSP server,
    353 This means that information about these file's contents is exchanged
    354 periodically to provide enhanced coding assistance.  Eglot works
    355 primarily with Emacs' built-in libraries and _not_ with third-party
    356 replacements for those facilities.
    357 
    358 * definitions can be found via `xref-find-definitions`;
    359 * on-the-fly diagnostics are given by `flymake-mode`;
    360 * function signature hints are given by `eldoc-mode`;
    361 * completion can be summoned with `completion-at-point`.
    362 * projects are discovered via `project.el`'s API;
    363 
    364 Some extra features are provided if certain libraries are installed
    365 and enabled, such as:
    366 
    367 * completion dropdowns via [company];
    368 * snippet completions via [yasnippet];
    369 * marked-up documentation via [markdown].
    370 
    371 Eglot doesn't _require_ these libraries to work effectively, but will
    372 use them automatically if they are found to be active.
    373 
    374 To "unmanage" a project's buffers, shutdown the server with `M-x
    375 eglot-shutdown`.
    376 
    377 # Supported Protocol features
    378 
    379 ## General
    380 - [x] initialize
    381 - [x] initialized
    382 - [x] shutdown
    383 - [x] exit
    384 - [ ] $/cancelRequest
    385 
    386 ## Window
    387 - [x] window/showMessage
    388 - [x] window/showMessageRequest
    389 - [x] window/logMessage
    390 - [x] telemetry/event
    391 
    392 ## Client
    393 - [x] client/registerCapability (but only
    394   `workspace/didChangeWatchedFiles`, like RLS asks)
    395 - [x] client/unregisterCapability  (ditto)
    396 
    397 ## Workspace
    398 - [ ] workspace/workspaceFolders (3.6.0)
    399 - [ ] workspace/didChangeWorkspaceFolders (3.6.0)
    400 - [x] workspace/didChangeConfiguration
    401 - [x] workspace/configuration (3.6.0)
    402 - [x] workspace/didChangeWatchedFiles
    403 - [x] workspace/symbol
    404 - [x] workspace/executeCommand
    405 - [x] workspace/applyEdit
    406 
    407 ## Text Synchronization
    408 - [x] textDocument/didOpen
    409 - [x] textDocument/didChange (incremental or full)
    410 - [x] textDocument/willSave
    411 - [x] textDocument/willSaveWaitUntil
    412 - [x] textDocument/didSave
    413 - [x] textDocument/didClose
    414 
    415 ## Diagnostics
    416 - [x] textDocument/publishDiagnostics
    417 
    418 ## Language features
    419 - [x] textDocument/completion
    420 - [x] completionItem/resolve (works quite well with [company-mode][company-mode])
    421 - [x] textDocument/hover
    422 - [x] textDocument/signatureHelp (fancy stuff with Python's [pyls][pyls])
    423 - [x] textDocument/definition
    424 - [x] textDocument/typeDefinition (3.6.0)
    425 - [x] textDocument/implementation (3.6.0)
    426 - [x] textDocument/declaration (3.14)
    427 - [x] textDocument/references
    428 - [x] textDocument/documentHighlight
    429 - [x] textDocument/documentSymbol
    430 - [x] textDocument/codeAction
    431 - [ ] textDocument/codeLens
    432 - [ ] codeLens/resolve
    433 - [ ] textDocument/documentLink
    434 - [ ] documentLink/resolve
    435 - [ ] textDocument/documentColor
    436 - [ ] textDocument/colorPresentation (3.6.0)
    437 - [x] textDocument/formatting 
    438 - [x] textDocument/rangeFormatting
    439 - [ ] textDocument/onTypeFormatting
    440 - [x] textDocument/rename
    441 
    442 <a name="animated_gifs"></a>
    443 # _Obligatory animated gif section_
    444 
    445 ## Completion
    446 ![eglot-completions](./gif-examples/eglot-completions.gif)
    447 
    448 The animation shows [company-mode][company] presenting the completion
    449 candidates to the user, but Eglot works with the built-in
    450 `completion-at-point` function as well, which is usually bound to
    451 `C-M-i`.
    452 
    453 ## Snippet completion
    454 ![eglot-snippets-on-completion](./gif-examples/eglot-snippets-on-completion.gif)
    455 
    456 Eglot provides template based completion if the server supports
    457 snippet completion and [yasnippet][yasnippet] is enabled _before_
    458 Eglot connects to the server.  The animation shows
    459 [company-mode][company], but `completion-at-point` also works with
    460 snippets.
    461 
    462 ## Diagnostics
    463 ![eglot-diagnostics](./gif-examples/eglot-diagnostics.gif)
    464 
    465 Eglot relays the diagnostics information received from the server to
    466 [flymake][flymake].  Command `display-local-help` (bound to `C-h .`)
    467 shows the diagnostic message under point, but flymake provides other
    468 convenient ways to handle diagnostic errors.
    469 
    470 When Eglot manages a buffer, it disables other flymake backends.  See
    471 variable `eglot-stay-out-of` to change that.
    472 
    473 ## Code Actions
    474 ![eglot-code-actions](./gif-examples/eglot-code-actions.gif)
    475 
    476 The server may provide code actions, for example, to fix a diagnostic
    477 error or to suggest refactoring edits.  Command `eglot-code-actions`
    478 queries the server for possible code actions at point.  See variable
    479 `eglot-confirm-server-initiated-edits` to customize its behavior.
    480 
    481 ## Hover on symbol
    482 ![eglot-hover-on-symbol](./gif-examples/eglot-hover-on-symbol.gif)
    483 
    484 ## Rename
    485 ![eglot-rename](./gif-examples/eglot-rename.gif)
    486 
    487 Type `M-x eglot-rename RET` to rename the symbol at point.
    488 
    489 ## Find definition
    490 ![eglot-xref-find-definition](./gif-examples/eglot-xref-find-definition.gif)
    491 
    492 To jump to the definition of a symbol, use the built-in
    493 `xref-find-definitions` command, which is bound to `M-.`.
    494 
    495 ## Find references
    496 ![eglot-xref-find-references](./gif-examples/eglot-xref-find-references.gif)
    497 
    498 Eglot here relies on emacs' built-in functionality as well.
    499 `xref-find-references` is bound to `M-?`.  Additionally, Eglot
    500 provides the following similar commands: `eglot-find-declaration`,
    501 `eglot-find-implementation`, `eglot-find-typeDefinition`.
    502 
    503 # Historical differences to lsp-mode.el
    504 
    505 Around May 2018, I wrote a comparison of Eglot to `lsp-mode.el`, and
    506 was discussed with its then-maintainer.  That mode has since been
    507 refactored/rewritten and now
    508 [purports to support](https://github.com/joaotavora/eglot/issues/180)
    509 a lot of features that differentiated Eglot from it.  It may now be
    510 very different or very similar to Eglot, or even sing with the birds
    511 in the trees, so [go check it out][emacs-lsp].  That said, here's the
    512 original comparison, which I will not be updating any more.
    513 
    514 "Eglot is considerably less code and hassle than lsp-mode.el.  In most
    515 cases, there's nothing to configure.  It's a minimalist approach
    516 focused on user experience and performance.
    517 
    518 User-visible differences:
    519 
    520 - The single most visible difference is the friendly entry point `M-x
    521   eglot`, not `M-x eglot-<language>`.  Also, there are no
    522   `eglot-<language>` extra packages.
    523 
    524 - There's no "whitelisting" or "blacklisting" directories to
    525   languages.  `M-x eglot` starts servers to handle file of a major
    526   mode inside a specific project, using Emacs's built-in `project.el`
    527   library to discover projects.  Then it automatically detects current
    528   and future opened files under that project and syncs with server;
    529 
    530 - Easy way to quit/restart a server, just middle/right click on the
    531   connection name;
    532 - Pretty interactive mode-line section for live tracking of server
    533   communication;
    534 - Automatically restarts frequently crashing servers (like RLS);
    535 - Slow-to-start servers start asynchronously in the background;
    536 - Server-initiated edits are confirmed with the user;
    537 - Diagnostics work out-of-the-box (no `flycheck.el` needed);
    538 - Smoother/more responsive (read below).
    539    
    540 Under the hood:
    541 
    542 - Message parser is much simpler.
    543 - Defers signature requests like `textDocument/hover` until server is
    544   ready.
    545 - Sends `textDocument/didChange` for groups of edits, not
    546   one per each tiny change.
    547 - Easier to read and maintain elisp. Yeah I know, *very subjective*,
    548   so judge for yourself.
    549 - Doesn't *require* anything other than Emacs, but will automatically
    550   upgrade to work with stuff outside Emacs, like `company`,
    551   `markdown-mode`, if you happen to have these installed.
    552 - Has automated tests that check against actual LSP servers."
    553 
    554 [lsp]: https://microsoft.github.io/language-server-protocol/
    555 [rls]: https://github.com/rust-lang-nursery/rls
    556 [pyls]: https://github.com/palantir/python-language-server
    557 [pylsp]: https://github.com/python-lsp/python-lsp-server
    558 [pyright]: https://github.com/microsoft/pyright
    559 [gnuelpa]: https://elpa.gnu.org/packages/eglot.html
    560 [melpa]: https://melpa.org/#/eglot
    561 [typescript-language-server]: https://github.com/theia-ide/typescript-language-server
    562 [emacs-lsp]: https://github.com/emacs-lsp/lsp-mode
    563 [emacs-lsp-plugins]: https://github.com/emacs-lsp
    564 [bash-language-server]: https://github.com/mads-hartmann/bash-language-server
    565 [rnix-lsp]: https://github.com/nix-community/rnix-lsp
    566 [yaml-language-server]: https://github.com/redhat-developer/yaml-language-server
    567 [php-language-server]: https://github.com/felixfbecker/php-language-server
    568 [company-mode]: https://github.com/company-mode/company-mode
    569 [cquery]: https://github.com/cquery-project/cquery
    570 [ccls]: https://github.com/MaskRay/ccls
    571 [clangd]: https://clang.llvm.org/extra/clangd.html
    572 [solargraph]: https://github.com/castwide/solargraph
    573 [windows-subprocess-hang]: https://www.gnu.org/software/emacs/manual/html_node/efaq-w32/Subprocess-hang.html
    574 [haskell-language-server]: https://github.com/haskell/haskell-language-server
    575 [elm-language-server]: https://github.com/elm-tooling/elm-language-server
    576 [mint-ls]: https://www.mint-lang.com/
    577 [kotlin-language-server]: https://github.com/fwcd/KotlinLanguageServer
    578 [gopls]: https://github.com/golang/tools/tree/master/gopls
    579 [eclipse-jdt]: https://github.com/eclipse/eclipse.jdt.ls
    580 [ocaml-lsp]: https://github.com/ocaml/ocaml-lsp/
    581 [r-languageserver]: https://cran.r-project.org/package=languageserver
    582 [dart_language_server]: https://github.com/natebosch/dart_language_server
    583 [elixir-ls]: https://github.com/elixir-lsp/elixir-ls
    584 [erlang_ls]: https://github.com/erlang-ls/erlang_ls
    585 [html-languageserver]: https://github.com/hrsh7th/vscode-langservers-extracted
    586 [css-languageserver]: https://github.com/hrsh7th/vscode-langservers-extracted
    587 [vscode-json-languageserver]: https://github.com/hrsh7th/vscode-langservers-extracted
    588 [docker-langserver]: https://github.com/rcjsuen/dockerfile-language-server-nodejs
    589 [cmake-language-server]: https://github.com/regen100/cmake-language-server
    590 [vim-language-server]: https://github.com/iamcco/vim-language-server
    591 [news]: https://github.com/joaotavora/eglot/blob/master/NEWS.md
    592 [ada_language_server]: https://github.com/AdaCore/ada_language_server
    593 [metals]: https://scalameta.org/metals/
    594 [digestif]: https://github.com/astoff/digestif
    595 [company]: https://elpa.gnu.org/packages/company.html
    596 [flymake]: https://www.gnu.org/software/emacs/manual/html_node/flymake/index.html#Top
    597 [yasnippet]: https://elpa.gnu.org/packages/yasnippet.html
    598 [markdown]: https://github.com/defunkt/markdown-mode
    599 [godot]: https://godotengine.org
    600 [fortls]: https://github.com/hansec/fortran-language-server
    601 [gospb]: https://opensource.googleblog.com/2020/10/announcing-latest-google-open-source.html
    602 [zls]: https://github.com/zigtools/zls
    603 [fsharp-mode]: https://github.com/fsharp/emacs-fsharp-mode
    604 [lua-lsp]: https://github.com/Alloyed/lua-lsp