rust-lang / rust-lang/rust-analyzer

Code actions use lots of text edits for small changes

Open
#11,316 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-ide C-support E-unknown
Dominant language
Rust
Stars
16.9k
Forks
2.2k
Avg merge
1d 12h
Merged PRs (30d)
72

Description

Example reproducer:

  1. Clone https://github.com/kak-lsp/kak-lsp (I'm using 1ffcd26021fb2f5818353254e9e15042852bbedb)
  2. Open src/main.rs in your editor
  3. Goto line 46, the one with use std::path::Path;
  4. Hover over std::path::Path and run the code action "Merge Imports".

To apply "Merge Imports", rust-analyzer sends a sequence of 274 text edits, some extending to unrelated lines like 315.
This feels a bit weird because their sum is just this:

diff --git a/src/main.rs b/src/main.rs
index 11b623c..53ac623 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -45,4 +45,3 @@ use std::os::unix::net::UnixStream;
 use std::panic;
-use std::path::Path;
-use std::process::{Command, Stdio};
+use std::{path::Path, process::{Command, Stdio}};
 

perhaps we can make this more minimal?

Of course this difference is not user-visible in most clients.
However, the LSP client kak-lsp leaks this noise to the user in some scenarios:
it applies each text edit directly inside the Kakoune editor (kind of as if the user had made the edit).
Now when the user undoes the code action, Kakoune will use a heuristic to select the ranges that were touched by the text edits. In this case it selects much more than just the two affected lines, which is unfortunate.

I guess various clients have their own ways of squashing sequences of text edits.
Undo works properly in VSCode, but it's probably based on a diff of the old/new buffer contents.
Computing this diff seems unnecessary if we already have the text edits; we should just make them simpler.

(FWIW kak-lsp currently has a bug on the reproducer: it modifies unrelated lines, probably because it doesn't interpret text edits correctly)

rust-analyzer version: rust-analyzer 2022-01-17

rustc version: rustc 1.56.1 (59eed8a2a 2021-11-01

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the "Merge Imports" action in kak-lsp using src/main.rs and the pinned rust-analyzer version described in the issue. Start by tracing how this action produces its sequence of text edits; done means the same import merge is represented by minimal edits limited to the affected lines, without changing unrelated ranges.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.