vscode-go icon indicating copy to clipboard operation
vscode-go copied to clipboard

Don't replace next token on autocomplete

Open powellnorma opened this issue 1 year ago • 2 comments

Is your feature request related to a problem? Please describe.

Let's say the line currently is: someLongVariableName.Name()

When I now place the cursor before someLongVariableName, and type strings.HasP + [enter], the line becomes: strings.HasPrefix().Name()

I think it would be better if it would become one of: strings.HasPrefix(someLongVariableName.Name() (missing closing bracket) strings.HasPrefix(someLongVariableName.Name()) (with closing bracket) strings.HasPrefixsomeLongVariableName.Name() (cursor being in front of someLongVariableName)

Describe the solution you'd like

If this isn't a bug (it sort of feels like one, though), can we get a setting with which we can control this behavior?

Thank you!

powellnorma avatar Apr 25 '24 10:04 powellnorma

We agree that this is annoying, and doesn't happen in other LSP clients so may not be directly related to gopls. Needs more investigation.

Even if we're not smart enough to include the variable as an argument, we should not be deleting existing text.

findleyr avatar Apr 25 '24 19:04 findleyr

VSCode has this setting:

  "editor.suggest.insertMode": "insert"

However, it seems that each extension needs to opt into supporting it, and I assume vscode-go hasn't? Also, I don't believe I had this issue in the past, but my memory might be playing tricks on me here. There is a chance this is a regression?

I'd appreciate this being prioritized, or if not, some pointers to where in the codebase this may be happening. I can spend some time researching this and sending a PR.

aaomidi avatar Apr 30 '24 15:04 aaomidi

@findleyr Is this working in other editors? I thought about https://github.com/golang/go/issues/61215 but maybe it is something else?

Repro:

package main

import (
	"fmt"
	"strings"
	"os"
)

func main() {
	var someLongVariableName S
	fmt.Println(someLongVariableName.Name()) // "someLongVariableName" LSP position (10:13-10:33)
}

type S string

var _ = strings.Compare

func (s S) Name() string {
	return string(s)
}
...

hyangah avatar May 09 '24 21:05 hyangah

I think this needs golang/go#61215.

In this specific example, triggering completion after typing s after (

    fmt.Println(ssomeLongVariableName.Name())
                ^
                + trigger completion

gopls returns completion items, whose text edit ranges are always the whole ssomeLongVariableName token in this case, regardless whether the editor insert mode is insert or replace.

[Trace - 5: 11: 59 PM
] Sending request 'textDocument/completion - (453)'.
Params: {
    "textDocument": {
        "uri": "file:///Users/hakim/xx/main.go"
    },
    "position": {
        "line": 10,
        "character": 14
    },
    "context": {
        "triggerKind": 1
    }
}



[Trace - 5: 11: 59 PM
] Received response 'textDocument/completion - (453)' in 11ms.
Result: {
    "isIncomplete": true,
    "items": [
         ...
        {
            "label": "strings",
            "kind": 9,
            "detail": "\"strings\"",
            "documentation": {
                "kind": "markdown",
                "value": ""
            },
            "sortText": "00001",
            "filterText": "strings",
            "insertTextFormat": 2,
            "textEdit": {
                "range": {
                    "start": {
                        "line": 10,
                        "character": 13 <---- begining of `ssomeLongVariableName`.
                    },
                    "end": {
                        "line": 10,
                        "character": 34   <------  end of `ssomeLongVariableName`.
                    }
                },
                "newText": "strings"
            },
 
            ...
        },

This old style TextEdit is translated to a VS Code CompletionItem with a single Range. https://code.visualstudio.com/api/references/vscode-api#CompletionItem.range I guess, if the range is not omitted, VS Code respects what the provided range. Since gopls always gives the word boundary, VS Code ends up replacing the entire word boundary.

hyangah avatar May 10 '24 23:05 hyangah

Change https://go.dev/cl/585275 mentions this issue: gopls/internal/server: support InsertReplaceEdit completion

gopherbot avatar May 13 '24 22:05 gopherbot

Any progress on this issue?

thedemons avatar May 15 '24 19:05 thedemons