joaotavora / eglot

A client for Language Server Protocol servers
GNU General Public License v3.0
2.21k stars 203 forks source link

Formatting parameters are not exposed #1380

Closed brosasaki closed 3 months ago

brosasaki commented 3 months ago

If you have a major-mode which sets its own formatting parameters (i.e. uses its own version of tab-width), then there is no way to communicate that to eglot so that requests to format the file, etc. use the proper formatting parameters.

Reproduction Recipe

  1. Ensure R and its languageserver package are installed along with the latest version of ess.
  2. Open a .R script and start the language server.
  3. Use M-x ess-set-style or C-c C-e s to set the style to something with an ess-indent-offset of something other than tab-width (by default, this is 'RRR', with a 4-wide indent and call-aligned function arguments--very different from tab-width's default 8).
  4. Indent your code with indent-region or indent-paragraph*.
  5. Use M-x eglot-format-buffer and watch it change all of the indentation again*.

*There is a bug in languageserver right now in which the indentation linter is hardcoded to a 2-space indent, so it may be marked as incorrect indentation, even after the same language server (which the linter is a part of) just formatted it. But that is a langageserver problem.

Solution Pointers

Looking over the source, it looks like maybe changing these lines to refer to new package options which could be specified per-major-mode (e.g. in eglot-server-programs) would allow for users to specify which variables are the correct formatting parameters for each major mode. But, since I do not understand the codebase well, I am hesitant to write the patch myself for now.

joaotavora commented 3 months ago

There is no real harmony between Elisp indent-region and LSP "formatting". There never was, and I doubt if it is even possible. Elisp's indentation is about inserting or removing spaces or tabs at the beginning of the line, whereas LSP's is about adding/removing arbitrary whitespace (or maybe even more than that...).

The best you can hope for is baking an indent-region-function, but that didn't work very well last time I tried it: https://mail.gnu.org/archive/html/bug-gnu-emacs/2023-07/msg01541.html