bscan / PerlNavigator

Perl Language Server that includes syntax checking, perl critic, and code navigation
MIT License
207 stars 39 forks source link

Please add fallback on rootUri/rootPath when missing workspaceFolders capability [PoC patch attached] #146

Open nospam2998 opened 1 month ago

nospam2998 commented 1 month ago

According to language server specification for clients not announcing the workspaceFolders capability the server should fallback. Primarily to rootUri, and further to rootPath when needed.

I have pushed the workaround in the patch below to git.netizen.se. Attempting to fix this properly seems a bit too challenging to me, never ever having seen typescript code prior to today.

Please consider cleaning-up and including this, or re-implementing as you see fit:

From 7505ee134320457269f3376de8eae978ad6acb2a Mon Sep 17 00:00:00 2001
From: cos <cos>
Date: Tue, 15 Oct 2024 17:01:32 +0200
Subject: [PATCH] Workaround broken workspaceFolders capability handling

According to [language server specification][spec] clients not
announcing the workspaceFolders capability should fallback. Primarily to
rootUri, and further to rootPath when needed.

This commit works around the buggy behaviour with vim-ale. Since I have
never ever seen typescript code prior to today, attempting to fix this
properly seems a bit too challenging for me.

[spec]: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/
---
 server/src/server.ts | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/server/src/server.ts b/server/src/server.ts
index de62214..4be7e27 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -51,6 +51,7 @@ const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);

 let hasConfigurationCapability = false;
 let hasWorkspaceFolderCapability = false;
+let rootUri = '';

 connection.onInitialize(async (params: InitializeParams) => {
     const capabilities = params.capabilities;
@@ -87,6 +88,11 @@ connection.onInitialize(async (params: InitializeParams) => {
                 supported: true,
             },
         };
+    } else {
+        process.stderr.write("No hasWorkspaceFolderCapability in onInitialize().\n");
+        if (params.rootUri!=null) {
+            rootUri = params.rootUri;
+        }
     }
     await getPerlAssetsPath(); // Ensures assets are unpacked. Should this be in onInitialized?
     return result;
@@ -183,15 +189,30 @@ async function dispatchForMods(textDocument: TextDocument) {
 }

 async function getWorkspaceFoldersSafe(): Promise<WorkspaceFolder[]> {
-    try {
-        const workspaceFolders = await connection.workspace.getWorkspaceFolders();
-        if (!workspaceFolders) {
+    process.stderr.write("Now in getWorkspaceFoldersSafe().\n");
+    if (hasWorkspaceFolderCapability) {
+        process.stderr.write("getWorkspaceFoldersSafe() has hasWorkspaceFolderCapability.\n");
+        try {
+            const workspaceFolders = await connection.workspace.getWorkspaceFolders();
+            if (!workspaceFolders) {
+                return [];
+            } else {
+                return workspaceFolders;
+            }
+        } catch (error) {
             return [];
+        }
+    } else {
+        process.stderr.write("No hasWorkspaceFolderCapability in getWorkspaceFoldersSafe() .\n");
+        if (rootUri!=null) {
+            const dummyFolder: WorkspaceFolder = {
+                    uri: rootUri,
+                    name: rootUri,
+            }
+            return [dummyFolder];
         } else {
-            return workspaceFolders;
+            return [];
         }
-    } catch (error) {
-        return [];
     }
 }

-- 
2.45.2

P.S. It would be appreciated if there was at least one more open contact channel to reach this project, outside of the three walled gardens listed.