diff --git a/src/commands/compile.ts b/src/commands/compile.ts index 7c455fbb..7670633c 100644 --- a/src/commands/compile.ts +++ b/src/commands/compile.ts @@ -14,6 +14,7 @@ import { DocumentContentProvider } from "../providers/DocumentContentProvider"; import { base64EncodeContent, classNameRegex, + compileErrorMsg, cspAppsForUri, CurrentBinaryFile, currentFile, @@ -291,12 +292,7 @@ export async function compile(docs: CurrentFile[], flags?: string): Promise return docs; }) .catch(() => { - if (!conf.get("suppressCompileErrorMessages")) { - vscode.window.showErrorMessage( - "Compilation failed. Check the 'ObjectScript' Output channel for details.", - "Dismiss" - ); - } + compileErrorMsg(conf); // Always fetch server changes, even when compile failed or got cancelled return docs; }) @@ -483,9 +479,9 @@ export async function importFolder(uri: vscode.Uri, noCompile = false): Promise< } export async function compileExplorerItems(nodes: NodeBase[]): Promise { - const { workspaceFolder, namespace } = nodes[0]; - const flags = config().compileFlags; - const api = new AtelierAPI(workspaceFolder); + const { workspaceFolderUri, namespace } = nodes[0]; + const conf = vscode.workspace.getConfiguration("objectscript", workspaceFolderUri); + const api = new AtelierAPI(workspaceFolderUri); api.setNamespace(namespace); const docs = []; for (const node of nodes) { @@ -512,23 +508,16 @@ export async function compileExplorerItems(nodes: NodeBase[]): Promise { }, (progress, token: vscode.CancellationToken) => api - .asyncCompile(docs, token, flags) + .asyncCompile(docs, token, conf.get("compileFlags")) .then((data) => { const info = nodes.length > 1 ? "" : `${nodes[0].fullName}: `; if (data.status && data.status.errors && data.status.errors.length) { throw new Error(`${info}Compile error`); - } else if (!config("suppressCompileMessages")) { + } else if (!conf.get("suppressCompileMessages")) { vscode.window.showInformationMessage(`${info}Compilation succeeded.`, "Dismiss"); } }) - .catch(() => { - if (!config("suppressCompileErrorMessages")) { - vscode.window.showErrorMessage( - "Compilation failed. Check the 'ObjectScript' Output channel for details.", - "Dismiss" - ); - } - }) + .catch(() => compileErrorMsg(conf)) ); } @@ -585,6 +574,8 @@ async function importFileFromContent( /** Prompt the user to compile documents after importing them */ async function promptForCompile(imported: string[], api: AtelierAPI, refresh: boolean): Promise { + // This cast is safe because the only two callers intialize api with a workspace folder URI + const conf = vscode.workspace.getConfiguration("objectscript", api.wsOrFile); // Prompt the user for compilation if (imported.length) { return vscode.window @@ -606,23 +597,16 @@ async function promptForCompile(imported: string[], api: AtelierAPI, refresh: bo }, (progress, token: vscode.CancellationToken) => api - .asyncCompile(imported, token, config("compileFlags")) + .asyncCompile(imported, token, conf.get("compileFlags")) .then((data) => { const info = imported.length > 1 ? "" : `${imported[0]}: `; if (data.status && data.status.errors && data.status.errors.length) { throw new Error(`${info}Compile error`); - } else if (!config("suppressCompileMessages")) { + } else if (!conf.get("suppressCompileMessages")) { vscode.window.showInformationMessage(`${info}Compilation succeeded.`, "Dismiss"); } }) - .catch(() => { - if (!config("suppressCompileErrorMessages")) { - vscode.window.showErrorMessage( - "Compilation failed. Check the 'ObjectScript' Output channel for details.", - "Dismiss" - ); - } - }) + .catch(() => compileErrorMsg(conf)) .finally(() => { if (refresh) { // Refresh the files explorer to show the new files diff --git a/src/commands/project.ts b/src/commands/project.ts index bc4d5374..770ab676 100644 --- a/src/commands/project.ts +++ b/src/commands/project.ts @@ -3,7 +3,7 @@ import { AtelierAPI } from "../api"; import { config, filesystemSchemas, projectsExplorerProvider, schemas } from "../extension"; import { compareConns } from "../providers/DocumentContentProvider"; import { isfsDocumentName } from "../providers/FileSystemProvider/FileSystemProvider"; -import { getWsServerConnection, handleError, notIsfs, notNull } from "../utils"; +import { compileErrorMsg, getWsServerConnection, handleError, notIsfs, notNull } from "../utils"; import { exportList } from "./export"; import { OtherStudioAction, StudioActions } from "./studio"; import { NodeBase, ProjectNode, ProjectRootNode, RoutineNode, CSPFileNode, ClassNode } from "../explorer/nodes"; @@ -996,14 +996,7 @@ export async function compileProjectContents(node: ProjectNode): Promise { vscode.window.showInformationMessage("Compilation succeeded.", "Dismiss"); } }) - .catch(() => { - if (!conf.get("suppressCompileErrorMessages")) { - vscode.window.showErrorMessage( - "Compilation failed. Check the 'ObjectScript' Output channel for details.", - "Dismiss" - ); - } - }) + .catch(() => compileErrorMsg(conf)) ); } diff --git a/src/extension.ts b/src/extension.ts index 1ab7b1f8..523039a3 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -24,6 +24,7 @@ export const macLangId = "objectscript"; export const intLangId = "objectscript-int"; export const incLangId = "objectscript-macros"; export const cspLangId = "objectscript-csp"; +export const outputLangId = "vscode-objectscript-output"; import * as url from "url"; import path = require("path"); @@ -1032,10 +1033,6 @@ export async function activate(context: vscode.ExtensionContext): Promise { } } }), - - vscode.commands.registerCommand("vscode-objectscript.output", () => { - outputChannel.show(true); - }), vscode.commands.registerCommand("vscode-objectscript.compile", () => importAndCompile(false)), vscode.commands.registerCommand("vscode-objectscript.touchBar.compile", () => importAndCompile(false)), vscode.commands.registerCommand("vscode-objectscript.compileWithFlags", () => importAndCompile(true)), @@ -1244,10 +1241,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { ), vscode.commands.registerCommand("vscode-objectscript.compileOnly", () => compileOnly(false)), vscode.commands.registerCommand("vscode-objectscript.compileOnlyWithFlags", () => compileOnly(true)), - vscode.languages.registerDocumentLinkProvider( - { language: "vscode-objectscript-output" }, - new DocumentLinkProvider() - ), + vscode.languages.registerDocumentLinkProvider({ language: outputLangId }, new DocumentLinkProvider()), vscode.commands.registerCommand("vscode-objectscript.editOthers", () => viewOthers(true)), vscode.commands.registerCommand("vscode-objectscript.showClassDocumentationPreview", () => DocumaticPreviewPanel.create() diff --git a/src/providers/FileSystemProvider/FileSystemProvider.ts b/src/providers/FileSystemProvider/FileSystemProvider.ts index 715ed6c3..4ce19dfc 100644 --- a/src/providers/FileSystemProvider/FileSystemProvider.ts +++ b/src/providers/FileSystemProvider/FileSystemProvider.ts @@ -17,6 +17,7 @@ import { stringifyError, base64EncodeContent, openCustomEditors, + compileErrorMsg, } from "../../utils"; import { FILESYSTEM_READONLY_SCHEMA, FILESYSTEM_SCHEMA, intLangId, macLangId, workspaceState } from "../../extension"; import { addIsfsFileToProject, modifyProject } from "../../commands/project"; @@ -803,21 +804,7 @@ export class FileSystemProvider implements vscode.FileSystemProvider { vscode.window.showInformationMessage(`${info}Compilation succeeded.`, "Dismiss"); } }) - .catch(() => { - if (!conf.get("suppressCompileErrorMessages")) { - vscode.window - .showErrorMessage( - "Compilation failed. Check 'ObjectScript' Output channel for details.", - "Show", - "Dismiss" - ) - .then((action) => { - if (action === "Show") { - outputChannel.show(true); - } - }); - } - }) + .catch(() => compileErrorMsg(conf)) ); // Tell the client to update all "other" files affected by compilation const workspaceFolder = workspaceFolderOfUri(uri); diff --git a/src/utils/index.ts b/src/utils/index.ts index 794c583c..999c37b7 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -12,12 +12,13 @@ import { OBJECTSCRIPT_FILE_SCHEMA, documentContentProvider, filesystemSchemas, + outputLangId, } from "../extension"; import { getCategory } from "../commands/export"; import { isCSP, isfsDocumentName } from "../providers/FileSystemProvider/FileSystemProvider"; import { AtelierAPI } from "../api"; -export const outputChannel = vscode.window.createOutputChannel("ObjectScript", "vscode-objectscript-output"); +export const outputChannel = vscode.window.createOutputChannel("ObjectScript", outputLangId); /** * A map of all CSP web apps in a server-namespace. @@ -968,6 +969,22 @@ export async function replaceFile(uri: vscode.Uri, content: string | string[] | if (!success) throw `Failed to create or replace contents of file '${uri.toString(true)}'`; } +/** Show the compilation failure error message if required. */ +export function compileErrorMsg(conf: vscode.WorkspaceConfiguration): void { + if (conf.get("suppressCompileErrorMessages")) return; + vscode.window + .showErrorMessage( + "Compilation failed. Check 'ObjectScript' Output channel for details.", + !vscode.window.visibleTextEditors.some((e) => e.document.languageId == outputLangId) ? "Show" : undefined, + "Dismiss" + ) + .then((action) => { + if (action == "Show") { + outputChannel.show(true); + } + }); +} + class Semaphore { /** Queue of tasks waiting to acquire the semaphore */ private _tasks: (() => void)[] = [];