microsoft / vscode-dotnettools

This is a feedback repository to capture issues logged for the C# Dev Kit and related extensions from Visual Studio Code
Other
221 stars 10 forks source link

Test C# IntelliSense in Copilot chat code blocks #1361

Open mjbvz opened 1 month ago

mjbvz commented 1 month ago

VS Code recently enabled intellisense in copilot chat code blocks. Although this is mostly implemented in a language agnostic way, language extensions may need to make some changes to get the best support

For this exploration, I'd like your team's help testing out C# IntelliSense in copilot chat code blocks. I've provided a list of ideas on what to test below, however feel free to build on it. I've gone through them for JS/TS and found them to be a good starting point. You can also file feature request against VS Code for new feature ideas

Areas to test

AbhitejJohn commented 3 weeks ago

Tagging @arkalyanms on this ask.

dibarbet commented 1 week ago

Notes from suggested scenarios

  1. C# LSP server gets requests for vscode-chat-code-block documents. These documents get added to the misc workspace
  2. Syntax features appear to work (textmate).
  3. Diagnostics are not reported for code in the chat window
  4. Hovers and go to definition work for code that is defined in the same copilot chat block. It does not work for mscorlib library code or code defined outside the chat block (e.g. in the workspace). This is because the file is added to the miscellaneous workspace which has no references to outside code. mscorlib definitions require https://github.com/dotnet/vscode-csharp/issues/5729 copilot_def
  5. Cross chat block references do not work. Likely a limitation of the C# misc files workspace again.
  6. Copilot chat blocks populated with @workspace contents work (the requests execute on the underlying document URI which goes to the main workspace).
  7. Code in copilot blocks is not picked up as references (separate workspace contexts).
  8. Same for symbol search (it does not search the workspace that copilot chat blocks are in).

Additional testing notes

  1. Semantic classification is not working for chat blocks (not from workspace). Semantic classification requests are being made for the chat window, but similar to hover/gtd we have no references for the file.
  2. Semantic classification for parts of the @workspace blocks is not working. Requests are being made, but they're given a special URI that we don't know how to map to anything
    "uri": "vscode-chat-code-block://d0fa33c0-7600-4ec0-8c04-a34236adf0b6/response_9/0#{\"references\":[{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\.vscode\\\\tasks_old.json\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/.vscode/tasks_old.json\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/.vscode/tasks_old.json\",\"scheme\":\"file\"},\"range\":{\"startLineNumber\":1,\"startColumn\":1,\"endLineNumber\":19,\"endColumn\":2}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\BinarySearch.cs\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/BinarySearch.cs\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/BinarySearch.cs\",\"scheme\":\"file\"}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\ConsoleAppNet9.csproj\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/ConsoleAppNet9.csproj\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/ConsoleAppNet9.csproj\",\"scheme\":\"file\"},\"range\":{\"startLineNumber\":1,\"startColumn\":1,\"endLineNumber\":10,\"endColumn\":11}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\obj\\\\ConsoleAppNet9.csproj.nuget.g.targets\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/obj/ConsoleAppNet9.csproj.nuget.g.targets\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/obj/ConsoleAppNet9.csproj.nuget.g.targets\",\"scheme\":\"file\"},\"range\":{\"startLineNumber\":1,\"startColumn\":1,\"endLineNumber\":2,\"endColumn\":92}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\obj\\\\Debug\\\\net9.0\\\\ConsoleAppNet9.AssemblyInfoInputs.cache\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.AssemblyInfoInputs.cache\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.AssemblyInfoInputs.cache\",\"scheme\":\"file\"},\"range\":{\"startLineNumber\":1,\"startColumn\":1,\"endLineNumber\":1,\"endColumn\":65}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\obj\\\\Debug\\\\net9.0\\\\ConsoleAppNet9.csproj.CoreCompileInputs.cache\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.csproj.CoreCompileInputs.cache\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.csproj.CoreCompileInputs.cache\",\"scheme\":\"file\"},\"range\":{\"startLineNumber\":1,\"startColumn\":1,\"endLineNumber\":1,\"endColumn\":65}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\obj\\\\Debug\\\\net9.0\\\\ConsoleAppNet9.csproj.FileListAbsolute.txt\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.csproj.FileListAbsolute.txt\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.csproj.FileListAbsolute.txt\",\"scheme\":\"file\"},\"range\":{\"startLineNumber\":1,\"startColumn\":1,\"endLineNumber\":14,\"endColumn\":86}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\obj\\\\Debug\\\\net9.0\\\\ConsoleAppNet9.GlobalUsings.g.cs\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.GlobalUsings.g.cs\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.GlobalUsings.g.cs\",\"scheme\":\"file\"}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\Program.cs\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/Program.cs\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/Program.cs\",\"scheme\":\"file\"}}]}"
  3. Inlay hints are not requested for chat blocks
  4. Code lenses are not requested for chat blocks
  5. No sticky scroll
  6. No folding ranges in chat windows

