diff options
Diffstat (limited to 'Scripts')
| -rw-r--r-- | Scripts/main.js | 251 |
1 files changed, 158 insertions, 93 deletions
diff --git a/Scripts/main.js b/Scripts/main.js index bde902c..e3e175b 100644 --- a/Scripts/main.js +++ b/Scripts/main.js @@ -1,5 +1,7 @@ "use strict"; +// --- CONFIGURATION ----------------------------------------------------------- + const EXTENSION_ID = "at.dcz.nova-zig"; const TASK_ASSISTANT_ID = `${EXTENSION_ID}.tasks`; const LANGUAGE_CLIENT_ID = `${EXTENSION_ID}.zls`; @@ -18,6 +20,8 @@ const CONFIG_KEYS = { discoverSteps: `${EXTENSION_ID}.tasks.discover-steps`, }; +// --- LIFECYCLE --------------------------------------------------------------- + let languageServer = null; let taskAssistant = null; let commandRegistrations = []; @@ -49,7 +53,11 @@ exports.deactivate = function deactivate() { function getConfigValue(key) { const workspaceValue = nova.workspace.config.get(key); - if (workspaceValue !== undefined && workspaceValue !== null && workspaceValue !== "") { + if ( + workspaceValue !== undefined && + workspaceValue !== null && + workspaceValue !== "" + ) { return workspaceValue; } @@ -81,7 +89,9 @@ function normalizeArray(value) { } return value - .map((entry) => (entry === null || entry === undefined ? "" : String(entry).trim())) + .map((entry) => + entry === null || entry === undefined ? "" : String(entry).trim(), + ) .filter((entry) => entry.length > 0); } @@ -166,7 +176,8 @@ function buildZigArgv(config, options) { const opts = options || {}; const argv = ["build"]; - const optimize = getTaskConfigValue(config, "optimize") || opts.defaultOptimize || null; + const optimize = + getTaskConfigValue(config, "optimize") || opts.defaultOptimize || null; if (optimize) argv.push(`-Doptimize=${optimize}`); const target = getTaskConfigValue(config, "target"); @@ -193,8 +204,8 @@ function safeCleanPaths(cwd) { nova.workspace.showWarningMessage( localizeText( "warning.clean.unsafe_cwd", - "Refusing to clean: the working directory must be inside this workspace." - ) + "Refusing to clean: the working directory must be inside this workspace.", + ), ); }; @@ -210,7 +221,10 @@ function safeCleanPaths(cwd) { } const home = nova.environment ? nova.environment.HOME : null; - if (home && (normalized === home || normalized === nova.path.normalize(home))) { + if ( + home && + (normalized === home || normalized === nova.path.normalize(home)) + ) { showWarning(); return null; } @@ -222,7 +236,10 @@ function safeCleanPaths(cwd) { } const workspaceNormalized = nova.path.normalize(workspacePath); - if (normalized !== workspaceNormalized && !normalized.startsWith(workspaceNormalized + "/")) { + if ( + normalized !== workspaceNormalized && + !normalized.startsWith(workspaceNormalized + "/") + ) { showWarning(); return null; } @@ -295,8 +312,11 @@ const stepCache = { if (!buildZigStat) return null; const buildZonStat = nova.fs.stat(nova.path.join(cwd, "build.zig.zon")); - const buildZigMtimeMs = buildZigStat.mtime ? buildZigStat.mtime.getTime() : 0; - const buildZonMtimeMs = buildZonStat && buildZonStat.mtime ? buildZonStat.mtime.getTime() : 0; + const buildZigMtimeMs = buildZigStat.mtime + ? buildZigStat.mtime.getTime() + : 0; + const buildZonMtimeMs = + buildZonStat && buildZonStat.mtime ? buildZonStat.mtime.getTime() : 0; const cached = this.entries.get(cwd); const fresh = @@ -308,14 +328,16 @@ const stepCache = { if (fresh) return cached.steps; if (!this.pending.has(cwd)) { - const promise = this.fetch(cwd, buildZigMtimeMs, buildZonMtimeMs).finally(() => { - this.pending.delete(cwd); - if (typeof nova.workspace.reloadTasks === "function") { - try { - nova.workspace.reloadTasks(TASK_ASSISTANT_ID); - } catch (_) {} - } - }); + const promise = this.fetch(cwd, buildZigMtimeMs, buildZonMtimeMs).finally( + () => { + this.pending.delete(cwd); + if (typeof nova.workspace.reloadTasks === "function") { + try { + nova.workspace.reloadTasks(TASK_ASSISTANT_ID); + } catch (_) {} + } + }, + ); this.pending.set(cwd, promise); } @@ -499,7 +521,6 @@ async function resolveLldbDapExecutable() { return await findOnPath("lldb-dap"); } - function lldbFrameworkPaths() { return [ "/Applications/Xcode-beta.app/Contents/SharedFrameworks/", @@ -517,7 +538,11 @@ function debugAdapterLogPath() { } function issueNormalizerScriptPath() { - return nova.path.join(nova.extension.path, "Scripts", "normalize-zig-issues.pl"); + return nova.path.join( + nova.extension.path, + "Scripts", + "normalize-zig-issues.pl", + ); } function quoteShellArgument(value) { @@ -526,9 +551,7 @@ function quoteShellArgument(value) { } function escapeAppleScriptString(value) { - return String(value) - .replace(/\\/g, "\\\\") - .replace(/"/g, '\\"'); + return String(value).replace(/\\/g, "\\\\").replace(/"/g, '\\"'); } function buildShellCommand(command, args, cwd) { @@ -537,7 +560,11 @@ function buildShellCommand(command, args, cwd) { segments.push(`cd ${quoteShellArgument(cwd)}`); } - segments.push([quoteShellArgument(command), ...(args || []).map(quoteShellArgument)].join(" ")); + segments.push( + [quoteShellArgument(command), ...(args || []).map(quoteShellArgument)].join( + " ", + ), + ); return segments.join("; "); } @@ -573,31 +600,36 @@ end tell`; function registerCommands() { commandRegistrations.push( - nova.commands.register(`${EXTENSION_ID}.runInTerminal`, async (workspace, payload) => { - const command = payload && payload.command; - const args = (payload && payload.args) || []; - const cwd = (payload && payload.cwd) || workspace.path || null; + nova.commands.register( + `${EXTENSION_ID}.runInTerminal`, + async (workspace, payload) => { + const command = payload && payload.command; + const args = (payload && payload.args) || []; + const cwd = (payload && payload.cwd) || workspace.path || null; - if (!command) { - workspace.showWarningMessage( - localizeText( - "warning.terminal.launch_failed", - "Unable to launch the Zig task in Terminal." - ) - ); - return; - } + if (!command) { + workspace.showWarningMessage( + localizeText( + "warning.terminal.launch_failed", + "Unable to launch the Zig task in Terminal.", + ), + ); + return; + } - const result = await launchInTerminal(buildShellCommand(command, args, cwd)); - if (result.status !== 0) { - const prefix = localizeText( - "warning.terminal.open_failed", - "Unable to open Terminal for the Zig task." + const result = await launchInTerminal( + buildShellCommand(command, args, cwd), ); - const suffix = result.stderr ? ` ${result.stderr}` : ""; - workspace.showWarningMessage(`${prefix}${suffix}`); - } - }) + if (result.status !== 0) { + const prefix = localizeText( + "warning.terminal.open_failed", + "Unable to open Terminal for the Zig task.", + ); + const suffix = result.stderr ? ` ${result.stderr}` : ""; + workspace.showWarningMessage(`${prefix}${suffix}`); + } + }, + ), ); } @@ -632,7 +664,7 @@ class ZigLanguageServer { this.disposables.push( nova.workspace.onDidChangePath(() => { this.start(); - }) + }), ); this.start(); @@ -646,7 +678,7 @@ class ZigLanguageServer { } else { void this.pushConfiguration(); } - }) + }), ); this.disposables.push( nova.workspace.config.onDidChange(key, () => { @@ -655,7 +687,7 @@ class ZigLanguageServer { } else { void this.pushConfiguration(); } - }) + }), ); } @@ -689,8 +721,8 @@ class ZigLanguageServer { "zls", localizeText( "warning.zls.not_found", - "ZLS was not found. Install it or set a ZLS executable path in Zig extension settings." - ) + "ZLS was not found. Install it or set a ZLS executable path in Zig extension settings.", + ), ); return; } @@ -721,7 +753,7 @@ class ZigLanguageServer { LANGUAGE_CLIENT_ID, localizeText("name.language_server", "Zig Language Server"), serverOptions, - clientOptions + clientOptions, ); client.onNotification("window/logMessage", ({ type, message }) => { @@ -745,7 +777,7 @@ class ZigLanguageServer { nova.workspace.showWarningMessage( localizeText( "warning.zls.stopped_unexpectedly", - "The Zig language server stopped unexpectedly ({executable}).", + "The Zig Language Server stopped unexpectedly ({executable}).", { executable: zlsPath || "zls" }, ), ); @@ -767,8 +799,8 @@ class ZigLanguageServer { localizeText( "warning.zls.start_failed", "Unable to start the Zig language server at {path}.", - { path: zlsPath } - ) + { path: zlsPath }, + ), ); this.stop(); } @@ -776,7 +808,10 @@ class ZigLanguageServer { async resolveSettings() { const settings = { - enable_build_on_save: getBooleanConfigValue(CONFIG_KEYS.zlsBuildOnSave, false), + enable_build_on_save: getBooleanConfigValue( + CONFIG_KEYS.zlsBuildOnSave, + false, + ), }; const zigPath = await resolveExecutable(CONFIG_KEYS.zigPath, "zig"); if (zigPath) { @@ -789,7 +824,11 @@ class ZigLanguageServer { async pushConfiguration() { const generation = this.restartGeneration; const { settings } = await this.resolveSettings(); - if (generation !== this.restartGeneration || !this.client || !this.client.running) { + if ( + generation !== this.restartGeneration || + !this.client || + !this.client.running + ) { return; } @@ -803,7 +842,10 @@ class ZigLanguageServer { } stop() { - if (this.clientStopDisposable && typeof this.clientStopDisposable.dispose === "function") { + if ( + this.clientStopDisposable && + typeof this.clientStopDisposable.dispose === "function" + ) { this.clientStopDisposable.dispose(); this.clientStopDisposable = null; } @@ -843,33 +885,49 @@ class ZigTaskAssistant { provideTasks() { const tasks = []; - const currentFile = new Task(localizeText("task.current_file.name", "Current Zig File")); - currentFile.setAction(Task.Run, new TaskResolvableAction({ - data: { - type: "current-file-run", - }, - })); - currentFile.setAction(Task.Clean, new TaskResolvableAction({ - data: { - type: "current-file-clean", - }, - })); + const currentFile = new Task( + localizeText("task.current_file.name", "Current Zig File"), + ); + currentFile.setAction( + Task.Run, + new TaskResolvableAction({ + data: { + type: "current-file-run", + }, + }), + ); + currentFile.setAction( + Task.Clean, + new TaskResolvableAction({ + data: { + type: "current-file-clean", + }, + }), + ); tasks.push(currentFile); const workspacePath = nova.workspace.path; - if (workspacePath && getBooleanConfigValue(CONFIG_KEYS.discoverSteps, true)) { + if ( + workspacePath && + getBooleanConfigValue(CONFIG_KEYS.discoverSteps, true) + ) { const steps = stepCache.getOrFetch(workspacePath); if (steps && steps.length > 0) { for (const step of steps) { const task = new Task( - localizeText("task.build_step.name", "Zig Build: {step}", { step }) - ); - task.setAction(Task.Run, new TaskResolvableAction({ - data: { - type: "build-step", + localizeText("task.build_step.name", "Zig Build: {step}", { step, - }, - })); + }), + ); + task.setAction( + Task.Run, + new TaskResolvableAction({ + data: { + type: "build-step", + step, + }, + }), + ); tasks.push(task); } } @@ -928,8 +986,8 @@ class ZigTaskAssistant { nova.workspace.showWarningMessage( localizeText( "warning.clean.missing_cwd", - "Choose a workspace or working directory before cleaning Zig build artifacts." - ) + "Choose a workspace or working directory before cleaning Zig build artifacts.", + ), ); return null; } @@ -943,8 +1001,12 @@ class ZigTaskAssistant { const cached = stepCache.entries.get(cwd); const args = ["-rf", ...paths]; - if (cached && Array.isArray(cached.steps) && cached.steps.includes("uninstall")) { - const zigPath = await resolveExecutable(CONFIG_KEYS.zigPath, "zig"); + if ( + cached && + Array.isArray(cached.steps) && + cached.steps.includes("uninstall") + ) { + const zigPath = await resolveZigExecutable(); if (zigPath) { const command = `${quoteShellArgument(zigPath)} build uninstall; /bin/rm ${args .map(quoteShellArgument) @@ -988,7 +1050,9 @@ class ZigTaskAssistant { if (runArgs.length > 0) argv.push("--", ...runArgs); const consoleMode = - forceConsole || getTaskConfigValue(config, "console") || "internalConsole"; + forceConsole || + getTaskConfigValue(config, "console") || + "internalConsole"; if (consoleMode === "externalTerminal") { return new TaskCommandAction(`${EXTENSION_ID}.runInTerminal`, { @@ -1044,7 +1108,8 @@ class ZigTaskAssistant { const debounce = getTaskConfigValue(config, "debounceMs"); if (debounce !== null && debounce !== undefined && debounce !== "") { const n = Number(debounce); - if (Number.isFinite(n) && n >= 0) argv.push("--debounce", String(Math.floor(n))); + if (Number.isFinite(n) && n >= 0) + argv.push("--debounce", String(Math.floor(n))); } const incremental = getTaskConfigValue(config, "incremental"); @@ -1064,8 +1129,8 @@ class ZigTaskAssistant { nova.workspace.showWarningMessage( localizeText( "warning.current_file.focus_editor_for_run", - "Focus a Zig editor before running Current Zig File." - ) + "Focus a Zig editor before running Current Zig File.", + ), ); return null; } @@ -1079,8 +1144,8 @@ class ZigTaskAssistant { nova.workspace.showWarningMessage( localizeText( "warning.current_file.focus_editor_for_clean", - "Focus a Zig editor before cleaning Current Zig File artifacts." - ) + "Focus a Zig editor before cleaning Current Zig File artifacts.", + ), ); return null; } @@ -1090,14 +1155,13 @@ class ZigTaskAssistant { } async resolveDebugAction(config, cwd) { - const lldbDapPath = await resolveLldbDapExecutable - (); + const lldbDapPath = await resolveLldbDapExecutable(); if (!lldbDapPath) { nova.workspace.showWarningMessage( localizeText( "warning.lldb_dap.not_found", - "lldb-dap was not found. Install Xcode Command Line Tools or set an LLDB DAP executable path in Zig extension settings." - ) + "lldb-dap was not found. Install Xcode Command Line Tools or set an LLDB DAP executable path in Zig extension settings.", + ), ); return null; } @@ -1117,13 +1181,14 @@ class ZigTaskAssistant { nova.workspace.showWarningMessage( localizeText( "warning.debug.choose_program", - "Choose a program path before running Zig Debug." - ) + "Choose a program path before running Zig Debug.", + ), ); return null; } - const consoleMode = getTaskConfigValue(config, "console") || "internalConsole"; + const consoleMode = + getTaskConfigValue(config, "console") || "internalConsole"; const stopOnEntry = Boolean(config && config.get("stopOnEntry")); const action = new TaskDebugAdapterAction("zig-lldb-dap"); |
