Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/gopls: snippets do not replace triggering preamble #59508

Closed
kortschak opened this issue Apr 8, 2023 · 9 comments
Closed

x/tools/gopls: snippets do not replace triggering preamble #59508

kortschak opened this issue Apr 8, 2023 · 9 comments
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@kortschak
Copy link
Contributor

kortschak commented Apr 8, 2023

gopls version

Build info
----------
golang.org/x/tools/gopls v0.11.0
    golang.org/x/tools/gopls@v0.11.0 h1:/nvKHdTtePQmrv9XN3gIUN9MOdUrKzO/dcqgbG6x8EY=
    github.com/BurntSushi/toml@v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
    github.com/google/go-cmp@v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
    github.com/sergi/go-diff@v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
    golang.org/x/exp@v0.0.0-20221031165847-c99f073a8326 h1:QfTh0HpN6hlw6D3vu8DAwC8pBIwikq0AI1evdm+FksE=
    golang.org/x/exp/typeparams@v0.0.0-20221031165847-c99f073a8326 h1:fl8k2zg28yA23264d82M4dp+YlJ3ngDcpuB1bewkQi4=
    golang.org/x/mod@v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
    golang.org/x/sync@v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
    golang.org/x/sys@v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
    golang.org/x/text@v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
    golang.org/x/tools@v0.3.1-0.20221213193459-ca17b2c27ca8 h1:7/HkGkN/2ktghBCSRRgp31wAww4syfsW52tj7yirjWk=
    golang.org/x/vuln@v0.0.0-20221109205719-3af8368ee4fe h1:qptQiQwEpETwDiz85LKtChqif9xhVkAm8Nhxs0xnTww=
    honnef.co/go/tools@v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA=
    mvdan.cc/gofumpt@v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM=
    mvdan.cc/xurls/v2@v2.4.0 h1:tzxjVAj+wSBmDcF6zBB7/myTy3gX9xvi8Tyr28AuQgc=
go: go1.20.3

go env

GO111MODULE="on"
GOARCH="amd64"
GOBIN="/home/user/bin"
GOCACHE="/home/user/.cache/go-build"
GOENV="/home/user/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/user/pkg/mod"
GONOPROXY="git.sr.ht"
GONOSUMDB="git.sr.ht"
GOOS="linux"
GOPATH="/home/user"
GOPRIVATE="git.sr.ht"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/user/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/user/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.20.3"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build590652870=/tmp/go-build -gno-record-gcc-switches"

What did you do?

In a test file, start a snippet suggestion with "func Te" and accept the completion "TestXxx(t *testing.T)" and you'll end up with

func TeTestXxx(t *testing.T) {

}

What did you expect to see?

func TestXxx(t *testing.T) {

}

What did you see instead?

func TeTestXxx(t *testing.T) {

}

Editor and settings

Sublime Text

{
	"lsp_format_on_save": true,
    "lsp_code_actions_on_save": {
        "source.fixAll": true,
        "source.organizeImports": true
    },

	"clients":
	{
		"gopls":
		{
			"enabled": true,
			"initializationOptions": {
				"staticcheck": true,
				"analyses": {
					"ST1003": false,
					"ST1016": false,
				},
				"gofumpt": false,
			},
		},
	},
}

Client: https://github.com/sublimelsp/LSP

Logs

@gopherbot gopherbot added Tools This label describes issues relating to any tools in the x/tools repository. gopls Issues related to the Go language server, gopls. labels Apr 8, 2023
@gopherbot gopherbot added this to the Unreleased milestone Apr 8, 2023
@hyangah
Copy link
Contributor

hyangah commented Apr 12, 2023

Unfortunately I cannot reproduce the issue with VS Code.
I don't have sublime set up.
@kortschak and others who experience this issue, do you mind sharing the gopls trace?
Looks like https://lsp.sublimetext.io/troubleshooting/#self-help-instructions is the instruction for capturing lsp debug log in sublimelsp.

@hyangah hyangah added WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Apr 12, 2023
@kortschak
Copy link
Contributor Author

@hyangah Here you go. The conversation looks sane, so it may well be that the Sublime LSP client is doing something wrong.