Summary of potential improvements

  1. We need to figure out how to provide mscorlib references to copilot chat blocks. See https://github.com/dotnet/vscode-csharp/issues/5729 (L/M)
  2. We need to figure out a way to provide workspace context for chat window blocks (L/M) - https://github.com/dotnet/vscode-csharp/issues/7517 a. What is the project context for the copilot chat block? Should it be in a special project that references every project in the sln? Should it be part of a particular project in the sln? Should it have other package references as well? etc
  3. We need to figure out how to have cross-block references (M)
  4. Might need to handle @workspace context requests (see below with the chat window URI but references to all classes).

VSCode requests

(cc @mjbvz )

  1. The completion window showing up every time I type c# is annoying. It is the worst when the c# word is the last thing to type, as hitting enter will autocomplete the suggestion, instead of submitting the request to copilot. copilot_completion_csharp
  2. Is it possible to enable the Inspect Editor Tokens and Scopes command for chat window code blocks? Would be useful to see the classifications.
  3. Should the semantic tokens requests be using the regular underlying document URI for @workspace requests? Instead of what appears to be a special vscode-chat-code-block uri with extra references? Similar to how the hover/gtd requests work? Sample JSON
    [Trace - 1:47:01 PM] Sending request 'textDocument/semanticTokens/range - (53)'.
    Params: {
    "textDocument": {
        "uri": "vscode-chat-code-block://d0fa33c0-7600-4ec0-8c04-a34236adf0b6/response_11/0#{\"references\":[{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\.vscode\\\\tasks_old.json\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/.vscode/tasks_old.json\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/.vscode/tasks_old.json\",\"scheme\":\"file\"},\"range\":{\"startLineNumber\":1,\"startColumn\":1,\"endLineNumber\":19,\"endColumn\":2}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\BinarySearch.cs\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/BinarySearch.cs\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/BinarySearch.cs\",\"scheme\":\"file\"}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\ConsoleAppNet9.csproj\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/ConsoleAppNet9.csproj\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/ConsoleAppNet9.csproj\",\"scheme\":\"file\"},\"range\":{\"startLineNumber\":1,\"startColumn\":1,\"endLineNumber\":10,\"endColumn\":11}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\obj\\\\ConsoleAppNet9.csproj.nuget.g.targets\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/obj/ConsoleAppNet9.csproj.nuget.g.targets\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/obj/ConsoleAppNet9.csproj.nuget.g.targets\",\"scheme\":\"file\"},\"range\":{\"startLineNumber\":1,\"startColumn\":1,\"endLineNumber\":2,\"endColumn\":92}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\obj\\\\Debug\\\\net9.0\\\\ConsoleAppNet9.AssemblyInfoInputs.cache\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.AssemblyInfoInputs.cache\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.AssemblyInfoInputs.cache\",\"scheme\":\"file\"},\"range\":{\"startLineNumber\":1,\"startColumn\":1,\"endLineNumber\":1,\"endColumn\":65}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\obj\\\\Debug\\\\net9.0\\\\ConsoleAppNet9.csproj.CoreCompileInputs.cache\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.csproj.CoreCompileInputs.cache\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.csproj.CoreCompileInputs.cache\",\"scheme\":\"file\"},\"range\":{\"startLineNumber\":1,\"startColumn\":1,\"endLineNumber\":1,\"endColumn\":65}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\obj\\\\Debug\\\\net9.0\\\\ConsoleAppNet9.csproj.FileListAbsolute.txt\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.csproj.FileListAbsolute.txt\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.csproj.FileListAbsolute.txt\",\"scheme\":\"file\"},\"range\":{\"startLineNumber\":1,\"startColumn\":1,\"endLineNumber\":14,\"endColumn\":86}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\obj\\\\Debug\\\\net9.0\\\\ConsoleAppNet9.GlobalUsings.g.cs\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.GlobalUsings.g.cs\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/obj/Debug/net9.0/ConsoleAppNet9.GlobalUsings.g.cs\",\"scheme\":\"file\"}},{\"uri\":{\"$mid\":1,\"fsPath\":\"c:\\\\Users\\\\dabarbet\\\\source\\\\repos\\\\ConsoleAppNet9\\\\Program.cs\",\"_sep\":1,\"external\":\"file:///c%3A/Users/dabarbet/source/repos/ConsoleAppNet9/Program.cs\",\"path\":\"/c:/Users/dabarbet/source/repos/ConsoleAppNet9/Program.cs\",\"scheme\":\"file\"}}]}"
    },
    "range": {
        "start": {
            "line": 0,
            "character": 0
        },
        "end": {
            "line": 43,
            "character": 1
        }
    }
    }
  4. Should inlay hints be requested for chat blocks as well? I found no evidence in the LSP logs that inlay hints were ever requested for chat blocks.
  5. Should codelenses be requested for chat blocks. Also found no evidence of them being requested by the client.
  6. Is sticky scroll worth adding for chat blocks (could be useful for longer ones to show the context)?
  7. Same as above for folding ranges
