As far as I can tell, the language server protocol and the debug adapter protocol are compatible in how they work. Thus, in my head it felt like a good idea to add some "is_debugging_supported" request, which asks the language server if it also has debugging capabilities. If yes, communication via DAP is also supported, if no, well, one has to find another debug adapter.
By that, reusing the same connection was made easy and some information shall be provided by both, the debug adapter as well as the language server (like goto definition). And thus merging the forces on the server side might be clever anyway.
By that the protocols stay independent but the servers can be implemented with a similar codebase where possible (Mostly scripting languages). The fact that DAP is managed via "capabilities" can even offer a very capable feeling when working with these protocols in combination.
On the client, side when there is support for both, debugging as well as "smart features", both usually are in the same codebase. Thus, it would work here too.
How many language servers are also debuggers? (there's jdt.ls with the wonky java debugger plugin I suppose)
jdt.ls doesn't ship the Java debug adapter. They are separate projects.
I know. But they run at least in the same server. Which is the closest thing I could think of that related to the original request. I鈥檓 not aware of any others.
But they run at least in the same server.
What do you mean by that?
PowerShellEditorServices ships debug adapter and language server in same executable.
// cc @TylerLeonhardt
But they run at least in the same server.
What do you mean by that?
the java debugger is a plugin that is loaded by jdt.ls at runtime. they run in the same process, and are distinct only in packaging. the java debugger is 'started' by sending a command to jdt.ls.
My whole point is that I don't imagine this feature request is likely to move the needle on functionality for the vast number of language servers. I could only think of that one where there is any overlap (as the author of both a language server client and a separate debug adapter protocol client).
So my question was about how many there really are and so how useful this "feature" would really be.
For Julia there is such overlap:
https://github.com/julia-vscode/LanguageServer.jl
https://github.com/julia-vscode/DebugAdapter.jl
Though, currently it is quiet around the latter one.
Yes, for PowerShell we share a bunch of state between the language server side and debug adapter side (it makes for a nice PowerShell experience) and have to ship a bridge in the vscode-powershell extension side to forward stdio messages to the named pipe/unix domain socket that we use for the debug adapter.
@weinand FYI.
@rapus95 yes, for some languages debug adapters and language servers share the same underlying implementation. A good example is Java where DAP and LSP is implemented in one process (but via two independent communication channels).
But I do not see a value in supporting an "is_debugging_supported" request in LSP.
From the VS Code perspective LSP is an implementation detail of a language extension. VS Code knows nothing about LSP because it only talks to VS Code's extension API. So VS Code would not be able to send a "is_debugging_supported" request to the LSP. So the only code that could use the "is_debugging_supported" request is the language extension itself (because it knows that it is using a language server). But this code should also "know" that LSP and DAP are implemented as one component. There is no need to use an "introspection" request for that.
@weinand
From the VS Code perspective LSP is an implementation detail of a language extension.
This may be true, but as an extension author, I don't manually send a completions request when the user types in the editor and I think this is what the OP meant by "vscode should support". I would expect that as a language extension author, I would not be responsible for sending the DAP messages in my extension code and instead, expect some piece of vscode to send the messages for me over the language client.
But this code should also "know" that LSP and DAP are implemented as one component.
Don't you still need to tell the language server that this extension/editor supports handling of DAP messages over the LSP channel so that the language server sets itself up properly? I could see this as a dynamic registration.
@TylerLeonhardt
as a language extension author you are of course not responsible for sending DAP requests (because VS Code does this for you), but you still have to tell VS Code where the DAP implementation lives (by contributing a DAP provider in your extension). Just having a "is_debugging_supported" on the LSP doesn't help, because VS Code knows nothing about LSP.
Lets assume that the LSP protocol would have the "debugging-supported" command. How could VS Code make use of that? It could not call it directly because VS Code knows nothing about LSP.
Only if this "debugging-supported" command is surfaced through some official extension API could VS Code make use of it.
And this API exists and is called DebugAdapterDescriptorFactory. And there is even a dynamic registry for it.
Implementing this DebugAdapterDescriptorFactory is simple: if an extension author knows that the language server implements the DAP, the factory could just open another DAP-channel to the language server.
@rapus95 correct me if I'm wrong but I think the feature request is to reuse that same channel?
But @weinand I'm a bit confused, if VSCode doesn't know anything about LSP, how does VSCode request data for CodeLens, Reference, Completions, etc from a language server?
I think the feature request on the vscode side would be to allow the ability for those DAP messages to follow the same path as those?
@TylerLeonhardt The vscode-languageclient npm module takes care of hooking things up. When The module hooks up a completion provider with VSCode so when VSCode asks for completions it'll ask the npm module for that, the module that fires off a request to the language server and sends the results back to VSCode (after converting them from LSP types to VSCode types) asynchronously (but generally it is fast enough that it feels instantaneous).
Technically the core of VS Code does not know anything about the interfaces and messages defined in the LSP. However, since vscode-languageclient is bundled with VSCode you could somewhat argue VS Code does speak LSP...
@TylerLeonhardt
@rcjsuen the "vscode-languageclient" is not bundled with VS Code. And neither is the corresponding DAP support library "vscode-debugadapter-node".
Many LSPs and DAPs are implemented in different languages where no support libraries exists.
@weinand Apologies for the incorrect statement. I noticed it mentioned in the extensions/json-language-features/package.json file so I assumed it was included in a vanilla installation of VS Code given that VS Code comes with JSON editing features by default.
Yes, VS Code ships with these libraries because some extensions use them (as an implementation detail). But still VS Code only uses this VS Code Extension API when talking to extensions. There are no side channels (e.g. no access to LSP).
@weinand
for historical reasons LSP and DAP do not use the same protocol.
Yes I've felt this helping the folks over in Omnisharp's csharp-lsp implementation. I understand why this wouldn't be straightforward. I'll let @rapus95 chime in, but I think the ask is for DAP messages over LSP which I would take advantage of if it were available but understand if it's not a priority.
And this API exists and is called DebugAdapterDescriptorFactory. And there is even a dynamic registry for it.
AFAIK, this is good for:
in the PowerShell case, we use a named pipe/unix domain socket so unfortunately, I don't think this gets rid of our stdio bridge. Would you accept an issue opened to allow DebugAdapterDescriptorFactory to accept a net.Socket as the stream used to send messages to/from the server? That's basically what we're using in the bridge.
If you think this is a reasonable feature request, which repo should I open the request on?
In case you were wondering, we use a named pipe/unix domain socket for our language server because it was easier to secure than a raw TCP port.
Whatever you do, please continue to make sure that DAP and LSP are separate and independently supported. For example, vimspector should be able to use the powershell debug adapter with no client side code.
@puremourning the PowerShell language server and debug adapter have been in the same executable/process for years! That said, it can be run in "DAP only mode or LSP only mode"...
I see you're the maintainer of vimspector. I'm a maintainer of https://github.com/coc-extensions/coc-powershell which is the LSP side in vim. I'd love to talk to you about hooking up the PowerShell Editor Services instance that's already running in that with vimspector so we have a complete editing and debugging experience for PowerShell in vim. Maybe I open an issue in vimspector and we chat there?
Sure let鈥檚 talk about vimspector in the vimspector repo. But note I鈥檓 also maintainer of YCM so I have little interest in coc.vim ;)
Sounds good. @weinand let me know if you want that issue opened somewhere. Named Pipes/unix domain sockets are a great alternative to TCP as they are easy to lock down and are perfect considering the language server and the client are both on the same file system
Extra bonus that node's net.connect API works with both host/port and named pipes.
Hmm I I found it appealing that DAP has that "capabilities" feature which theoretically could implement a "further introspection capabilities" flag which itself just states whether the full LSP is supported. And since from the other side (LSP) that was missing I wanted to ask, as LSP somewhat feels like the more common protocol. But as DAP seems to be the more powerful protocol in regards of providing all-in-one support, maybe switching to DAP as the core plugin for the all-in-one product might make sense. That's my understanding of it right now. Correct me where I'm wrong.
@rapus95 LSP and DAP are independent protocols. They do not use the same underlying messaging technology (JSON RPC vs. V8) and they do not share any types that can be used to cross-relate semantics between the two protocols.
So connecting the protocols on the specification level would be purely artificial and not driven by any real use case.
All existing VS Code language and debugger extensions were able to combine LSP and DAP as needed in their implementation and there was never a feature request to connect them on the spec level.
So I do not understand what you mean by your statement "DAP seems to be the more powerful protocol in regards of providing all-in-one support".
@TylerLeonhardt please feel free to create a concrete feature request in the VS Code repo.
Most helpful comment
PowerShellEditorServices ships debug adapter and language server in same executable.
// cc @TylerLeonhardt