:: --> gopls initialize(1): {'clientInfo': {'version': '1.2.10', 'name': 'Sublime Text LSP'}, 'initializationOptions': {'staticcheck': True, 'analyses': {'ST1003': False, 'ST1016': False}, 'gofumpt': False}, 'capabilities': {'experimental': {}, 'workspace': {'didChangeConfiguration': {'dynamicRegistration': True}, 'workspaceEdit': {'failureHandling': 'abort', 'documentChanges': True}, 'applyEdit': True, 'executeCommand': {}, 'configuration': True, 'symbol': {'dynamicRegistration': True, 'symbolKind': {'valueSet': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]}, 'tagSupport': {'valueSet': [1]}}, 'workspaceFolders': True}, 'textDocument': {'definition': {'dynamicRegistration': True, 'linkSupport': True}, 'selectionRange': {'dynamicRegistration': True}, 'codeAction': {'dynamicRegistration': True, 'dataSupport': True, 'resolveSupport': {'properties': ['edit']}, 'codeActionLiteralSupport': {'codeActionKind': {'valueSet': ['quickfix', 'refactor', 'refactor.extract', 'refactor.inline', 'refactor.rewrite', 'source.organizeImports']}}}, 'synchronization': {'dynamicRegistration': True, 'didSave': True, 'willSaveWaitUntil': True, 'willSave': True}, 'typeDefinition': {'dynamicRegistration': True, 'linkSupport': True}, 'formatting': {'dynamicRegistration': True}, 'hover': {'dynamicRegistration': True, 'contentFormat': ['markdown', 'plaintext']}, 'codeLens': {'dynamicRegistration': True}, 'implementation': {'dynamicRegistration': True, 'linkSupport': True}, 'signatureHelp': {'dynamicRegistration': True, 'signatureInformation': {'parameterInformation': {'labelOffsetSupport': True}, 'documentationFormat': ['markdown', 'plaintext']}}, 'declaration': {'dynamicRegistration': True, 'linkSupport': True}, 'publishDiagnostics': {'dataSupport': True, 'relatedInformation': True, 'versionSupport': True, 'codeDescriptionSupport': True}, 'colorProvider': {'dynamicRegistration': True}, 'references': {'dynamicRegistration': True}, 'rename': {'dynamicRegistration': True, 'prepareSupport': True}, 'documentSymbol': {'dynamicRegistration': True, 'symbolKind': {'valueSet': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]}, 'tagSupport': {'valueSet': [1]}, 'hierarchicalDocumentSymbolSupport': True}, 'completion': {'dynamicRegistration': True, 'completionItemKind': {'valueSet': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]}, 'completionItem': {'deprecatedSupport': True, 'snippetSupport': True, 'documentationFormat': ['markdown', 'plaintext'], 'tagSupport': {'valueSet': [1]}}}, 'rangeFormatting': {'dynamicRegistration': True}, 'documentHighlight': {'dynamicRegistration': True}}, 'general': {'regularExpressions': {'engine': 'ECMAScript'}}, 'window': {'workDoneProgress': True, 'showMessage': {'messageActionItem': {'additionalPropertiesSupport': True}}, 'showDocument': {'support': True}}}, 'rootPath': '/home/user/lsp_issue', 'rootUri': 'file:///home/user/lsp_issue', 'processId': 4945, 'workspaceFolders': [{'uri': 'file:///home/user/lsp_issue', 'name': 'lsp'}]}
:: <<< gopls 1: {'serverInfo': {'version': '{"GoVersion":"go1.20.3","Path":"golang.org/x/tools/gopls","Main":{"Path":"golang.org/x/tools/gopls","Version":"v0.11.0","Sum":"h1:/nvKHdTtePQmrv9XN3gIUN9MOdUrKzO/dcqgbG6x8EY=","Replace":null},"Deps":[{"Path":"github.com/BurntSushi/toml","Version":"v1.2.1","Sum":"h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=","Replace":null},{"Path":"github.com/google/go-cmp","Version":"v0.5.9","Sum":"h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=","Replace":null},{"Path":"github.com/sergi/go-diff","Version":"v1.1.0","Sum":"h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=","Replace":null},{"Path":"golang.org/x/exp","Version":"v0.0.0-20221031165847-c99f073a8326","Sum":"h1:QfTh0HpN6hlw6D3vu8DAwC8pBIwikq0AI1evdm+FksE=","Replace":null},{"Path":"golang.org/x/exp/typeparams","Version":"v0.0.0-20221031165847-c99f073a8326","Sum":"h1:fl8k2zg28yA23264d82M4dp+YlJ3ngDcpuB1bewkQi4=","Replace":null},{"Path":"golang.org/x/mod","Version":"v0.7.0","Sum":"h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=","Replace":null},{"Path":"golang.org/x/sync","Version":"v0.1.0","Sum":"h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=","Replace":null},{"Path":"golang.org/x/sys","Version":"v0.2.0","Sum":"h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=","Replace":null},{"Path":"golang.org/x/text","Version":"v0.4.0","Sum":"h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=","Replace":null},{"Path":"golang.org/x/tools","Version":"v0.3.1-0.20221213193459-ca17b2c27ca8","Sum":"h1:7/HkGkN/2ktghBCSRRgp31wAww4syfsW52tj7yirjWk=","Replace":null},{"Path":"golang.org/x/vuln","Version":"v0.0.0-20221109205719-3af8368ee4fe","Sum":"h1:qptQiQwEpETwDiz85LKtChqif9xhVkAm8Nhxs0xnTww=","Replace":null},{"Path":"honnef.co/go/tools","Version":"v0.3.3","Sum":"h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA=","Replace":null},{"Path":"mvdan.cc/gofumpt","Version":"v0.4.0","Sum":"h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM=","Replace":null},{"Path":"mvdan.cc/xurls/v2","Version":"v2.4.0","Sum":"h1:tzxjVAj+wSBmDcF6zBB7/myTy3gX9xvi8Tyr28AuQgc=","Replace":null}],"Settings":[{"Key":"-buildmode","Value":"exe"},{"Key":"-compiler","Value":"gc"},{"Key":"CGO_ENABLED","Value":"1"},{"Key":"CGO_CFLAGS","Value":""},{"Key":"CGO_CPPFLAGS","Value":""},{"Key":"CGO_CXXFLAGS","Value":""},{"Key":"CGO_LDFLAGS","Value":""},{"Key":"GOARCH","Value":"amd64"},{"Key":"GOOS","Value":"linux"},{"Key":"GOAMD64","Value":"v1"}],"Version":"v0.11.0"}', 'name': 'gopls'}, 'capabilities': {'foldingRangeProvider': True, 'referencesProvider': True, 'inlayHintProvider': {}, 'workspaceSymbolProvider': True, 'codeActionProvider': {'codeActionKinds': ['quickfix', 'refactor.extract', 'refactor.rewrite', 'source.fixAll', 'source.organizeImports']}, 'implementationProvider': True, 'typeDefinitionProvider': True, 'completionProvider': {'triggerCharacters': ['.']}, 'callHierarchyProvider': True, 'hoverProvider': True, 'executeCommandProvider': {'commands': ['gopls.add_dependency', 'gopls.add_import', 'gopls.apply_fix', 'gopls.check_upgrades', 'gopls.edit_go_directive', 'gopls.fetch_vulncheck_result', 'gopls.gc_details', 'gopls.generate', 'gopls.generate_gopls_mod', 'gopls.go_get_package', 'gopls.list_imports', 'gopls.list_known_packages', 'gopls.regenerate_cgo', 'gopls.remove_dependency', 'gopls.reset_go_mod_diagnostics', 'gopls.run_govulncheck', 'gopls.run_tests', 'gopls.start_debugging', 'gopls.test', 'gopls.tidy', 'gopls.toggle_gc_details', 'gopls.update_go_sum', 'gopls.upgrade_dependency', 'gopls.vendor']}, 'documentSymbolProvider': True, 'signatureHelpProvider': {'triggerCharacters': ['(', ',']}, 'documentHighlightProvider': True, 'documentFormattingProvider': True, 'textDocumentSync': {'change': {'syncKind': 2}, 'didClose': {}, 'save': {}, 'didOpen': {}}, 'workspace': {'fileOperations': {}, 'workspaceFolders': {'changeNotifications': 'workspace/didChangeWorkspaceFolders', 'supported': True}}, 'codeLensProvider': {}, 'definitionProvider': True, 'documentLinkProvider': {}, 'renameProvider': {'prepareProvider': True}}}
::  -> gopls initialized: {}
::  -> gopls textDocument/didOpen: {'textDocument': {'version': 0, 'text': 'package main\n', 'uri': 'file:///home/user/lsp_issue/main_test.go', 'languageId': 'go'}}
:: <-- gopls window/workDoneProgress/create(1): {'token': '9043637350207253310'}
:: >>> gopls 1: None
:: <-  gopls $/progress: {'token': '9043637350207253310', 'value': {'message': 'Loading packages...', 'title': 'Setting up workspace', 'kind': 'begin'}}
:: <-- gopls workspace/configuration(2): {'items': [{'scopeUri': 'file:///home/user/lsp_issue', 'section': 'gopls'}]}
:: >>> gopls 2: [None]
gopls: 2023/04/12 13:02:35 go env for /home/user/lsp_issue
(root /home/user/lsp_issue)
(go version go version go1.20.3 linux/amd64)
(valid build configuration = true)
(build flags: [])
GO111MODULE=on
GOCACHE=/home/user/.cache/go-build
GOINSECURE=
GOPATH=/home/user
GONOSUMDB=git.sr.ht
GOMOD=/home/user/lsp_issue/go.mod
GOMODCACHE=/home/user/pkg/mod
GOFLAGS=
GOPROXY=https://proxy.golang.org,direct
GOROOT=/home/user/go
GOWORK=
GOSUMDB=sum.golang.org
GOPRIVATE=git.sr.ht
GONOPROXY=git.sr.ht


