What version of Go are you using (go version
)?
$ go version go version go1.12.4 linux/amd64 $ go list -m golang.org/x/tools golang.org/x/tools v0.0.0-20190428024724-550556f78a90
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GOARCH="amd64" GOBIN="/home/myitcv/gostuff/src/github.com/myitcv/govim/.bin" GOCACHE="/home/myitcv/.cache/go-build" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOOS="linux" GOPATH="/home/myitcv/gostuff" GOPROXY="" GORACE="" GOROOT="/home/myitcv/gos" GOTMPDIR="" GOTOOLDIR="/home/myitcv/gos/pkg/tool/linux_amd64" GCCGO="gccgo" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/home/myitcv/gostuff/src/github.com/myitcv/govim/go.mod" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build120717318=/tmp/go-build -gno-record-gcc-switches"
What did you do?
Considering the following govim
testscript
in which I attempt to range-format line numbers 3-5 (inc) in main.go
:
vim ex 'e main.go'
vim ex '3,5GOVIMGoFmt'
vim ex 'noautocmd w'
cmp main.go main.go.golden
-- go.mod --
module mod
-- main.go --
package main
func main(){
fmt.Println("Hello, world")
}
-- main.go.golden --
package main
func main() {
fmt.Println("Hello, world")
}
I get the error:
ToUTF16Column: point is missing offset
The params sent were:
&protocol.DocumentRangeFormattingParams{
TextDocument: protocol.TextDocumentIdentifier{URI:"file://$WORK/main.go"},
Range: protocol.Range{
Start: protocol.Position{Line:2, Character:0},
End: protocol.Position{Line:5, Character:0},
},
Options: protocol.FormattingOptions{},
}
What did you expect to see?
No error.
What did you see instead?
The above error.
cc @stamblerre @ianthehat
Comment From: sysulq
+1
Comment From: myitcv
@hnlq715 - please add π emoji responses to the original description (https://github.com/golang/go/wiki/NoPlusOne)
Comment From: ianthehat
I think I fixed this in https://go-review.googlesource.com/c/tools/+/170186, please re-open if it is still happening.
Comment From: myitcv
I'm still seeing this in 202502a5a924:
https://travis-ci.org/myitcv/govim/builds/515152204
Comment From: qqqasdwx
I use vscode-go get same error , when I save a go file,I miss result Output->go-langserver
[Error - δΈε2:46:00] Request textDocument/codeAction failed.
Message: ToUTF16Column: point is missing offset
Code: 0
And my settings.json
"go.alternateTools": {
"go-langserver": "gopls",
},
"go.languageServerExperimentalFeatures": {
"format": true,
"autoComplete": true,
"goToDefinition": true,
"signatureHelp": true,
"goToTypeDefinition": true
},
"go.useLanguageServer": true,
"[go]": {
"editor.snippetSuggestions": "none",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
},
}
I try
go get -u -v golang.org/x/tools/cmd/gopls
it's not ok T.T
Comment From: zippoxer
Can reproduce on Windows 10 64 bit, Go 1.12.4, VSCode 1.33.1 and gopls@cb2dda6eabdf9160e66ca7293897f984154a7f8b (latest at this time).
VSCode settings:
"go.useLanguageServer": true,
"[go]": {
"editor.snippetSuggestions": "none",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
},
"gopls": {
"usePlaceholders": true,
"enhancedHover": true
},
Edit: I noticed this error is showing up every time I save a Go file.
Comment From: zippoxer
I've found a temporary solution: convert all your source files from CRLF to LF (from Windows to Unix line endings).
Note for VSCode users: don't forget to put "files.eol": "\n"
in your settings.json
, otherwise new files will still use CRLF.
π‘ Yay! π‘ Now I'm not seeing the ToUTF16Column error anymore, and gopls formats my source files when it didn't before.
Hope this helps some fellow DOSphers.
Comment From: myitcv
@zippoxer the ToUTF16Column
errors are, I think, a separate issue, and should be fixed as of https://github.com/golang/tools/commit/0c752f569a3efd362925ea641059c7c60856053f
Comment From: sleep2death
pulled the latest 'tools', vscode with gopls is still not working...
Comment From: kylelemons
I can confirm that my ToUTF16Column
errors also went away on Windows with VSCode-Go after resetting my line endings to lf in git.
Comment From: myitcv
I'm still seeing this despite not having any Windows line endings.
Sample stack trace (if I change a return
to a panic
):
panic: ToUTF16Column: point is missing offset
goroutine 5 [running]:
golang.org/x/tools/internal/span.ToUTF16Column(0x2, 0x1, 0xffffffffffffffff, 0xc00d4580d0, 0xd, 0x10, 0x1, 0x0, 0x0)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/span/utf16.go:25 +0x561
golang.org/x/tools/internal/lsp/protocol.(*ColumnMapper).Position(0xc0010b0450, 0x2, 0x1, 0xffffffffffffffff, 0x0, 0x0, 0x0, 0x0)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/protocol/span.go:62 +0x63
golang.org/x/tools/internal/lsp/protocol.(*ColumnMapper).Range(0xc0010b0450, 0xc0028581c0, 0x39, 0x1, 0x1, 0x0, 0x2, 0x1, 0xffffffffffffffff, 0x39, ...)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/protocol/span.go:54 +0x4b0
golang.org/x/tools/internal/lsp.ToProtocolEdits(0xc0010b0450, 0xc0005ba320, 0x2, 0x2, 0xc000182740, 0x37ec55, 0x37ec62, 0xc0005ba320, 0x2)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/format.go:68 +0x134
golang.org/x/tools/internal/lsp.organizeImports(0x8dff20, 0xc006308740, 0x8e00a0, 0xc0001c8000, 0xc0028581c0, 0x39, 0x1, 0x1, 0x0, 0x1, ...)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/code_action.go:86 +0x21e
golang.org/x/tools/internal/lsp.(*Server).codeAction(0xc0000aa7e0, 0x8dff20, 0xc006308740, 0xc003688000, 0xc003688000, 0x0, 0x0, 0x0, 0xc0005ba280)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/code_action.go:32 +0x1fb
golang.org/x/tools/internal/lsp.(*Server).CodeAction(0xc0000aa7e0, 0x8dff20, 0xc006308740, 0xc003688000, 0xc003688000, 0x0, 0x0, 0x10, 0x0)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/server.go:202 +0x4d
golang.org/x/tools/internal/lsp/protocol.serverHandler.func1(0x8dff20, 0xc006308740, 0xc00014e3f0, 0xc003ebe940)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/protocol/server.go:336 +0x2bdd
golang.org/x/tools/internal/jsonrpc2.(*Conn).Run.func1(0xc000074a80, 0xc00014e3f0)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/jsonrpc2/jsonrpc2.go:276 +0xda
created by golang.org/x/tools/internal/jsonrpc2.(*Conn).Run
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/jsonrpc2/jsonrpc2.go:270 +0xba
@ianthehat - is the related to the diff changes that landed not long ago?
Comment From: ianthehat
I am confused as to what is happening here, and I can't reproduce it.
For that stack trace to be produced, the span of an edit must have an invalid end position.
It is failing in the call to m.Position(s.End())
a couple of lines after doing s, err := s.WithAll(m.Converter)
which means that either that function failed to set the offset without failing, or something concurrently modified the offset
Comment From: myitcv
Ok, I've managed to track down this particular instance of the ToUTF16Column: point is missing offset
error to the case where a file contains a single line that is the package clause, with no trailing \n
. Here is the sequence of events from govim
's perspective:
Sequence of events
gopls server start ======================= gopls.Initialize() call; params: &protocol.InitializeParams{ ProcessID: 0, RootPath: "", RootURI: "file:///home/myitcv/gostuff/src/github.com/myitcv/playground", Capabilities: protocol.ClientCapabilities{ Workspace: struct { ApplyEdit bool "json:\"applyEdit,omitempty\""; WorkspaceEdit struct { DocumentChanges bool "json:\"documentChanges,omitempty\""; ResourceOperations []protocol.ResourceOperationKind "json:\"resourceOperations,omitempty\""; FailureHandling protocol.FailureHandlingKind "json:\"failureHandling,omitempty\"" } "json:\"workspaceEdit,omitempty\""; DidChangeConfiguration struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" } "json:\"didChangeConfiguration,omitempty\""; DidChangeWatchedFiles struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" } "json:\"didChangeWatchedFiles,omitempty\""; Symbol struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; SymbolKind struct { ValueSet []protocol.SymbolKind "json:\"valueSet,omitempty\"" } "json:\"symbolKind,omitempty\"" } "json:\"symbol,omitempty\""; ExecuteCommand struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" } "json:\"executeCommand,omitempty\""; WorkspaceFolders bool "json:\"workspaceFolders,omitempty\""; Configuration bool "json:\"configuration,omitempty\"" }{}, TextDocument: struct { Synchronization struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; WillSave bool "json:\"willSave,omitempty\""; WillSaveWaitUntil bool "json:\"willSaveWaitUntil,omitempty\""; DidSave bool "json:\"didSave,omitempty\"" } "json:\"synchronization,omitempty\""; Completion struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; CompletionItem struct { SnippetSupport bool "json:\"snippetSupport,omitempty\""; CommitCharactersSupport bool "json:\"commitCharactersSupport,omitempty\""; DocumentationFormat []protocol.MarkupKind "json:\"documentationFormat,omitempty\""; DeprecatedSupport bool "json:\"deprecatedSupport,omitempty\""; PreselectSupport bool "json:\"preselectSupport,omitempty\"" } "json:\"completionItem,omitempty\""; CompletionItemKind struct { ValueSet []protocol.CompletionItemKind "json:\"valueSet,omitempty\"" } "json:\"completionItemKind,omitempty\""; ContextSupport bool "json:\"contextSupport,omitempty\"" } "json:\"completion,omitempty\""; Hover struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; ContentFormat []protocol.MarkupKind "json:\"contentFormat,omitempty\"" } "json:\"hover,omitempty\""; SignatureHelp struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; SignatureInformation struct { DocumentationFormat []protocol.MarkupKind "json:\"documentationFormat,omitempty\""; ParameterInformation struct { LabelOffsetSupport bool "json:\"labelOffsetSupport,omitempty\"" } "json:\"parameterInformation,omitempty\"" } "json:\"signatureInformation,omitempty\"" } "json:\"signatureHelp,omitempty\""; References struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" } "json:\"references,omitempty\""; DocumentHighlight struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" } "json:\"documentHighlight,omitempty\""; DocumentSymbol struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; SymbolKind struct { ValueSet []protocol.SymbolKind "json:\"valueSet,omitempty\"" } "json:\"symbolKind,omitempty\""; HierarchicalDocumentSymbolSupport bool "json:\"hierarchicalDocumentSymbolSupport,omitempty\"" } "json:\"documentSymbol,omitempty\""; Formatting struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" } "json:\"formatting,omitempty\""; RangeFormatting struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" } "json:\"rangeFormatting,omitempty\""; OnTypeFormatting struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" } "json:\"onTypeFormatting,omitempty\""; Definition struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; LinkSupport bool "json:\"linkSupport,omitempty\"" } "json:\"definition,omitempty\""; CodeAction struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; CodeActionLiteralSupport struct { CodeActionKind struct { ValueSet []protocol.CodeActionKind "json:\"valueSet\"" } "json:\"codeActionKind\"" } "json:\"codeActionLiteralSupport,omitempty\"" } "json:\"codeAction,omitempty\""; CodeLens struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" } "json:\"codeLens,omitempty\""; DocumentLink struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" } "json:\"documentLink,omitempty\""; Rename struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; PrepareSupport bool "json:\"prepareSupport,omitempty\"" } "json:\"rename,omitempty\""; PublishDiagnostics struct { RelatedInformation bool "json:\"relatedInformation,omitempty\""; TagSupport bool "json:\"tagSupport,omitempty\"" } "json:\"publishDiagnostics,omitempty\""; Implementation struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; LinkSupport bool "json:\"linkSupport,omitempty\"" } "json:\"implementation,omitempty\""; TypeDefinition struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; LinkSupport bool "json:\"linkSupport,omitempty\"" } "json:\"typeDefinition,omitempty\""; ColorProvider struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" } "json:\"colorProvider,omitempty\""; FoldingRange struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; RangeLimit float64 "json:\"rangeLimit,omitempty\""; LineFoldingOnly bool "json:\"lineFoldingOnly,omitempty\"" } "json:\"foldingRange,omitempty\""; Declaration struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; LinkSupport bool "json:\"linkSupport,omitempty\"" } "json:\"declaration,omitempty\""; SelectionRange struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" } "json:\"selectionRange,omitempty\"" }{ Synchronization: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; WillSave bool "json:\"willSave,omitempty\""; WillSaveWaitUntil bool "json:\"willSaveWaitUntil,omitempty\""; DidSave bool "json:\"didSave,omitempty\"" }{}, Completion: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; CompletionItem struct { SnippetSupport bool "json:\"snippetSupport,omitempty\""; CommitCharactersSupport bool "json:\"commitCharactersSupport,omitempty\""; DocumentationFormat []protocol.MarkupKind "json:\"documentationFormat,omitempty\""; DeprecatedSupport bool "json:\"deprecatedSupport,omitempty\""; PreselectSupport bool "json:\"preselectSupport,omitempty\"" } "json:\"completionItem,omitempty\""; CompletionItemKind struct { ValueSet []protocol.CompletionItemKind "json:\"valueSet,omitempty\"" } "json:\"completionItemKind,omitempty\""; ContextSupport bool "json:\"contextSupport,omitempty\"" }{}, Hover: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; ContentFormat []protocol.MarkupKind "json:\"contentFormat,omitempty\"" }{ DynamicRegistration: false, ContentFormat: {"plaintext"}, }, SignatureHelp: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; SignatureInformation struct { DocumentationFormat []protocol.MarkupKind "json:\"documentationFormat,omitempty\""; ParameterInformation struct { LabelOffsetSupport bool "json:\"labelOffsetSupport,omitempty\"" } "json:\"parameterInformation,omitempty\"" } "json:\"signatureInformation,omitempty\"" }{}, References: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" }{}, DocumentHighlight: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" }{}, DocumentSymbol: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; SymbolKind struct { ValueSet []protocol.SymbolKind "json:\"valueSet,omitempty\"" } "json:\"symbolKind,omitempty\""; HierarchicalDocumentSymbolSupport bool "json:\"hierarchicalDocumentSymbolSupport,omitempty\"" }{}, Formatting: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" }{}, RangeFormatting: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" }{}, OnTypeFormatting: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" }{}, Definition: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; LinkSupport bool "json:\"linkSupport,omitempty\"" }{}, CodeAction: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; CodeActionLiteralSupport struct { CodeActionKind struct { ValueSet []protocol.CodeActionKind "json:\"valueSet\"" } "json:\"codeActionKind\"" } "json:\"codeActionLiteralSupport,omitempty\"" }{}, CodeLens: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" }{}, DocumentLink: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" }{}, Rename: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; PrepareSupport bool "json:\"prepareSupport,omitempty\"" }{}, PublishDiagnostics: struct { RelatedInformation bool "json:\"relatedInformation,omitempty\""; TagSupport bool "json:\"tagSupport,omitempty\"" }{}, Implementation: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; LinkSupport bool "json:\"linkSupport,omitempty\"" }{}, TypeDefinition: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; LinkSupport bool "json:\"linkSupport,omitempty\"" }{}, ColorProvider: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" }{}, FoldingRange: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; RangeLimit float64 "json:\"rangeLimit,omitempty\""; LineFoldingOnly bool "json:\"lineFoldingOnly,omitempty\"" }{}, Declaration: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\""; LinkSupport bool "json:\"linkSupport,omitempty\"" }{}, SelectionRange: struct { DynamicRegistration bool "json:\"dynamicRegistration,omitempty\"" }{}, }, Experimental: nil, }, InitializationOptions: nil, Trace: "", WorkspaceFolders: nil, } gopls server end ======================= gopls server start ======================= gopls.Initialize() return; err:; res: &protocol.InitializeResult{ Capabilities: protocol.ServerCapabilities{ TextDocumentSync: map[string]interface {}{ "openClose": bool(true), "change": float64(1), }, HoverProvider: true, CompletionProvider: &protocol.CompletionOptions{ TriggerCharacters: {"."}, AllCommitCharacters: nil, ResolveProvider: false, }, SignatureHelpProvider: &protocol.SignatureHelpOptions{ TriggerCharacters: {"(", ","}, }, DefinitionProvider: true, ReferencesProvider: false, DocumentHighlightProvider: true, DocumentSymbolProvider: true, WorkspaceSymbolProvider: false, CodeActionProvider: true, CodeLensProvider: (*protocol.CodeLensOptions)(nil), DocumentFormattingProvider: true, DocumentRangeFormattingProvider: true, DocumentOnTypeFormattingProvider: (*struct { FirstTriggerCharacter string "json:\"firstTriggerCharacter\""; MoreTriggerCharacter []string "json:\"moreTriggerCharacter,omitempty\"" })(nil), RenameProvider: (*protocol.RenameOptions)(nil), DocumentLinkProvider: (*protocol.DocumentLinkOptions)(nil), ExecuteCommandProvider: (*protocol.ExecuteCommandOptions)(nil), Experimental: nil, ImplementationProvider: false, TypeDefinitionProvider: true, Workspace: (*struct { WorkspaceFolders *struct { Supported bool "json:\"supported,omitempty\""; ChangeNotifications string "json:\"changeNotifications,omitempty\"" } "json:\"workspaceFolders,omitempty\"" })(nil), ColorProvider: false, FoldingRangeProvider: false, DeclarationProvider: false, SelectionRangeProvider: false, }, Custom: {}, } gopls server end ======================= gopls server start ======================= gopls.DidOpen() call; params: &protocol.DidOpenTextDocumentParams{ TextDocument: protocol.TextDocumentItem{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/main.go", LanguageID:"", Version:0, Text:"package main\n"}, } gopls server end ======================= gopls server start ======================= gopls.DidOpen() return; err: gopls server end ======================= gopls server start ======================= gopls.DidOpen() call; params: &protocol.DidOpenTextDocumentParams{ TextDocument: protocol.TextDocumentItem{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go", LanguageID:"", Version:0, Text:""}, } gopls server end ======================= gopls server start ======================= gopls.DidOpen() return; err: gopls server end ======================= gopls server start ======================= gopls.DidChange() call; params: &protocol.DidChangeTextDocumentParams{ TextDocument: protocol.VersionedTextDocumentIdentifier{ Version: 1, TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, }, ContentChanges: { { Range: (*protocol.Range)(nil), RangeLength: 0, Text: "p", }, }, } gopls server end ======================= gopls server start ======================= gopls.DidChange() return; err: gopls server end ======================= gopls server start ======================= gopls.DidChange() call; params: &protocol.DidChangeTextDocumentParams{ TextDocument: protocol.VersionedTextDocumentIdentifier{ Version: 2, TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, }, ContentChanges: { { Range: (*protocol.Range)(nil), RangeLength: 0, Text: "pa", }, }, } gopls server end ======================= gopls server start ======================= gopls.DidChange() return; err: gopls server end ======================= gopls server start ======================= gopls.DidChange() call; params: &protocol.DidChangeTextDocumentParams{ TextDocument: protocol.VersionedTextDocumentIdentifier{ Version: 3, TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, }, ContentChanges: { { Range: (*protocol.Range)(nil), RangeLength: 0, Text: "pac", }, }, } gopls server end ======================= gopls server start ======================= gopls.DidChange() return; err: gopls server end ======================= gopls server start ======================= gopls.DidChange() call; params: &protocol.DidChangeTextDocumentParams{ TextDocument: protocol.VersionedTextDocumentIdentifier{ Version: 4, TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, }, ContentChanges: { { Range: (*protocol.Range)(nil), RangeLength: 0, Text: "pack", }, }, } gopls server end ======================= gopls server start ======================= gopls.DidChange() return; err: gopls server end ======================= gopls server start ======================= gopls.DidChange() call; params: &protocol.DidChangeTextDocumentParams{ TextDocument: protocol.VersionedTextDocumentIdentifier{ Version: 5, TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, }, ContentChanges: { { Range: (*protocol.Range)(nil), RangeLength: 0, Text: "packa", }, }, } gopls server end ======================= gopls server start ======================= gopls.DidChange() return; err: gopls server end ======================= gopls server start ======================= gopls.DidChange() call; params: &protocol.DidChangeTextDocumentParams{ TextDocument: protocol.VersionedTextDocumentIdentifier{ Version: 6, TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, }, ContentChanges: { { Range: (*protocol.Range)(nil), RangeLength: 0, Text: "packag", }, }, } gopls server end ======================= gopls server start ======================= gopls.DidChange() return; err: gopls server end ======================= gopls server start ======================= gopls.DidChange() call; params: &protocol.DidChangeTextDocumentParams{ TextDocument: protocol.VersionedTextDocumentIdentifier{ Version: 7, TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, }, ContentChanges: { { Range: (*protocol.Range)(nil), RangeLength: 0, Text: "package", }, }, } gopls server end ======================= gopls server start ======================= gopls.DidChange() return; err: gopls server end ======================= gopls server start ======================= gopls.DidChange() call; params: &protocol.DidChangeTextDocumentParams{ TextDocument: protocol.VersionedTextDocumentIdentifier{ Version: 8, TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, }, ContentChanges: { { Range: (*protocol.Range)(nil), RangeLength: 0, Text: "package ", }, }, } gopls server end ======================= gopls server start ======================= gopls.DidChange() return; err: gopls server end ======================= gopls server start ======================= gopls.DidChange() call; params: &protocol.DidChangeTextDocumentParams{ TextDocument: protocol.VersionedTextDocumentIdentifier{ Version: 9, TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, }, ContentChanges: { { Range: (*protocol.Range)(nil), RangeLength: 0, Text: "package m", }, }, } gopls server end ======================= gopls server start ======================= gopls.DidChange() return; err: gopls server end ======================= gopls server start ======================= gopls.DidChange() call; params: &protocol.DidChangeTextDocumentParams{ TextDocument: protocol.VersionedTextDocumentIdentifier{ Version: 10, TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, }, ContentChanges: { { Range: (*protocol.Range)(nil), RangeLength: 0, Text: "package ma", }, }, } gopls server end ======================= gopls server start ======================= gopls.DidChange() return; err: gopls server end ======================= gopls server start ======================= gopls.DidChange() call; params: &protocol.DidChangeTextDocumentParams{ TextDocument: protocol.VersionedTextDocumentIdentifier{ Version: 11, TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, }, ContentChanges: { { Range: (*protocol.Range)(nil), RangeLength: 0, Text: "package mai", }, }, } gopls server end ======================= gopls server start ======================= gopls.DidChange() return; err: gopls server end ======================= gopls server start ======================= gopls.DidChange() call; params: &protocol.DidChangeTextDocumentParams{ TextDocument: protocol.VersionedTextDocumentIdentifier{ Version: 12, TextDocumentIdentifier: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, }, ContentChanges: { { Range: (*protocol.Range)(nil), RangeLength: 0, Text: "package main", }, }, } gopls server end ======================= gopls server start ======================= gopls.DidChange() return; err: gopls server end ======================= gopls server start ======================= gopls.CodeAction() call; params: &protocol.CodeActionParams{ TextDocument: protocol.TextDocumentIdentifier{URI:"file:///home/myitcv/gostuff/src/github.com/myitcv/playground/blah.go"}, Range: protocol.Range{}, Context: protocol.CodeActionContext{}, } gopls server end =======================
which gives rise to the following exception:
panic: ToUTF16Column: point is missing offset
goroutine 5 [running]:
golang.org/x/tools/internal/span.ToUTF16Column(0x2, 0x1, 0xffffffffffffffff, 0xc0003c02f0, 0xc, 0x10, 0x1, 0x0, 0x0)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/span/utf16.go:25 +0x561
golang.org/x/tools/internal/lsp/protocol.(*ColumnMapper).Position(0xc0003fe150, 0x2, 0x1, 0xffffffffffffffff, 0x0, 0x0, 0x0, 0x0)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/protocol/span.go:62 +0x63
golang.org/x/tools/internal/lsp/protocol.(*ColumnMapper).Range(0xc0003fe150, 0xc000188460, 0x44, 0x1, 0x1, 0x0, 0x2, 0x1, 0xffffffffffffffff, 0x44, ...)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/protocol/span.go:54 +0x4b0
golang.org/x/tools/internal/lsp.ToProtocolEdits(0xc0003fe150, 0xc0003f80a0, 0x2, 0x2, 0xc000182740, 0x16b, 0x177, 0xc0003f80a0, 0x2)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/format.go:68 +0x134
golang.org/x/tools/internal/lsp.organizeImports(0x8dff20, 0xc000222b80, 0x8e00a0, 0xc0001c4000, 0xc000188460, 0x44, 0x1, 0x1, 0x0, 0x1, ...)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/code_action.go:86 +0x21e
golang.org/x/tools/internal/lsp.(*Server).codeAction(0xc0000a87e0, 0x8dff20, 0xc000222b80, 0xc0003f6000, 0xc0003f6000, 0x0, 0x0, 0x0, 0xc0003f8000)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/code_action.go:32 +0x1fb
golang.org/x/tools/internal/lsp.(*Server).CodeAction(0xc0000a87e0, 0x8dff20, 0xc000222b80, 0xc0003f6000, 0xc0003f6000, 0x0, 0x0, 0x0, 0x0)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/server.go:202 +0x4d
golang.org/x/tools/internal/lsp/protocol.serverHandler.func1(0x8dff20, 0xc000222b80, 0xc00014c3f0, 0xc000228ec0)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/lsp/protocol/server.go:336 +0x2bdd
golang.org/x/tools/internal/jsonrpc2.(*Conn).Run.func1(0xc000072a80, 0xc00014c3f0)
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/jsonrpc2/jsonrpc2.go:276 +0xda
created by golang.org/x/tools/internal/jsonrpc2.(*Conn).Run
/tmp/tmp.xetMpJpdla/golang.org/x/tools/internal/jsonrpc2/jsonrpc2.go:270 +0xba
If instead of simply writing package main
to blah.go
I write package main\n
(i.e. there is a trailing newline), then I don't see any issues.
Comment From: iwittkau
I had the same issue on a fresh macOS install today (latests Go, VSCode and tools). I was able to resolve the issue by using gofmt -w file.go
on the offending file.go
. The file contained copied code from json-to-go.
Comment From: gopherbot
Change https://golang.org/cl/175938 mentions this issue: internal/lsp: disable rangeFormatting temporarily
Comment From: stamblerre
It seems that range formatting has actually not been working for quite some time - temporarily disabling it until we find a good solution. Formatting should still work correctly however.
Comment From: hyangah
This is marked as "help wanted" currently. @findleyr @pjweinb According to the description of the change that disabled this feature https://golang.org/cl/175938 I guess the challenge is in using the diff library. Will the new diff work you were looking into remove one of the road blockers?
Comment From: pjweinb
I don't fully understand what was happening, but once the new diff is in, range formatting is a feature we should be able to make work.
Comment From: pjweinb
Go programs are formatted by the go/format package, which has two entry points, format.Node() and format.Source(). The former has restricted input and unless the input is the whole file, loses comments. The latter, to simplify, only formats text that could syntactically be the body of a function. That is, formatting the range Foo: "xxx", Bar: "yyy", to fix the whitespace produces an error. TLDR, neither of the possibilities works adequately well. The alternative, writing our own implementation of formatting, would be error-prone and difficult to keep in sync with go/format. This feature request will be closed soon unless someone has a better idea how to implement it.
Comment From: kylelemons
I'm not super familiar with the LSP API itself, but could you conceivably expand the range you're given until you can format it with Source, and then either return that rewrite or (harder) try to work backwards to figure out the changes required to just the portion that was selected?
Comment From: pjweinb
I looked at small extensions of the user selection, but that just didn't add much utility. There's probably something gopls could do, but what, exactly? That is, there is a sort of specification of what formatting the whole file does (namely, call format.Node on the ast.FIle), but what should range formatting do? Without a clear and convincing proposal we (meaning me) don't know what to try to implement.
On Wed, Sep 28, 2022 at 11:16 AM Kyle Lemons @.***> wrote:
I'm not super familiar with the LSP API itself, but could you conceivably expand the range you're given until you can format it with Source, and then either return that rewrite or (harder) try to work backwards to figure out the changes required to just the portion that was selected?
β Reply to this email directly, view it on GitHub https://github.com/golang/go/issues/31150#issuecomment-1261066844, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABJIAIZ4ZLIB4UY3SHHYH2TWAROL7ANCNFSM4HCLYSNA . You are receiving this because you were assigned.Message ID: @.***>
Comment From: adonovan
I'm not convinced this is a feature we should ever add. Technical difficulties aside, Go source files, even generated ones, should spend most of their lives in well formatted state. For those that are generated ill-formatted, it's a better use of everyone's time (and rarely difficult) to fix the upstream generator.