TypeFox / monaco-languageclient

Repo hosts npm packages for monaco-languageclient, vscode-ws-jsonrpc, monaco-editor-wrapper, @typefox/monaco-editor-react and monaco-languageclient-examples
https://www.npmjs.com/package/monaco-languageclient
MIT License
1.04k stars 178 forks source link

Creating files/directories within a java language server #731

Open Sin-Yone opened 3 weeks ago

Sin-Yone commented 3 weeks ago

Hi everyone, I have a question about the implementation using a Java language server (eclipse.jdt.ls). I followed the example to set up a Java language server with the Monaco editor. So I have a docker container running a server which then starts the java language server. Just like the example in this repo.

I am using the @typefox/monaco-editor-react package within next.js. The monaco client connects to the language server and works fine. However, I only get autocomplete if the file exists within the Java language server workspace in docker. This makes sense, otherwise the server can't know if the file exists or read content from it. So I created a sample file manually and I get autocompletion and all the other features. Now I want to dynamically create new files and folders from the client, which need to be created inside the language server workspace. But I am stuck and do not know how to do this. I have tried calling vscode.workspace.fs.createDirectory which does nothing. When I check vscode.workspace.workspaceFolders the array is empty. But shouldn't it be the workspace folder set in the user config that is parsed to the monaco editor react component? I have also tried fileSystemProvider.mkdirSync which also does nothing. I think I am confusing the concepts of file systems. As far as I understand, the filesystemprovider from @codingame/monaco-vscode-files-service-override is used for the editor to create a virtual filesystem. But how do I create files and directories on the server? I thought that was what the vscode.workspace api was for. I've been trying to figure this out for a few days now, but I haven't succeeded. So maybe someone could help me out.

Not a problem for this repo, but maybe someone can help me: I get the following warning image The first time the client connects to the language server, a `jdt.ls-java-project' is created. I guess it automatically created a java project. Do I need to put my files in there to get rid of the warning?

Since both of these are probably not an issue of this package, perhaps its better to turn this into a discussion.

Either way an awesome package and many thanks already :)

kaisalmen commented 3 weeks ago

@Sin-Yone this is a common problem and I am working on some kind of language server protocol extension/enhancement allowing to sync files (it is not visible yet / not yet ready for review). Even if you use something like vscode.workspace.openTextDocument there is no guarantee a language server handles this. Pyright for example does not. Usually vscode and the language server have access to the same file system. With monaco-languageclient this is not the case (same for LS connected over web socket or LS running as web worker). See also this discussion.

Your question is totally valid. But it is not really an issue of the library, but it is a new feature we need to make it easier to build applications. 👍

Sin-Yone commented 3 weeks ago

@kaisalmen Thanks for the quick reply. Is there any starting point for me to get started as I really need it right now for my masters thesis? The only way I can see now is to mount the workspace of the docker container with the project and then trigger a server action in next.js (basically an api call) and then create the files/folders in that workspace. Then they should be inside the docker container since its mounted. Or is there a better way?

Also, could you maybe clarify for me what exactly vscode.workspace.xxx does? What workspace does it access? The virtual filesystem I created via registerFileSystemOverlay? Or the workspace on the server? I'm kinda having a hard time understanding what exactly it does.

CGNonofr commented 3 weeks ago

By default, the accessible filesystem in the client is just a memory filesystem. But you are free to replace it by whatever you want, you can make your own file system provider implementation that remotely manipulate the server filesystem.

Then using vscode.workspace.fs will allow you to manipulate the server filesystem.

When I check vscode.workspace.workspaceFolders the array is empty.

Not a problem for this repo, but maybe someone can help me: I get the following warning image The first time the client connects to the language server, a `jdt.ls-java-project' is created. I guess it automatically created a java project. Do I need to put my files in there to get rid of the warning?

The 2 are probably related: you don't have any configured workspace folder

CGNonofr commented 3 weeks ago

Btw, another options is to use the VSCode server that, among others things, allows to access the remote filesystem, more info here: https://github.com/CodinGame/monaco-vscode-api/blob/main/docs/vscode_server.md (I'm not sure how it integrates with @typefox/monaco-editor-react though)

kaisalmen commented 3 weeks ago

The virtual filesystem I created via registerFileSystemOverlay?

That is on the client side and the server does not see that (at least as we do it in the examples here). vscode.workspace.openTextDocument tells the language server a new document is open at location xyz, but if the language server does not use this info, you have to somehow do yourself (for example like you suggested or you create your own FS provider to prevent the problem like @CGNonofr proposed above).

Btw, another options is to use the VSCode server that, among others things, allows to access the remote filesystem, more info here: https://github.com/CodinGame/monaco-vscode-api/blob/main/docs/vscode_server.md (I'm not sure how it integrates with @typefox/monaco-editor-react though)

This would remove the need for monaco-lanugageclient and would be possible to achieve with @typefox/monaco-editor-react, but require a bit of code taken/derived from the monaco-vscode-api demo. Also a new example we could integrate here.

Anyway, every possible solution requires extra real work and we don't have a readily available solution, yet.

Sin-Yone commented 3 weeks ago

@kaisalmen @CGNonofr Thanks both of you for the quick help. I'll look into it and see if I can get it working!