:: <-  gopls window/logMessage: {'message': '2023/04/12 13:02:35 go env for /home/user/lsp_issue\n(root /home/user/lsp_issue)\n(go version go version go1.20.3 linux/amd64)\n(valid build configuration = true)\n(build flags: [])\nGO111MODULE=on\nGOCACHE=/home/user/.cache/go-build\nGOINSECURE=\nGOPATH=/home/user\nGONOSUMDB=git.sr.ht\nGOMOD=/home/user/lsp_issue/go.mod\nGOMODCACHE=/home/user/pkg/mod\nGOFLAGS=\nGOPROXY=https://proxy.golang.org,direct\nGOROOT=/home/user/go\nGOWORK=\nGOSUMDB=sum.golang.org\nGOPRIVATE=git.sr.ht\nGONOPROXY=git.sr.ht\n\n', 'type': 3}
gopls: 2023/04/12 13:02:35 go/packages.Load #1
	snapshot=0
	directory=file:///home/user/lsp_issue
	query=[builtin lsp/...]
	packages=4

gopls: 2023/04/12 13:02:35 go/packages.Load #1: updating metadata for 2 packages

:: <-  gopls window/logMessage: {'message': '2023/04/12 13:02:35 go/packages.Load #1\n\tsnapshot=0\n\tdirectory=file:///home/user/lsp_issue\n\tquery=[builtin lsp/...]\n\tpackages=4\n', 'type': 3}
:: <-  gopls window/logMessage: {'message': '2023/04/12 13:02:35 go/packages.Load #1: updating metadata for 2 packages\n', 'type': 3}
:: <-  gopls $/progress: {'token': '9043637350207253310', 'value': {'message': 'Finished loading packages.', 'kind': 'end'}}
:: <-- gopls client/registerCapability(3): {'registrations': [{'id': 'workspace/didChangeConfiguration', 'method': 'workspace/didChangeConfiguration'}]}
:: >>> gopls 3: None
:: <-  gopls textDocument/publishDiagnostics: {'diagnostics': [], 'uri': 'file:///home/user/lsp_issue/main_test.go'}
::  -> gopls textDocument/didChange: {'contentChanges': [{'text': '\n', 'range': {'end': {'character': 0, 'line': 1}, 'start': {'character': 0, 'line': 1}}, 'rangeLength': 0}], 'textDocument': {'version': 1, 'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: --> gopls textDocument/documentHighlight(2): {'position': {'character': 0, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <<< gopls 2: []
:: <-  gopls textDocument/publishDiagnostics: {'version': 1, 'diagnostics': [], 'uri': 'file:///home/user/lsp_issue/main_test.go'}
::  -> gopls textDocument/didChange: {'contentChanges': [{'text': 'f', 'range': {'end': {'character': 0, 'line': 2}, 'start': {'character': 0, 'line': 2}}, 'rangeLength': 0}], 'textDocument': {'version': 2, 'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: --> gopls textDocument/completion(3): {'position': {'character': 1, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <-  gopls textDocument/publishDiagnostics: {'version': 2, 'diagnostics': [{'source': 'syntax', 'severity': 1, 'range': {'end': {'character': 0, 'line': 2}, 'start': {'character': 0, 'line': 2}}, 'message': 'expected declaration, found f'}], 'uri': 'file:///home/user/lsp_issue/main_test.go'}
:: --> gopls textDocument/codeAction(4): {'context': {'diagnostics': []}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}, 'range': {'end': {'character': 1, 'line': 2}, 'start': {'character': 1, 'line': 2}}}
:: <<< gopls 3: {'items': [{'textEdit': {'newText': 'func', 'range': {'end': {'character': 1, 'line': 2}, 'start': {'character': 0, 'line': 2}}}, 'sortText': '00000', 'preselect': True, 'filterText': 'func', 'label': 'func', 'insertTextFormat': 2, 'kind': 14}], 'isIncomplete': True}
gopls: 2023/04/12 13:02:44 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:1: expected declaration, found f
	file="/home/user/lsp_issue/main_test.go"

:: <-  gopls window/logMessage: {'message': '2023/04/12 13:02:44 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:1: expected declaration, found f\n\tfile="/home/user/lsp_issue/main_test.go"\n', 'type': 1}
:: <<< gopls 4: None
::  -> gopls textDocument/didChange: {'contentChanges': [{'text': 'u', 'range': {'end': {'character': 1, 'line': 2}, 'start': {'character': 1, 'line': 2}}, 'rangeLength': 0}], 'textDocument': {'version': 3, 'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: --> gopls textDocument/completion(5): {'position': {'character': 2, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <<< gopls 5: {'items': [{'textEdit': {'newText': 'func', 'range': {'end': {'character': 2, 'line': 2}, 'start': {'character': 0, 'line': 2}}}, 'sortText': '00000', 'preselect': True, 'filterText': 'func', 'label': 'func', 'insertTextFormat': 2, 'kind': 14}], 'isIncomplete': True}
:: <-  gopls textDocument/publishDiagnostics: {'version': 3, 'diagnostics': [{'source': 'syntax', 'severity': 1, 'range': {'end': {'character': 0, 'line': 2}, 'start': {'character': 0, 'line': 2}}, 'message': 'expected declaration, found fu'}], 'uri': 'file:///home/user/lsp_issue/main_test.go'}
:: --> gopls textDocument/codeAction(6): {'context': {'diagnostics': []}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}, 'range': {'end': {'character': 2, 'line': 2}, 'start': {'character': 2, 'line': 2}}}
gopls: 2023/04/12 13:02:44 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:1: expected declaration, found fu
	file="/home/user/lsp_issue/main_test.go"

:: <-  gopls window/logMessage: {'message': '2023/04/12 13:02:44 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:1: expected declaration, found fu\n\tfile="/home/user/lsp_issue/main_test.go"\n', 'type': 1}
:: <<< gopls 6: None
::  -> gopls textDocument/didChange: {'contentChanges': [{'text': 'n', 'range': {'end': {'character': 2, 'line': 2}, 'start': {'character': 2, 'line': 2}}, 'rangeLength': 0}], 'textDocument': {'version': 4, 'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: --> gopls textDocument/completion(7): {'position': {'character': 3, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <<< gopls 7: {'items': [{'textEdit': {'newText': 'func', 'range': {'end': {'character': 3, 'line': 2}, 'start': {'character': 0, 'line': 2}}}, 'sortText': '00000', 'preselect': True, 'filterText': 'func', 'label': 'func', 'insertTextFormat': 2, 'kind': 14}], 'isIncomplete': True}
:: <-  gopls textDocument/publishDiagnostics: {'version': 4, 'diagnostics': [{'source': 'syntax', 'severity': 1, 'range': {'end': {'character': 0, 'line': 2}, 'start': {'character': 0, 'line': 2}}, 'message': 'expected declaration, found fun'}], 'uri': 'file:///home/user/lsp_issue/main_test.go'}
:: --> gopls textDocument/codeAction(8): {'context': {'diagnostics': []}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}, 'range': {'end': {'character': 3, 'line': 2}, 'start': {'character': 3, 'line': 2}}}
gopls: 2023/04/12 13:02:44 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:1: expected declaration, found fun
	file="/home/user/lsp_issue/main_test.go"

:: <-  gopls window/logMessage: {'message': '2023/04/12 13:02:44 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:1: expected declaration, found fun\n\tfile="/home/user/lsp_issue/main_test.go"\n', 'type': 1}
:: <<< gopls 8: None
:: --> gopls textDocument/documentHighlight(9): {'position': {'character': 3, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <<< gopls 9: []
::  -> gopls textDocument/didChange: {'contentChanges': [{'text': 'c', 'range': {'end': {'character': 3, 'line': 2}, 'start': {'character': 3, 'line': 2}}, 'rangeLength': 0}], 'textDocument': {'version': 5, 'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: --> gopls textDocument/completion(10): {'position': {'character': 4, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <-  gopls textDocument/publishDiagnostics: {'version': 5, 'diagnostics': [{'source': 'syntax', 'severity': 1, 'range': {'end': {'character': 0, 'line': 3}, 'start': {'character': 0, 'line': 3}}, 'message': "expected '(', found 'EOF'"}], 'uri': 'file:///home/user/lsp_issue/main_test.go'}
:: --> gopls textDocument/codeAction(11): {'context': {'diagnostics': [{'source': 'syntax', 'severity': 1, 'range': {'end': {'character': 0, 'line': 3}, 'start': {'character': 0, 'line': 3}}, 'message': "expected '(', found 'EOF'"}]}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}, 'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 4, 'line': 2}}}
:: <<< gopls 10: {'items': [{'textEdit': {'newText': 'func', 'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 0, 'line': 2}}}, 'sortText': '00000', 'preselect': True, 'filterText': 'func', 'label': 'func', 'insertTextFormat': 2, 'kind': 14}, {'detail': '"github.com/go-logr/logr/funcr"', 'textEdit': {'newText': 'funcr', 'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 0, 'line': 2}}}, 'sortText': '00001', 'additionalTextEdits': [{'newText': '\nimport "github.com/go-logr/logr/funcr"\n', 'range': {'end': {'character': 0, 'line': 1}, 'start': {'character': 0, 'line': 1}}}], 'filterText': 'funcr', 'label': 'funcr', 'insertTextFormat': 2, 'kind': 9}, {'detail': '"github.com/zclconf/go-cty/cty/function"', 'textEdit': {'newText': 'function', 'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 0, 'line': 2}}}, 'sortText': '00002', 'additionalTextEdits': [{'newText': '\nimport "github.com/zclconf/go-cty/cty/function"\n', 'range': {'end': {'character': 0, 'line': 1}, 'start': {'character': 0, 'line': 1}}}], 'filterText': 'function', 'label': 'function', 'insertTextFormat': 2, 'kind': 9}, {'detail': '"github.com/dolthub/go-mysql-server/sql/expression/function"', 'textEdit': {'newText': 'function', 'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 0, 'line': 2}}}, 'sortText': '00003', 'additionalTextEdits': [{'newText': '\nimport "github.com/dolthub/go-mysql-server/sql/expression/function"\n', 'range': {'end': {'character': 0, 'line': 1}, 'start': {'character': 0, 'line': 1}}}], 'filterText': 'function', 'label': 'function', 'insertTextFormat': 2, 'kind': 9}, {'detail': '"github.com/Microsoft/hcsshim/test/functional"', 'textEdit': {'newText': 'functional', 'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 0, 'line': 2}}}, 'sortText': '00004', 'additionalTextEdits': [{'newText': '\nimport "github.com/Microsoft/hcsshim/test/functional"\n', 'range': {'end': {'character': 0, 'line': 1}, 'start': {'character': 0, 'line': 1}}}], 'filterText': 'functional', 'label': 'functional', 'insertTextFormat': 2, 'kind': 9}], 'isIncomplete': True}
gopls: 2023/04/12 13:02:45 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:5: expected '(', found 'EOF' (and 3 more errors)
	file="/home/user/lsp_issue/main_test.go"

:: <-  gopls window/logMessage: {'message': '2023/04/12 13:02:45 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:5: expected \'(\', found \'EOF\' (and 3 more errors)\n\tfile="/home/user/lsp_issue/main_test.go"\n', 'type': 1}
:: <<< gopls 11: None
:: --> gopls textDocument/documentHighlight(12): {'position': {'character': 4, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <<< gopls 12: [{'range': {'end': {'character': 0, 'line': 3}, 'start': {'character': 0, 'line': 2}}, 'kind': 1}]
::  -> gopls textDocument/didChange: {'contentChanges': [{'text': ' ', 'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 4, 'line': 2}}, 'rangeLength': 0}], 'textDocument': {'version': 6, 'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: --> gopls textDocument/completion(13): {'position': {'character': 5, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <<< gopls 13: <params with 10059 characters>
:: --> gopls textDocument/documentHighlight(14): {'position': {'character': 5, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <<< gopls 14: [{'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 0, 'line': 2}}, 'kind': 1}]
:: <-  gopls textDocument/publishDiagnostics: {'version': 6, 'diagnostics': [{'source': 'syntax', 'severity': 1, 'range': {'end': {'character': 0, 'line': 3}, 'start': {'character': 0, 'line': 3}}, 'message': "expected '(', found 'EOF'"}], 'uri': 'file:///home/user/lsp_issue/main_test.go'}
:: --> gopls textDocument/codeAction(15): {'context': {'diagnostics': [{'source': 'syntax', 'severity': 1, 'range': {'end': {'character': 0, 'line': 3}, 'start': {'character': 0, 'line': 3}}, 'message': "expected '(', found 'EOF'"}]}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}, 'range': {'end': {'character': 5, 'line': 2}, 'start': {'character': 5, 'line': 2}}}
gopls: 2023/04/12 13:02:46 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:6: expected '(', found 'EOF' (and 3 more errors)
	file="/home/user/lsp_issue/main_test.go"

:: <-  gopls window/logMessage: {'message': '2023/04/12 13:02:46 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:6: expected \'(\', found \'EOF\' (and 3 more errors)\n\tfile="/home/user/lsp_issue/main_test.go"\n', 'type': 1}
:: <<< gopls 15: None
::  -> gopls textDocument/didChange: {'contentChanges': [{'text': 'T', 'range': {'end': {'character': 5, 'line': 2}, 'start': {'character': 5, 'line': 2}}, 'rangeLength': 0}], 'textDocument': {'version': 7, 'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: --> gopls textDocument/completion(16): {'position': {'character': 6, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <-  gopls textDocument/publishDiagnostics: {'version': 7, 'diagnostics': [{'source': 'syntax', 'severity': 1, 'range': {'end': {'character': 0, 'line': 3}, 'start': {'character': 0, 'line': 3}}, 'message': "expected '(', found newline"}], 'uri': 'file:///home/user/lsp_issue/main_test.go'}
:: --> gopls textDocument/codeAction(17): {'context': {'diagnostics': [{'source': 'syntax', 'severity': 1, 'range': {'end': {'character': 0, 'line': 3}, 'start': {'character': 0, 'line': 3}}, 'message': "expected '(', found newline"}]}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}, 'range': {'end': {'character': 6, 'line': 2}, 'start': {'character': 6, 'line': 2}}}
:: <<< gopls 16: {'items': [{'detail': 'tab, type the rest of the name, then tab', 'textEdit': {'newText': 'Test${1:Xxx}(t *testing.T) {\n$0\n\\}', 'range': {'end': {'character': 5, 'line': 2}, 'start': {'character': 5, 'line': 2}}}, 'label': 'TestXxx(t *testing.T)', 'preselect': True, 'documentation': 'Test test function', 'sortText': '00000', 'insertTextFormat': 2, 'kind': 3}, {'textEdit': {'newText': 'TestMain(m *testing.M)', 'range': {'end': {'character': 5, 'line': 2}, 'start': {'character': 5, 'line': 2}}}, 'filterText': 'TestMain(m *testing.M)', 'sortText': '00001', 'documentation': 'complete the parameter', 'label': 'TestMain(m *testing.M)', 'insertTextFormat': 2, 'kind': 3}], 'isIncomplete': True}
gopls: 2023/04/12 13:02:47 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:7: expected '(', found newline (and 2 more errors)
	file="/home/user/lsp_issue/main_test.go"

:: <-  gopls window/logMessage: {'message': '2023/04/12 13:02:47 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:7: expected \'(\', found newline (and 2 more errors)\n\tfile="/home/user/lsp_issue/main_test.go"\n', 'type': 1}
:: <<< gopls 17: None
:: --> gopls textDocument/documentHighlight(18): {'position': {'character': 6, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <<< gopls 18: [{'range': {'end': {'character': 0, 'line': 3}, 'start': {'character': 5, 'line': 2}}, 'kind': 1}]
::  -> gopls textDocument/didChange: {'contentChanges': [{'text': 'e', 'range': {'end': {'character': 6, 'line': 2}, 'start': {'character': 6, 'line': 2}}, 'rangeLength': 0}], 'textDocument': {'version': 8, 'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: --> gopls textDocument/completion(19): {'position': {'character': 7, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <<< gopls 19: {'items': [{'detail': 'tab, type the rest of the name, then tab', 'textEdit': {'newText': 'Test${1:Xxx}(t *testing.T) {\n$0\n\\}', 'range': {'end': {'character': 5, 'line': 2}, 'start': {'character': 5, 'line': 2}}}, 'label': 'TestXxx(t *testing.T)', 'preselect': True, 'documentation': 'Test test function', 'sortText': '00000', 'insertTextFormat': 2, 'kind': 3}, {'textEdit': {'newText': 'TestMain(m *testing.M)', 'range': {'end': {'character': 5, 'line': 2}, 'start': {'character': 5, 'line': 2}}}, 'filterText': 'TestMain(m *testing.M)', 'sortText': '00001', 'documentation': 'complete the parameter', 'label': 'TestMain(m *testing.M)', 'insertTextFormat': 2, 'kind': 3}], 'isIncomplete': True}
:: <-  gopls textDocument/publishDiagnostics: {'version': 8, 'diagnostics': [{'source': 'syntax', 'severity': 1, 'range': {'end': {'character': 0, 'line': 3}, 'start': {'character': 0, 'line': 3}}, 'message': "expected '(', found newline"}], 'uri': 'file:///home/user/lsp_issue/main_test.go'}
:: --> gopls textDocument/codeAction(20): {'context': {'diagnostics': [{'source': 'syntax', 'severity': 1, 'range': {'end': {'character': 0, 'line': 3}, 'start': {'character': 0, 'line': 3}}, 'message': "expected '(', found newline"}]}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}, 'range': {'end': {'character': 7, 'line': 2}, 'start': {'character': 7, 'line': 2}}}
gopls: 2023/04/12 13:02:47 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:8: expected '(', found newline (and 2 more errors)
	file="/home/user/lsp_issue/main_test.go"

:: <-  gopls window/logMessage: {'message': '2023/04/12 13:02:47 imports fixes: AllImportsFixes: /home/user/lsp_issue/main_test.go:3:8: expected \'(\', found newline (and 2 more errors)\n\tfile="/home/user/lsp_issue/main_test.go"\n', 'type': 1}
:: <<< gopls 20: None
:: --> gopls textDocument/documentHighlight(21): {'position': {'character': 7, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <<< gopls 21: [{'range': {'end': {'character': 0, 'line': 3}, 'start': {'character': 5, 'line': 2}}, 'kind': 1}]
::  -> gopls textDocument/didChange: {'contentChanges': [{'text': 'TestXxx(t *testing.T) {\n\n}', 'range': {'end': {'character': 7, 'line': 2}, 'start': {'character': 7, 'line': 2}}, 'rangeLength': 0}], 'textDocument': {'version': 9, 'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: --> gopls textDocument/documentHighlight(22): {'position': {'character': 14, 'line': 2}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <<< gopls 22: [{'range': {'end': {'character': 14, 'line': 2}, 'start': {'character': 5, 'line': 2}}, 'kind': 1}]
:: <-  gopls textDocument/publishDiagnostics: {'version': 9, 'diagnostics': [{'message': 'undefined: testing', 'code': 'UndeclaredName', 'codeDescription': {'href': 'https://pkg.go.dev/golang.org/x/tools/internal/typesinternal#UndeclaredName'}, 'source': 'compiler', 'range': {'end': {'character': 25, 'line': 2}, 'start': {'character': 18, 'line': 2}}, 'severity': 1}], 'uri': 'file:///home/user/lsp_issue/main_test.go'}
:: --> gopls textDocument/codeAction(23): {'context': {'diagnostics': []}, 'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}, 'range': {'end': {'character': 14, 'line': 2}, 'start': {'character': 11, 'line': 2}}}
:: <<< gopls 23: [{'edit': {'documentChanges': [{'edits': [{'newText': '\nimport "testing"\n', 'range': {'end': {'character': 0, 'line': 1}, 'start': {'character': 0, 'line': 1}}}], 'textDocument': {'version': 9, 'uri': 'file:///home/user/lsp_issue/main_test.go'}}]}, 'title': 'Organize Imports', 'kind': 'source.organizeImports'}]

@findleyr findleyr removed the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Apr 12, 2023
@hyangah
Copy link
Contributor

hyangah commented Apr 12, 2023

Thanks for sharing the trace.
I don't know the cause yet. Would be nice if someone could test with other editors too before we conclude this is a bad interaction with sublime text editor.

This is the part that may look relevant.

::  -> gopls textDocument/didChange: {'contentChanges': [{'text': 'e', 'range': {'end': {'character': 6, 'line': 2}, 'start': {'character': 6, 'line': 2}}, 'rangeLength': 0}], 'textDocument': {'version': 8, 'uri': 'file:///home/user/lsp_issue/main_test.go'}}

:: --> gopls textDocument/completion(19): {
     'position': {'character': 7, 'line': 2},
     'textDocument': {'uri': 'file:///home/user/lsp_issue/main_test.go'}}
:: <<< gopls 19: {
     'items': [{
         'detail': 'tab, type the rest of the name, then tab',
         'textEdit': {'newText': 'Test${1:Xxx}(t *testing.T) {\n$0\n\\}',
         'range': {
              'end': {'character': 5, 'line': 2},
              'start': {'character': 5, 'line': 2}}},
        'label': 'TestXxx(t *testing.T)', 
        'preselect': True,
        'documentation': 'Test test function',
        'sortText': '00000',
        'insertTextFormat': 2,
        'kind': 3
   }, 
   ....],
   'isIncomplete': True}

::  -> gopls textDocument/didChange: {'contentChanges': [{'text': 'TestXxx(t *testing.T) {\n\n}', 'range': {'end': {'character': 7, 'line': 2}, 'start': {'character': 7, 'line': 2}}, 'rangeLength': 0}], 'textDocument': {'version': 9, 'uri': 'file:///home/user/lsp_issue/main_test.go'}}

This is a similar sequence captured in vscode.

[Trace - 5:56:15 PM] Sending notification 'textDocument/didChange'.
Params: {
    "textDocument": {"uri": "file:///Users/hakim/projects/tmp/main_test.go", "version": 9},
    "contentChanges": [{
            "range": {
                "start": {"line": 2, "character": 6},
                "end": {"line": 2,"character": 6}
            },
            "rangeLength": 0,
            "text": "e"
    }]
}
...
[Trace - 5:56:15 PM] Sending request 'textDocument/completion - (38)'.
Params: {
    "textDocument": { "uri": "file:///Users/hakim/projects/tmp/main_test.go"},
    "position": {"line": 2,"character": 7},
    "context": {"triggerKind": 3}
}

[Trace - 5:56:15 PM] Received response 'textDocument/completion - (38)' in 5ms.
Result: {
    "isIncomplete": true,
    "items": [
        {
            "label": "TestXxx(t *testing.T)",
            "kind": 3,
            "detail": "tab, type the rest of the name, then tab",
            "documentation": {
                "kind": "markdown",
                "value": "Test test function\n"
            },
            "preselect": true,
            "sortText": "00000",
            "insertTextFormat": 2,
            "textEdit": {
                "range": {
                    "start": {"line": 2,"character": 5},
                    "end": {"line": 2, "character": 7}
                },
                "newText": "Test${1:Xxx}(t *testing.T) {\n\t$0\n\\}"
            }
        },
        ...
   ]
}     

In both cases, the editor sent the completion request when on position (2,7). Gopls returned the completion item with start range (2,5). However, there are some differences.

  • Sublime LSP client didn't fill in "context"/"triggerKind" field in the request. However, I couldn't see the code that uses the triggerKind in gopls, so that may not be relevant.
  • Gopls returned the completion item with textEdit.range (2,5)-(2,5) for Sublime text. That is very suspicious.
    Gopls returned range (2,5)~(2,7) which makes sense.
  • Sublime LSP client then inserted the textEdit to the position (2,7).

Some hypothesis:

  • Gopls's returning the range (2,5)~(2,5) for the completion request on position (2,7) confused the Sublime LSP client.
  • Sublime LSP client has a bug that just couldn't handle the start range before the completion request position.

@muirdm
Copy link

muirdm commented Apr 15, 2023

someone could test with other editors

I couldn't repro in Emacs via lsp-mode.

@muirdm
Copy link

muirdm commented Apr 15, 2023

The insert range from gopls is definitely wrong - it should be overwriting the prefix. The initial range computed by gopls in this case is the start and end of the *ast.Ident being completed (i.e. "Te"). I haven't spotted any conditional logic yet to explain the discrepancy.

Can you share the entire contents of a test file that reproduces it?

@kortschak
Copy link
Contributor Author

package main

import "testing"

func Te

<tab> at the final position in the file.

@vikblom
Copy link

vikblom commented Apr 19, 2023

Hi @kortschak ,
this sounds similar to #56852 which should be fixed but has not yet been released.

Could you test if the problem exists on gopls master? Edit: see findleyr response on how.

@findleyr
Copy link
Contributor

Thanks for finding that, @vikblom. Yes, I think this is a dupe of https://go.dev/issue/57480.

go install golang.org/x/tools/gopls@master

This is not the correct way to install gopls@master (and I'd be surprised if it worked), because it doesn't honor the replace directive. To install gopls@master, you should check out x/tools, cd gopls, and go install.

@kortschak
Copy link
Contributor Author

Thanks, yes that has it fixed.

@golang golang locked and limited conversation to collaborators Apr 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

6 participants