helix-editor / helix

A post-modern modal text editor.
https://helix-editor.com
Mozilla Public License 2.0
32.33k stars 2.38k forks source link

Text edits with the same start position are applied in reverse #11174

Closed kyoh86 closed 3 weeks ago

kyoh86 commented 1 month ago

Summary

Text edits returned from the LSP that have the same start position are being applied in reverse. According to the spec, text edits with the same start position should be applied in the order received.

Recently, the language server client included with Neovim has fixed this bug (https://github.com/neovim/neovim/issues/29202)

Accordingly, using some servers (e.g. efm-langserver) with the client included with Neovim, the formatted lines of the result may be reversed. So I tried to ask the server to fix it (https://github.com/mattn/efm-langserver/issues/281), but the fix causes problems with other (non-specified) clients such as Helix. Therefore, I would like you to implement a fix in Helix that follows the spec, as well as Neovim.

Reproduction Steps

  1. Install efm-langserver with patch to follow the LSP spec.
$ git clone --branch fix-281 https://github.com/kyoh86/efm-langserver.git
$ cd efm-langserver
$ go install .
  1. Set the path
$ export PATH="$(go env GOPATH)/bin:$PATH"
  1. Configure the Helix

helix/languages.toml

[language-server.efm]
command = "efm-langserver"

[[language]]
name = "go"
language-servers = [
  { name = "efm", only-features = [ "diagnostics", "format" ] },
]
  1. Configure the efm-langserver
version: 2

tools:
  echo-fix: &echo-fix
    format-command: zsh -c 'print "foo\nbar\nbaz"'
    format-stdin: true

languages:
  json:
    - <<: *echo-fix
  1. Open helix
$ hx foo.json
  1. Call :format

Expected result:

foo
bar
baz

But actual result:

baz
bar
foo

If you install the efm-langserver without the patch, this doesn't happen.

Helix log

~/.cache/helix/helix.log ``` 2024-07-15T14:46:45.102 helix_lsp::transport [ERROR] efm err <- "2024/07/15 14:46:45 jsonrpc2 handler: sending response 2: jsonrpc2: connection is closed\n" 2024-07-15T14:46:45.104 helix_lsp::transport [ERROR] efm err <- "2024/07/15 14:46:45 efm-langserver: connections closed\n" 2024-07-15T14:46:45.102 helix_lsp::client [WARN] language server failed to terminate gracefully - server closed the stream 2024-07-15T14:46:45.104 helix_lsp::transport [ERROR] efm err: <- StreamClosed 2024-07-15T14:46:45.104 helix_lsp::transport [ERROR] efm err: <- IO(Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }) ```

Platform

Linux

Terminal Emulator

WezTerm

Installation Method

releases page

Helix Version

helix 24.7 (079f5442)

pascalkuthe commented 1 month ago

does this match what vscode does? You will have a hard time convincing servers to follow the spec if vscode doesn't follow it unfortunately so that is the the behaviour I would aim to emulate

kyoh86 commented 1 month ago

@pascalkuthe Thank you for your reply.

In the Neovim issue that triggered this modification, it is stated that it follows the VSCode implementation as follows. Therefore, it is assumed that VSCode also processes in the same order.

Also, in the vscode implementation, similar start position text edits aren't sorted in reverse order

I do not know how to apply formatting using VSCode and a language server, and have not been able to confirm how "changes across multiple consecutive lines" like efm-langserver are handled.

kyoh86 commented 3 weeks ago

It has fixed in Neovim, thanks.

pascalkuthe commented 3 weeks ago

This still appear in helix because we accidentally perform an unstable sort (instead of a stable sort).

Just need to replace this here