Applying Edits/Undo Stack - GLSP/Langium Integration - VSCode Extension/Node Server #1519
-
Hey there, Context: We've built a VSCode extension that uses Langium documents as the source model for GLSP diagrams. Up until recently our GLSP server was separate from the Language Server in Langium and running in the extension process with access to the VSCode API. In order to integrate Langium and GLSP better we moved the GLSP server out into it's own process using the socket launcher and this gets triggered after the language server does. Resulting in our GLSP server being able to access SharedServices etc. This also removes access to the VSCode API. After doing this however we've ran into one main issue in regards to editing the Langium document. Previously, because we had access to the VSCode API, we could simply perform a vscode.workspace.applyEdit from the server side node creation handler and this would apply the edit and sync in fine with the undo/redo stack. Now what happens is that we have to trigger an applyEdit from the server side that gets sent back up to the language client and that applies it. Unfortunately this has broken the synchronization with the undo stack, essentially resulting in us having to hit undo twice (once for GLSP and then once for Langium). In an attempt to fix this, we disabled undo for GLSP operations that only affect the Langium document (i.e. node creation/deletion etc.), which sort of worked, however if you move a node and then add a new node, because the applyEdit from the server isn't directly coming from the diagram editor the move is actually first in the undo stack, which results in it undoing the move before undoing the node creation. I even tried triggering the applyEdit from the GLSPVCodeConnector.handleSetDirtyStateAction, but unfortunately the move still receives priority over the edit that happens after it. Question/Conclusion: I'm starting to get the impression that this is due to CustomEditors vs CustomTextEditors, and because the text document and the diagram editor are different that trying to get things to sync up just isn't playing nicely with VSCode. My next rabbit hole essentially, is looking into whether I can convert the GLSP editor over to a CustomTextEditor and then find a way to ensure that operations that do not directly modify the document can still be undone. I know a few contributors here also contribute to the crossmodel project that uses Langium/GLSP (though I believe it uses the Theia GLSP integration for the frontend instead of VSCode so might not suffer from the exact same problems), so I was wondering if anyone had any insights into this? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 7 replies
-
Hi @jmenzies12, I don't have too much insights into the difference between CustomEditors vs CustomTextEditors, maybe @tortmayr can shed some light on this. I could imagine, however, that does indeed make a difference. In CrossModel, we currently send full updates to the Langium language server by having a custom command structure that 1:
Doing this should ensure that we are working on the same semantic models from Langium and make sure that GLSP is aware of any changes in Langium as well. I also had a quick look at what the VS Code API does when you do a Could you explain a bit more how you were syncing the GLSP server with Langium before? I'm not sure I fully grasp your approach. Nevertheless, it seems you experience some issues with the new approach. It would be interesting, where those issues come from. However, you could try to mimic the old behavior by introducing a custom request to communicate between the language server connection and the VS Code extension. A good location for this would be when you launch your language client. For instance, in CrossModel, we register a command to report the port of the GLSP server using the VS Code API 7. Using a similar approach you can set up the reverse, e.g., something along the lines of: I hope this will help you out in some way. Footnotes
|
Beta Was this translation helpful? Give feedback.
-
I don't think it makes much of a difference in practice. When using a |
Beta Was this translation helpful? Give feedback.
@martin-fleck-at,
Just a quick update, incase you or anyone else is curious.
I spent more time on it and came up with a better solution (this removes the need for delaying the applyEdit and confusion of having conflicting operations at once):