Repository: go
Issue: x/tools/gopls: can't enable semantic tokens from Emacs lsp-mode
Labels: gopls,Tools

I enabled semantic tokens in my LSP client and I enabled the experimental "semanticTokens" gopls config, but tokens still aren't happening. Currently the capability is registered in gopls after "initialize", but that looks too early since the client has not sent the "semanticTokens: true" custom gopls config yet (so options.SemanticTokens is always false).

I think we either need to not gate registration on options.SemanticTokens, or move the capability registration later until after the "workspace/configuration" is received from the client (, or maybe my client is doing something wrong?).

/cc @pjweinb 

Here is the transcript of my gopls startup:

<details>
<summary>lsp transcript</summary>

```
[Trace - 10:51:05 AM] Sending request 'initialize - (105)'.
Params: {
  "processId": null,
  "rootPath": "/Users/muir/scratch/foo",
  "clientInfo": {
    "name": "emacs",
    "version": "GNU Emacs 28.0.91 (build 1, aarch64-apple-darwin21.1.0, NS appkit-2113.00 Version 12.0.1 (Build 21A559))\n of 2022-01-19"
  },
  "rootUri": "file:///Users/muir/scratch/foo",
  "capabilities": {
    "workspace": {
      "workspaceEdit": {
        "documentChanges": true,
        "resourceOperations": [
          "create",
          "rename",
          "delete"
        ]
      },
      "applyEdit": true,
      "symbol": {
        "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
          ]
        }
      },
      "executeCommand": {
        "dynamicRegistration": false
      },
      "workspaceFolders": true,
      "configuration": true,
      "semanticTokens": {
        "refreshSupport": false
      },
      "codeLens": {
        "refreshSupport": true
      },
      "fileOperations": {
        "didCreate": false,
        "willCreate": false,
        "didRename": false,
        "willRename": false,
        "didDelete": false,
        "willDelete": false
      }
    },
    "textDocument": {
      "declaration": {
        "linkSupport": true
      },
      "definition": {
        "linkSupport": true
      },
      "implementation": {
        "linkSupport": true
      },
      "typeDefinition": {
        "linkSupport": true
      },
      "synchronization": {
        "willSave": true,
        "didSave": true,
        "willSaveWaitUntil": true
      },
      "documentSymbol": {
        "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
          ]
        },
        "hierarchicalDocumentSymbolSupport": true
      },
      "formatting": {
        "dynamicRegistration": true
      },
      "rangeFormatting": {
        "dynamicRegistration": true
      },
      "semanticTokens": {
        "dynamicRegistration": true,
        "requests": {
          "range": true,
          "full": true
        },
        "tokenModifiers": [
          "declaration",
          "definition",
          "implementation",
          "readonly",
          "static",
          "deprecated",
          "abstract",
          "async",
          "modification",
          "documentation",
          "defaultLibrary"
        ],
        "tokenTypes": [
          "comment",
          "keyword",
          "string",
          "number",
          "regexp",
          "operator",
          "namespace",
          "type",
          "struct",
          "class",
          "interface",
          "enum",
          "typeParameter",
          "function",
          "method",
          "member",
          "property",
          "event",
          "macro",
          "variable",
          "parameter",
          "label",
          "enumConstant",
          "enumMember",
          "dependent",
          "concept"
        ],
        "formats": [
          "relative"
        ]
      },
      "rename": {
        "dynamicRegistration": true,
        "prepareSupport": true
      },
      "codeAction": {
        "dynamicRegistration": true,
        "isPreferredSupport": true,
        "codeActionLiteralSupport": {
          "codeActionKind": {
            "valueSet": [
              "",
              "quickfix",
              "refactor",
              "refactor.extract",
              "refactor.inline",
              "refactor.rewrite",
              "source",
              "source.organizeImports"
            ]
          }
        },
        "resolveSupport": {
          "properties": [
            "edit",
            "command"
          ]
        },
        "dataSupport": true
      },
      "completion": {
        "completionItem": {
          "snippetSupport": true,
          "documentationFormat": [
            "markdown",
            "plaintext"
          ],
          "resolveAdditionalTextEditsSupport": true,
          "insertReplaceSupport": true,
          "deprecatedSupport": true,
          "resolveSupport": {
            "properties": [
              "documentation",
              "details",
              "additionalTextEdits",
              "command"
            ]
          },
          "insertTextModeSupport": {
            "valueSet": [
              1,
              2
            ]
          }
        },
        "contextSupport": true
      },
      "signatureHelp": {
        "signatureInformation": {
          "parameterInformation": {
            "labelOffsetSupport": true
          }
        }
      },
      "documentLink": {
        "dynamicRegistration": true,
        "tooltipSupport": true
      },
      "hover": {
        "contentFormat": [
          "markdown",
          "plaintext"
        ]
      },
      "foldingRange": {
        "dynamicRegistration": true
      },
      "callHierarchy": {
        "dynamicRegistration": false
      },
      "publishDiagnostics": {
        "relatedInformation": true,
        "tagSupport": {
          "valueSet": [
            1,
            2
          ]
        },
        "versionSupport": true
      },
      "linkedEditingRange": {
        "dynamicRegistration": true
      }
    },
    "window": {
      "workDoneProgress": true,
      "showMessage": null,
      "showDocument": {
        "support": true
      }
    }
  },
  "initializationOptions": null,
  "workDoneToken": "1"
}


[Trace - 10:51:05 AM] Received response 'initialize - (105)' in 45ms.
Result: {
  "capabilities": {
    "textDocumentSync": {
      "openClose": true,
      "change": 2,
      "save": {}
    },
    "completionProvider": {
      "triggerCharacters": [
        "."
      ],
      "completionItem": {}
    },
    "hoverProvider": true,
    "signatureHelpProvider": {
      "triggerCharacters": [
        "(",
        ","
      ]
    },
    "definitionProvider": true,
    "typeDefinitionProvider": true,
    "implementationProvider": true,
    "referencesProvider": true,
    "documentHighlightProvider": true,
    "documentSymbolProvider": true,
    "codeActionProvider": {
      "codeActionKinds": [
        "quickfix",
        "refactor.extract",
        "refactor.rewrite",
        "source.fixAll",
        "source.organizeImports"
      ]
    },
    "codeLensProvider": {},
    "documentLinkProvider": {},
    "workspaceSymbolProvider": true,
    "documentFormattingProvider": true,
    "documentOnTypeFormattingProvider": {
      "firstTriggerCharacter": ""
    },
    "renameProvider": {
      "prepareProvider": true
    },
    "foldingRangeProvider": true,
    "executeCommandProvider": {
      "commands": [
        "gopls.add_dependency",
        "gopls.add_import",
        "gopls.apply_fix",
        "gopls.check_upgrades",
        "gopls.edit_go_directive",
        "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.run_tests",
        "gopls.run_vulncheck_exp",
        "gopls.start_debugging",
        "gopls.test",
        "gopls.tidy",
        "gopls.toggle_gc_details",
        "gopls.update_go_sum",
        "gopls.upgrade_dependency",
        "gopls.vendor"
      ]
    },
    "callHierarchyProvider": true,
    "workspace": {
      "workspaceFolders": {
        "supported": true,
        "changeNotifications": "workspace/didChangeWorkspaceFolders"
      }
    }
  },
  "serverInfo": {
    "name": "gopls",
    "version": "{\"GoVersion\":\"go1.18\",\"Path\":\"golang.org/x/tools/gopls\",\"Main\":{\"Path\":\"golang.org/x/tools/gopls\",\"Version\":\"(devel)\",\"Sum\":\"\",\"Replace\":null},\"Deps\":[{\"Path\":\"github.com/BurntSushi/toml\",\"Version\":\"v1.0.0\",\"Sum\":\"h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=\",\"Replace\":null},{\"Path\":\"github.com/google/go-cmp\",\"Version\":\"v0.5.7\",\"Sum\":\"h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=\",\"Replace\":null},{\"Path\":\"github.com/sergi/go-diff\",\"Version\":\"v1.1.0\",\"Sum\":\"h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=\",\"Replace\":null},{\"Path\":\"golang.org/x/exp/typeparams\",\"Version\":\"v0.0.0-20220218215828-6cf2b201936e\",\"Sum\":\"h1:qyrTQ++p1afMkO4DPEeLGq/3oTsdlvdH4vqZUBWzUKM=\",\"Replace\":null},{\"Path\":\"golang.org/x/mod\",\"Version\":\"v0.6.0-dev.0.20220106191415-9b9b3d81d5e3\",\"Sum\":\"h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=\",\"Replace\":null},{\"Path\":\"golang.org/x/sync\",\"Version\":\"v0.0.0-20210220032951-036812b2e83c\",\"Sum\":\"h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=\",\"Replace\":null},{\"Path\":\"golang.org/x/sys\",\"Version\":\"v0.0.0-20220209214540-3681064d5158\",\"Sum\":\"h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=\",\"Replace\":null},{\"Path\":\"golang.org/x/text\",\"Version\":\"v0.3.7\",\"Sum\":\"h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=\",\"Replace\":null},{\"Path\":\"golang.org/x/tools\",\"Version\":\"v0.1.11-0.20220330174940-8e193c2ba95e\",\"Sum\":\"\",\"Replace\":{\"Path\":\"../\",\"Version\":\"(devel)\",\"Sum\":\"\",\"Replace\":null}},{\"Path\":\"golang.org/x/vuln\",\"Version\":\"v0.0.0-20220324005316-18fd808f5c7f\",\"Sum\":\"h1:9dMzk88fnONra7zrEalqkRMGa9jMGf9B5mdzhYVyI28=\",\"Replace\":null},{\"Path\":\"golang.org/x/xerrors\",\"Version\":\"v0.0.0-20200804184101-5ec99f83aff1\",\"Sum\":\"h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\",\"Replace\":null},{\"Path\":\"honnef.co/go/tools\",\"Version\":\"v0.3.0\",\"Sum\":\"h1:2LdYUZ7CIxnYgskbUZfY7FPggmqnh6shBqfWa8Tn3XU=\",\"Replace\":null},{\"Path\":\"mvdan.cc/gofumpt\",\"Version\":\"v0.3.0\",\"Sum\":\"h1:kTojdZo9AcEYbQYhGuLf/zszYthRdhDNDUi2JKTxas4=\",\"Replace\":null},{\"Path\":\"mvdan.cc/xurls/v2\",\"Version\":\"v2.4.0\",\"Sum\":\"h1:tzxjVAj+wSBmDcF6zBB7/myTy3gX9xvi8Tyr28AuQgc=\",\"Replace\":null}],\"Settings\":[{\"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\":\"arm64\"},{\"Key\":\"GOOS\",\"Value\":\"darwin\"},{\"Key\":\"vcs\",\"Value\":\"git\"},{\"Key\":\"vcs.revision\",\"Value\":\"46bc274e027b115f6b27988c1d28d2e91afdfbcb\"},{\"Key\":\"vcs.time\",\"Value\":\"2022-04-15T16:11:44Z\"},{\"Key\":\"vcs.modified\",\"Value\":\"true\"}],\"Version\":\"master\"}"
  }
}


[Trace - 10:51:05 AM] Sending notification 'initialized'.
Params: {}


[Trace - 10:51:05 AM] Sending notification 'textDocument/didOpen'.
Params: {
  "textDocument": {
    "uri": "file:///Users/muir/scratch/foo/foo.go",
    "languageId": "go",
    "version": 0,
    "text": "package main\n\ntype Foo[T any] func(T) T\n\nfunc Bar[T any](f Foo[T]) {}\n\n// Or\nfunc FooBar[T any](val T, f Foo[T]) {}\n\nfunc takesFunc[T any](func(T) T) {}\n\ntype foo[A int | string] struct{}\n\nfunc main() {\n\tvar f float64\n\tvar i int\n\t//\tfoo[]{}\n\t//\ttakesFunc(func(a bool) T {}\n}\n"
  }
}


[Trace - 10:51:05 AM] Sending request 'textDocument/codeLens - (106)'.
Params: {
  "textDocument": {
    "uri": "file:///Users/muir/scratch/foo/foo.go"
  }
}


[Trace - 10:51:05 AM] Sending request 'textDocument/codeAction - (107)'.
Params: {
  "textDocument": {
    "uri": "file:///Users/muir/scratch/foo/foo.go"
  },
  "range": {
    "start": {
      "line": 19,
      "character": 0
    },
    "end": {
      "line": 19,
      "character": 0
    }
  },
  "context": {
    "diagnostics": []
  }
}


[Trace - 10:51:05 AM] Sending request 'textDocument/documentHighlight - (108)'.
Params: {
  "textDocument": {
    "uri": "file:///Users/muir/scratch/foo/foo.go"
  },
  "position": {
    "line": 19,
    "character": 0
  }
}


[Trace - 10:51:05 AM] Sending notification '$/cancelRequest'.
Params: {
  "id": 106
}


[Trace - 10:51:05 AM] Sending request 'textDocument/codeLens - (109)'.
Params: {
  "textDocument": {
    "uri": "file:///Users/muir/scratch/foo/foo.go"
  }
}


[Trace - 10:51:05 AM] Received request 'window/workDoneProgress/create - (1).
Params: {
  "token": "5577006791947779410"
}


[Trace - 10:51:05 AM] Sending response 'window/workDoneProgress/create - (1)'. Processing request took 0ms
Params: {
  "jsonrpc": "2.0",
  "id": 1,
  "result": null
}


[Trace - 10:51:05 AM] Received notification '$/progress'.
Params: {
  "token": "5577006791947779410",
  "value": {
    "kind": "begin",
    "title": "Setting up workspace",
    "message": "Loading packages..."
  }
}


[Trace - 10:51:05 AM] Received request 'workspace/configuration - (2).
Params: {
  "items": [
    {
      "scopeUri": "file:///Users/muir/scratch/foo",
      "section": "gopls"
    }
  ]
}


[Trace - 10:51:05 AM] Sending response 'workspace/configuration - (2)'. Processing request took 0ms
Params: {
  "jsonrpc": "2.0",
  "id": 2,
  "result": [
    {
      "completeUnimported": true,
      "gofumpt": true,
      "completionDocumentation": false,
      "staticcheck": true,
      "verboseOutput": false,
      "linksInHover": false,
      "hoverKind": "SynopsisDocumentation",
      "allExperiments": true,
      "diagnosticsDelay": "10s",
      "semanticTokens": true,
      "codelenses": {
        "gc_details": false,
        "test": false
      },
      "analyses": {
        "ST1000": false,
        "ST1003": false,
        "ST1016": false,
        "ST1021": false,
        "SA5011": false,
        "ST1020": false,
        "unusedparams": false
      },
      "usePlaceholders": true,
      "buildFlags": [],
      "linkTarget": "pkg.go.dev",
      "local": "",
      "directoryFilters": [],
      "importShortcut": "Both",
      "symbolMatcher": "Fuzzy",
      "symbolStyle": "Dynamic"
    }
  ]
}
```
</summary>