Skip to content

x/tools/internal/lsp: support files outside $GOPATH and outside of a module #31168

Closed
@Lekensteyn

Description

@Lekensteyn

What version of Go are you using (go version)?

$ go version
go version go1.12.1 linux/amd64

Originally encountered with 1.12. Reproduced on Arch Linux (x86_64).

What did you do?

Install vim-go (fatih/vim-go@17d4c08) for use with vim (8.1.1073-1). This will use gopls by default for autocompletion.

Create a file outside $GOPATH, e.g. /tmp/foo.vim with this sample content:

package main

import "fmt"

func main() {
	fmt.Println("vim-go")
	fmt.
}

After fmt., press Ctrl-X, Ctrl-O to trigger auto completion.

Alternatively, try this reproducer which does not require vim:

repro.py
#!/usr/bin/env python3
import json
import os
import subprocess
import sys

uri = os.path.expanduser('~/go/src/github.com/google/fscrypt/cmd/fscrypt/foo.go')
# does not work
uri = '/tmp/foo.go'
if len(sys.argv) >= 2:
    uri = sys.argv[1]

# rootUri value does not seem to matter
rootUri = "file:///"
uri = "file://%s" % uri

cmd_a = {
  "method": "initialize",
  "jsonrpc": "2.0",
  "id": 1,
  "params": {
    "rootUri": rootUri,
    "capabilities": {
      "workspace": {},
      "textDocument": {}
    },
    "processId": 13448
  }
}

cmd_b = {
  "method": "textDocument/didChange",
  "jsonrpc": "2.0",
  "params": {
    "contentChanges": [
      {
        "text": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.Println(\"vim-go\")\n\tfmt.\n}\n"
      }
    ],
    "textDocument": {
      "uri": uri
    }
  }
}

cmd_c = {
  "method": "textDocument/completion",
  "jsonrpc": "2.0",
  "id": 2,
  "params": {
    "textDocument": {
      "uri": uri
    },
    "position": {
      "character": 5,
      "line": 6
    }
  }
}

def send_receive(proc, cmd, receive=False):
    print('\n# Sending: %r\n' % cmd)
    s = json.dumps(cmd)
    proc.stdin.write('Content-Length: %d\r\n\r\n%s' % (len(s), s))
    proc.stdin.flush()
    # Read response
    if receive:
        size = int(proc.stdout.readline().split('Content-Length: ')[1])
        print('\n# Response (%d bytes)' % size)
        while proc.stdout.readline().strip():
            pass
        print(json.dumps(json.loads(proc.stdout.read(size)), indent=4))

with subprocess.Popen(os.path.expanduser('~/go/bin/gopls'),
        stdin=subprocess.PIPE, stdout=subprocess.PIPE, encoding='utf8') as p:
    send_receive(p, cmd_a, receive=True)
    send_receive(p, cmd_b)
    send_receive(p, cmd_c, receive=True)
    p.terminate()
    print('')

Run python3 repro.py which will send some commands to gopls and print the responses.

What did you expect to see?

Expected to see completion:
vim-go

With the Python reproducer, I would expect something like:

[Trace - 12:52:45 AM] Received response 'textDocument/completion - (2)' in 1010ms.
Params: {"isIncomplete":false,"items":[{"label":"Errorf(format string, a ...interface{})", ...

What did you see instead?

No autocompletion.

With the Python reproducer, I see:

[Trace - 12:57:34 AM] Sending request 'textDocument/completion - (2)'.
Params: {"textDocument": {"uri": "file:///tmp/foo.go"}, "position": {"character": 5, "line": 6}}

[Error - 12:57:34 AM] send textDocument/completion#2 no file information for file:///tmp/foo.go

Additional information

I posted an analysis at fatih/vim-go#2193 (comment), the following patch would permit gopls to be used with individual files, e.g. for use with go run script.go. When used with projects with multiple files, there may be issues like missing identifiers (unless the client loads all files) or duplicate identifiers when multiple packages are combined.

Regardless of those issues, it does address the single script use case though.

[Patch redacted by @bcmills. Please send a PR or CL so that we can verify CLA compliance.]

Other similar issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    FeatureRequestIssues asking for a new feature that does not need a proposal.FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.goplsIssues related to the Go language server, gopls.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions