From 1e40002cdc7f298471bcd59d33729541f6478a3a Mon Sep 17 00:00:00 2001
From: Ben Sherman <bentshermann@gmail.com>
Date: Fri, 13 Dec 2024 21:50:36 -0600
Subject: [PATCH 1/2] Download language server on startup

Signed-off-by: Ben Sherman <bentshermann@gmail.com>
---
 esbuild.js        |  1 -
 package-lock.json |  8 ++++++++
 package.json      | 11 ++++++++++-
 src/extension.ts  | 22 ++++++++++++++++------
 4 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/esbuild.js b/esbuild.js
index 22dd639..c890576 100644
--- a/esbuild.js
+++ b/esbuild.js
@@ -13,7 +13,6 @@ async function main() {
     'README.md': './README.md',
     'language-configuration.json': './language-configuration.json',
     'package.json': './package.json',
-    'language-server/build/libs/language-server-all.jar': 'bin',
     'node_modules/mermaid/dist/mermaid.min.js': 'media',
   };
   await build({
diff --git a/package-lock.json b/package-lock.json
index 731e6ee..7c602f2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
             "name": "nextflow",
             "version": "1.0.2",
             "devDependencies": {
+                "@microsoft/vscode-file-downloader-api": "^1.0.1",
                 "@types/node": "^20",
                 "@types/vscode": "^1.73.1",
                 "@vscode/vsce": "^3.2.1",
@@ -335,6 +336,13 @@
                 "langium": "3.0.0"
             }
         },
+        "node_modules/@microsoft/vscode-file-downloader-api": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/@microsoft/vscode-file-downloader-api/-/vscode-file-downloader-api-1.0.1.tgz",
+            "integrity": "sha512-cO9n/IpTMbXizz5YcEkiuRyX5r66SBY/3LnrlroyXbQXrgDdaKecfV3n4viTcvp9O//QF2AxcBfDZex2d4VSTg==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/@nodelib/fs.scandir": {
             "version": "2.1.5",
             "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
diff --git a/package.json b/package.json
index f861bdb..99b7ad3 100644
--- a/package.json
+++ b/package.json
@@ -144,6 +144,11 @@
                     "type": "boolean",
                     "default": false,
                     "description": "Enable additional warnings for things like future deprecations, discouraged patterns, and so on."
+                },
+                "nextflow.targetVersion": {
+                    "type": "string",
+                    "default": null,
+                    "markdownDescription": "Target version of Nextflow to be used by the language server."
                 }
             }
         }
@@ -154,6 +159,7 @@
         "package": "npm run check-types && node esbuild.js --production && (cd build ; vsce package -o nextflow.vsix)"
     },
     "devDependencies": {
+        "@microsoft/vscode-file-downloader-api": "^1.0.1",
         "@types/node": "^20",
         "@types/vscode": "^1.73.1",
         "@vscode/vsce": "^3.2.1",
@@ -163,5 +169,8 @@
         "typescript": "^5.7.2",
         "vscode-jsonrpc": "^8.0.2",
         "vscode-languageclient": "^8.0.2"
-    }
+    },
+    "extensionDependencies": [
+        "mindaro-dev.file-downloader"
+    ]
 }
diff --git a/src/extension.ts b/src/extension.ts
index 0187d1d..9d4f9d8 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -1,7 +1,7 @@
 import buildMermaid from "./utils/buildMermaid";
 import findJava from "./utils/findJava";
-import * as path from "path";
 import * as vscode from "vscode";
