Skip to content

Completion replaces the word cursor is at instead of insertingΒ #21365

@suguruwataru

Description

@suguruwataru

rust-analyzer version: commit 11d6212

rustc version: rustc 1.92.0

editor or extension: I use NeoVim with vim-lsp but this should affect everything

relevant settings: None

repository link (if public, optional): None

code snippet to reproduce:

Code snippet is based on this test

fn completes_if_prefix_is_keyword() {

You can also reproduce using this test.

fn main() {
    let wherewolf = 92;
    drop(where$0sheep) // Note that compared to original test, `sheep` is added behind the cursor
}

After the text edit from the completion, it's expected that the code becomes

fn main() {
    let wherewolf = 92;
    drop(wherewolfsheep)
}

However, the actual behavior is that, the sheep gets eaten by the wolf:

fn main() {
    let wherewolf = 92;
    drop(wherewolf)
}

I thought this current behavior was the expected behavior, because it's the default behavior of Intellij IDEA (and has been hated by people for years), but looking at this comment makes me think this might be unintentional:

text_edit should start with what source_range points to

as in this case, source_range points to wheresheep, but text_edit is wherewolf.

I think the problem here is that, here

let mut item = CompletionItem::new(
kind,
ctx.source_range(),

the text to delete in this completion is decided to be ctx.source_range(), which is determined here

_ if kind.is_any_identifier() => self.original_token.text_range(),

to be the original_token's text_range(), and the original_token has been decided here

let original_token = original_file.syntax().token_at_offset(offset).left_biased()?;

to be wheresheep instead of where.

There's also a discussion about this: #21029, where an example that better illustrates why this behavior is annoying in practice is given.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lspLSP conformance issues and missing featuresC-bugCategory: bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions