aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Scripts/main.js112
1 files changed, 65 insertions, 47 deletions
diff --git a/Scripts/main.js b/Scripts/main.js
index a1c86f6..652e4cc 100644
--- a/Scripts/main.js
+++ b/Scripts/main.js
@@ -1,6 +1,6 @@
"use strict";
-// --- CONFIGURATION -----------------------------------------------------------
+// --- CONSTANTS ---------------------------------------------------------------
const EXTENSION_ID = "at.dcz.nova-zig";
const TASK_ASSISTANT_ID = `${EXTENSION_ID}.tasks`;
@@ -51,6 +51,8 @@ exports.deactivate = function deactivate() {
commandRegistrations = [];
};
+// --- CONFIG HELPERS ----------------------------------------------------------
+
/**
* Resolve a configuration value respecting precedence
*
@@ -143,7 +145,7 @@ function resolvePathAgainstBase(path, base) {
/**
* Safely retrieve a task config value
*
- * @param {task configuration object} config - Task configuration
+ * @param {Object} config - Nova task configuration object
* @param {string} key - Key
* @returns {string} - Value
*/
@@ -161,7 +163,7 @@ function getTaskConfigValue(config, key) {
*
* Specialized version of {@link getTaskConfigValue}
*
- * @param {task configuration object} config - Task configuration
+ * @param {Object} config - Nova task configuration object
* @param {string} key - Key
* @returns {string[]} - Argument list
*/
@@ -184,6 +186,8 @@ function getTaskCwd(config) {
return nova.workspace.path || null;
}
+// --- TASK ARG HELPERS --------------------------------------------------------
+
// Returns the configured step string, or null if the step should be omitted.
// An explicit empty string means "no step argument" — `zig build` then runs the
// default install step (Ziglings-style projects rely on this). Missing/null
@@ -237,12 +241,13 @@ function buildZigArgv(config, options) {
return argv;
}
+// --- PATH & WORKSPACE HELPERS ------------------------------------------------
+
/**
* Validate cwd is safe to clean (absolute, inside workspace, not root or home),
* returning directories or null
*
* @param {string} cwd - Directory to clean
- *
* @returns {string[]|null} - Directories to remove
*/
function resolveCleanPaths(cwd) {
@@ -321,17 +326,11 @@ function findNearestZigBuildDir(startDir) {
return workspacePath || null;
}
-// Best-effort regex extraction of the package name from build.zig.zon. Returns
-// null when the file is missing, unreadable, or doesn't match the expected
-// `\.name = "<name>"` / `\.name = .<ident>` shapes. Used to default
-// `programPath` for the Debug template.
-
/**
* Extract the package name from `build.zig.zon` by regex,
* returning null if absent or unreadable
*
* @param {string} cwd - Directory in which to search for build.zig.zon
- *
* @returns {string|null} - Package name or null if parsing fails
*/
function parseProjectName(cwd) {
@@ -358,6 +357,40 @@ function parseProjectName(cwd) {
return match[1] || match[2] || null;
}
+/**
+ * Resolve the path of the active zig file
+ *
+ * @returns {string|null} - Path or null if active editor is not a zig file
+ */
+function activeZigFilePath() {
+ const editor = nova.workspace.activeTextEditor;
+ if (!editor || !editor.document || !editor.document.path) {
+ return null;
+ }
+
+ if (editor.document.syntax !== "zig") {
+ return null;
+ }
+
+ return editor.document.path;
+}
+
+/**
+ * Resolve the directory of the active zig file
+ *
+ * @returns {string|null} - Directory or null if active editor is not a zig file
+ */
+function activeZigFileDirectory() {
+ const filePath = activeZigFilePath();
+ if (!filePath) {
+ return null;
+ }
+
+ return nova.path.dirname(filePath);
+}
+
+// --- STEP CACHE --------------------------------------------------------------
+
// Per-cwd cache for `zig build --list-steps`. Invalidated by mtime changes on
// build.zig / build.zig.zon and a soft 5-minute TTL. `getOrFetch` returns
// cached steps synchronously and kicks off a background refresh when stale,
@@ -441,37 +474,7 @@ const stepCache = {
},
};
-/**
- * Resolve the path of the active zig file
- *
- * @returns {string|null} - Path or null if active editor is not a zig file
- */
-function activeZigFilePath() {
- const editor = nova.workspace.activeTextEditor;
- if (!editor || !editor.document || !editor.document.path) {
- return null;
- }
-
- if (editor.document.syntax !== "zig") {
- return null;
- }
-
- return editor.document.path;
-}
-
-/**
- * Resolve the directory of the active zig file
- *
- * @returns {string|null} - Directory or null if active editor is not a zig file
- */
-function activeZigFileDirectory() {
- const filePath = activeZigFilePath();
- if (!filePath) {
- return null;
- }
-
- return nova.path.dirname(filePath);
-}
+// --- LOCALIZATION -------------------------------------------------------------
/**
* Resolve a localized string, substituting `{variable}` placeholders
@@ -494,6 +497,8 @@ function localizeText(key, fallback, variables) {
return text;
}
+// --- PROCESS -----------------------------------------------------------------
+
/**
* Wraps Nova's Process API in a Promise, resolving with stdout, stderr, and exit status.
*
@@ -525,11 +530,13 @@ function runProcess(command, options) {
});
}
+// --- EXECUTABLE RESOLVERS ----------------------------------------------------
+
/**
* Find executable on PATH using `which`
*
* @param {string} executableName - Executable name
- * @returns {Promise(string|null)} - Path to the executable or null if not found
+ * @returns {Promise<string|null>} - Path to the executable or null if not found
*/
async function findOnPath(executableName) {
const result = await runProcess("/usr/bin/env", {
@@ -549,7 +556,7 @@ async function findOnPath(executableName) {
*
* @param {string} configKey - Configuration key
* @param {string} defaultCommand - Default command to be searched on PATH
- * @returns {Promise(string|null)} - Path to the executable or null if not found
+ * @returns {Promise<string|null>} - Path to the executable or null if not found
*/
async function resolveExecutable(configKey, defaultCommand) {
const configuredPath = getConfigValue(configKey);
@@ -563,7 +570,7 @@ async function resolveExecutable(configKey, defaultCommand) {
/**
* Resolve the zig executable, show warning if not found
*
- * @returns {Promise(string|null)} - Path to the zig executable or null if not found
+ * @returns {Promise<string|null>} - Path to the zig executable or null if not found
*/
async function resolveZigExecutable() {
const zigPath = await resolveExecutable(CONFIG_KEYS.zigPath, "zig");
@@ -583,7 +590,7 @@ async function resolveZigExecutable() {
* Resolve executable using Xcode `xcrun`
*
* @param {string} executableName - Executable name
- * @returns {Promise(string|null)} - Path to the executable or null if not found
+ * @returns {Promise<string|null>} - Path to the executable or null if not found
*/
async function findWithXcode(executableName) {
const result = await runProcess("/usr/bin/xcrun", {
@@ -601,7 +608,7 @@ async function findWithXcode(executableName) {
/**
* Resolve the lldb-dap executable
*
- * @returns {Promise(string|null)} - Path to the lldb-dap executable or null if not found
+ * @returns {Promise<string|null>} - Path to the lldb-dap executable or null if not found
*/
async function resolveLldbDapExecutable() {
const configuredPath = getConfigValue(CONFIG_KEYS.lldbDapPath);
@@ -619,6 +626,7 @@ async function resolveLldbDapExecutable() {
/**
* Return Dynamic Linker (DYLD) framework search paths for LLDB
+ *
* @returns {string[]} - Search paths
*/
function lldbFrameworkPaths() {
@@ -662,6 +670,8 @@ function issueNormalizerScriptPath() {
);
}
+// --- SHELL UTILITIES ---------------------------------------------------------
+
/**
* Wrap a value in single quotes with embedded single quotes escaped,
* safe for POSIX shell
@@ -724,9 +734,10 @@ function buildIssueNormalizedCommand(command, args) {
}
/**
- * Open macOS Terminal and run a shell command via AppleScript
+ * Runs a shell command string in a new macOS Terminal window.
*
* @param {string} commandLine - Command to run
+ * @returns {Promise<{status: number, stderr: string}>}
*/
function launchInTerminal(commandLine) {
return new Promise((resolve) => {
@@ -749,6 +760,9 @@ end tell`;
});
}
+// --- COMMANDS ----------------------------------------------------------------
+
+/** Registers the internal runInTerminal command used by external-terminal task actions. */
function registerCommands() {
commandRegistrations.push(
nova.commands.register(
@@ -784,6 +798,8 @@ function registerCommands() {
);
}
+// --- LANGUAGE SERVER ---------------------------------------------------------
+
function syncWorkspaceZlsConfiguration(settings) {
const bridge = {
"zls.zig_exe_path": settings.zig_exe_path,
@@ -1018,6 +1034,8 @@ class ZigLanguageServer {
}
}
+// --- TASK ASSISTANT ----------------------------------------------------------
+
class ZigTaskAssistant {
constructor() {
this.disposable = nova.assistants.registerTaskAssistant(this, {