+import { getApi } from "@microsoft/vscode-file-downloader-api";
 import {
   LanguageClient,
   LanguageClientOptions,
@@ -13,6 +13,10 @@ let extensionContext: vscode.ExtensionContext | null = null;
 let languageClient: LanguageClient | null = null;
 let javaPath: string | null = null;
 
+function getDefaultVersion() {
+  return "1.0.3";
+}
+
 function startLanguageServer() {
   vscode.window.withProgress(
     { location: vscode.ProgressLocation.Window },
@@ -35,6 +39,16 @@ function startLanguageServer() {
           }
           return;
         }
+        progress.report({ message: "Downloading Nextflow language server..." });
+        const version = vscode.workspace
+          .getConfiguration("nextflow")
+          .get("targetVersion") as string ?? getDefaultVersion();
+        const fileDownloader = await getApi();
+        const serverUri = await fileDownloader.downloadFile(
+          vscode.Uri.parse(`https://github.com/nextflow-io/language-server/releases/download/v${version}/language-server-all.jar`),
+          "language-server-all.jar",
+          extensionContext
+        );
         progress.report({ message: "Initializing Nextflow language server..." });
         let clientOptions: LanguageClientOptions = {
           documentSelector: [
@@ -59,11 +73,7 @@ function startLanguageServer() {
         };
         let args = [
           "-jar",
-          path.resolve(
-            extensionContext.extensionPath,
-            "bin",
-            "language-server-all.jar"
-          ),
+          serverUri.fsPath,
         ];
         // uncomment to allow a debugger to attach to the language server
         // args.unshift("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005,quiet=y");

From 9f7cf0d3342cf3b9067698de3241997774872786 Mon Sep 17 00:00:00 2001
From: Ben Sherman <bentshermann@gmail.com>
Date: Fri, 13 Dec 2024 22:08:37 -0600
Subject: [PATCH 2/2] Use local build of language server in dev mode

Signed-off-by: Ben Sherman <bentshermann@gmail.com>
---
 esbuild.js       |  2 ++
 src/extension.ts | 45 ++++++++++++++++++++++++++++++++++-----------
 2 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/esbuild.js b/esbuild.js
index c890576..02fc0fa 100644
--- a/esbuild.js
+++ b/esbuild.js
@@ -15,6 +15,8 @@ async function main() {
     'package.json': './package.json',
     'node_modules/mermaid/dist/mermaid.min.js': 'media',
   };
+  if( !production )
+      files['language-server/build/libs/language-server-all.jar'] = 'bin'
   await build({
     entryPoints: [
       'src/extension.ts'
diff --git a/src/extension.ts b/src/extension.ts
index 9d4f9d8..6b6d648 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -1,5 +1,7 @@
 import buildMermaid from "./utils/buildMermaid";
 import findJava from "./utils/findJava";
+import * as fs from 'fs';
+import * as path from "path";
 import * as vscode from "vscode";
 import { getApi } from "@microsoft/vscode-file-downloader-api";
 import {
@@ -17,6 +19,31 @@ function getDefaultVersion() {
   return "1.0.3";
 }
 
+async function getLanguageServerPath() {
+  if (!extensionContext) {
+    return null;
+  }
+  const devPath = path.resolve(
+    extensionContext.extensionPath,
+    "bin",
+    "language-server-all.jar"
+  );
+  if( fs.existsSync(devPath) ) {
+    vscode.window.showInformationMessage("Using local build of language server.");
+    return devPath;
+  }
+  const version = vscode.workspace
+    .getConfiguration("nextflow")
+    .get("targetVersion") as string ?? getDefaultVersion();
+  const fileDownloader = await getApi();
+  const serverUri = await fileDownloader.downloadFile(
+    vscode.Uri.parse(`https://github.com/nextflow-io/language-server/releases/download/v${version}/language-server-all.jar`),
+    "language-server-all.jar",
+    extensionContext
+  );
+  return serverUri.fsPath;
+}
+
 function startLanguageServer() {
   vscode.window.withProgress(
     { location: vscode.ProgressLocation.Window },
@@ -39,16 +66,6 @@ function startLanguageServer() {
           }
           return;
         }
-        progress.report({ message: "Downloading Nextflow language server..." });
-        const version = vscode.workspace
-          .getConfiguration("nextflow")
-          .get("targetVersion") as string ?? getDefaultVersion();
-        const fileDownloader = await getApi();
-        const serverUri = await fileDownloader.downloadFile(
-          vscode.Uri.parse(`https://github.com/nextflow-io/language-server/releases/download/v${version}/language-server-all.jar`),
-          "language-server-all.jar",
-          extensionContext
-        );
         progress.report({ message: "Initializing Nextflow language server..." });
         let clientOptions: LanguageClientOptions = {
           documentSelector: [
@@ -71,9 +88,15 @@ function startLanguageServer() {
             protocol2Code: (value) => vscode.Uri.parse(value),
           },
         };
+        let serverPath = await getLanguageServerPath();
+        if (!serverPath) {
+          resolve();
+          vscode.window.showErrorMessage("Failed to retrieve language server.");
+          return;
+        }
         let args = [
           "-jar",
-          serverUri.fsPath,
+          serverPath,
         ];
         // uncomment to allow a debugger to attach to the language server
         // args.unshift("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005,quiet=y");