mjbvz commented 1 week ago

Thanks for testing! Sounds pretty good overall! Library intellisense is probably the top priority in terms of user impact

For the VS Code asks:

  1. Should already be fixed https://github.com/microsoft/vscode/issues/216757

  2. Opened https://github.com/microsoft/vscode/issues/227639

  3. This sounds expected. You should see the same vscode-chat-code-block doc used for hover and other requests too in the purely local cases

  4. Opened https://github.com/microsoft/vscode/issues/227640

  5. Opened https://github.com/microsoft/vscode/issues/227641. Less sure about this one as code lenses are visually more heavy weight

  6. Opened https://github.com/microsoft/vscode/issues/227644

  7. Opened https://github.com/microsoft/vscode/issues/227642

Feel free to open any additional issues directly against VS Code and ping me on them

dibarbet commented 1 week ago

Thanks!

This sounds expected. You should see the same vscode-chat-code-block doc used for hover and other requests too in the purely local cases

@mjbvz For this one - when the chat block was from a workspace file, for Go to def and hover I was getting LSP requests for the actual workspace document URI (not the vscode-chat-code-block). Whereas only the semantic tokens request had the vscode-chat-block URI instead of the workspace URI.

mjbvz commented 1 week ago

@dibarbet Is it possible your extension / language server hasn't registered to support that document scheme for hover/go to def?

I just confirmed that for JS/TS, the go to def requests go to vscode-chat-code-block (ignore the ^ at the start):

Image

What should happen on go to def:

  1. The language extension is asked for a local definition in the vscode-chat-code-block document

  2. If none is found, then we fall back to trying to resolve the symbol from the @workspace context. This is handled by copilot but may trigger a go to def request in one of the actual workspace files

dibarbet commented 1 week ago

@mjbvz ah you're correct - it was the fallback request that uses the document URI from the workspace (for go to def and hover). The request for the vscode-chat-code-block returned nothing for those features, so the fallback got called. That is why they were working.

It looks like semantic tokens doesn't do the same fallback request because we return tokens for the initial request (just incorrect ones). Apologies for the misunderstanding there. We'll have to figure out if we can answer the semantic tokens request on the original URI or if we should return nothing and allow the fallback to be invoked.