Windows file uri encoding issues
Hi,
For some time I've been working to enable running roslyn c# lsp using monaco-languageclient on Windows OS. Unfortunately, roslyn lsp does not work without files being physically on disc for restore of projects, so using in-memory files only is out of the question. Specifically, it needs Windows paths for workspace folders/files.
I managed to get it working with all the features I need (btw. this library is absolutely awesome!), but I had to write backend proxy that fixes encoding of uris that monaco-languageclient sends to lsp.
From my investigation, it comes down to two issues in monaco-languageclient:
- Following code throws error:
const defaultFilesystemProvider = new RegisteredFileSystemProvider(false);
const fileUri = vscode.Uri.file("C:\\temp\\file.cs");
defaultFilesystemProvider.registerFile(new RegisteredMemoryFile(fileUri, ""));
files.js:98 Uncaught (in promise) EntryNotFound (FileSystemError): file not found
at _FileSystemProviderError.create (files.js:98:33)
at createFileSystemProviderError (files.js:108:36)
at RegisteredFileSystemProvider._lookup (index.js:267:27)
at RegisteredFileSystemProvider._lookupAsDirectory (index.js:278:28)
at RegisteredFileSystemProvider.mkdirSync (index.js:416:29)
at RegisteredFileSystemProvider.registerFile (index.js:302:43)
This I could overcome by patching the code myself. I changed RegisteredFileSystemProvider to work with Windows paths correctly, but the code is based on regex with drive letters and I'm not confident 100% correct.
- After patching the file provider, both workspace initalization and
createModelReferencewere throwing warnings and errors:
const workspaceUri = vscode.Uri.file('/workspace.code-workspace');
function generateAndInitializeWorkspace(): IWorkspaceProvider {
defaultFilesystemProvider.registerFile(new RegisteredMemoryFile(
workspaceUri,
JSON.stringify(<IStoredWorkspace>{
workspaceUri,
folders: [
{
path: "C:\\temp"
}
]
})))
return <IWorkspaceProvider>{
open: async () => false,
workspace: <Partial<IWorkspace>>{
workspaceUri,
label: "My Workspace"
},
trusted: true
}
}
const modelRef = await monaco.editor.createModelReference(fileUri)
(please don't mind different paths than in code above, I only have screenshot from reproduction)
At this point I gave up and used proxy to translate /c/temp/path.cs -> c:\\temp\\path.cs on the fly before it touches my LSP, this resolved the issues. Sorry there is no easy reproduction steps - hosting c# lsp is quite involved currently.
For completness, here is my service initialization code:
// adding services
await initialize({
...getTextMateServiceOverride(),
...getThemeServiceOverride(),
...getLanguagesServiceOverride(),
...getConfigurationServiceOverride(),
...getKeybindingsServiceOverride(),
...getModelServiceOverride(),
...getEditorServiceOverride(async (modelRef) => {
const editor = monaco.editor.getEditors()[0]
if (!editor) {
return undefined
}
editor.setModel(modelRef.object.textEditorModel)
return editor
})
}, undefined, { workspaceProvider: generateAndInitializeWorkspace() });