diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bae4fe1..ad875145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - added Server actions menu, by clicking on server info from status bar. Open Management portal, Class Reference and toggle connection. - Class Suggestion in ##class, Extends, As, CompileAfter, DependsOn, PropertyClass - \$SYSTEM suggestion by Classes from %SYSTEM +- Import and compile folder or file by context menu in File explorer ## [0.7.10] diff --git a/commands/compile.ts b/commands/compile.ts index 116d8a0f..7d5159c3 100644 --- a/commands/compile.ts +++ b/commands/compile.ts @@ -1,5 +1,7 @@ import vscode = require('vscode'); import fs = require('fs'); +import path = require('path'); +import glob = require('glob'); import { AtelierAPI } from '../api'; import { currentFile, CurrentFile, outputChannel } from '../utils'; import { documentContentProvider, config } from '../extension'; @@ -13,7 +15,7 @@ async function compileFlags(): Promise { }); } -async function importFile(file: CurrentFile, flags: string): Promise { +async function importFile(file: CurrentFile): Promise { const api = new AtelierAPI(); return api .putDoc( @@ -23,13 +25,7 @@ async function importFile(file: CurrentFile, flags: string): Promise { content: file.content.split(/\r?\n/) }, true - ) - .then(() => compile(file, flags)) - .catch((error: Error) => { - outputChannel.appendLine(error.message); - outputChannel.show(true); - vscode.window.showErrorMessage(error.message); - }); + ); } function updateOthers(others: string[]) { @@ -39,30 +35,42 @@ function updateOthers(others: string[]) { }); } -async function loadChanges(file: CurrentFile): Promise { +async function loadChanges(files: CurrentFile[]): Promise { const api = new AtelierAPI(); - return api.getDoc(file.name).then(data => { - fs.writeFileSync(file.fileName, (data.result.content || []).join('\n')); - api - .actionIndex([file.name]) - .then(data => data.result.content[0].others) - .then(updateOthers); - }); + return Promise.all(files.map(file => + api.getDoc(file.name).then(data => { + fs.writeFileSync(file.fileName, (data.result.content || []).join('\n')); + return api + .actionIndex([file.name]) + .then(data => data.result.content[0].others) + .then(updateOthers); + }) + )); } -async function compile(file: CurrentFile, flags: string): Promise { +async function compile(docs: CurrentFile[], flags?: string): Promise { + flags = flags || config().compileFlags; const api = new AtelierAPI(); return api - .actionCompile([file.name], flags) + .actionCompile(docs.map(el => el.name), flags) .then(data => { + let info = docs.length > 1 ? '' : `${docs[0].name}: `; if (data.status && data.status.errors && data.status.errors.length) { - throw new Error(`${file.name}: Compile error`); + throw new Error(`${info}Compile error`); } else { - vscode.window.showInformationMessage(`${file.name}: Compile successed`); + vscode.window.showInformationMessage(`${info}Compile successed`, 'Hide'); } - return file; + return docs; }) - .then(loadChanges); + .then(loadChanges) + .catch((error: Error) => { + outputChannel.appendLine(error.message); + outputChannel.show(true); + vscode.window.showErrorMessage(error.message, 'Show details') + .then(data => { + outputChannel.show(true); + }); + }); } export async function importAndCompile(askFLags = false): Promise { @@ -76,15 +84,15 @@ export async function importAndCompile(askFLags = false): Promise { const defaultFlags = config().compileFlags; const flags = askFLags ? await compileFlags() : defaultFlags; - return importFile(file, flags).catch(error => { + return importFile(file).catch(error => { console.error(error); - }); + }).then(() => compile([file], flags)); } // Compiles all files types in the namespace export async function namespaceCompile(askFLags = false): Promise { const api = new AtelierAPI(); - const fileTypes = ["*.CLS", "*.MAC", "*.INC", "*.BAS"] + const fileTypes = ['*.CLS', '*.MAC', '*.INC', '*.BAS']; if (!config('conn').active) { throw new Error(`No Active Connection`); } @@ -94,21 +102,58 @@ export async function namespaceCompile(askFLags = false): Promise { // User cancelled return; } - vscode.window.withProgress({ - location: vscode.ProgressLocation.Notification, - title: `Compiling Namespace: ${api.ns}`, - cancellable: false - }, async () => { - const data = await api - .actionCompile(fileTypes, flags); - if (data.status && data.status.errors && data.status.errors.length) { - console.error(data.status.summary); - throw new Error(`Compiling Namespace: ${api.ns} Error`); - } - else { - vscode.window.showInformationMessage(`Compiling Namespace: ${api.ns} Success`); + vscode.window.withProgress( + { + location: vscode.ProgressLocation.Notification, + title: `Compiling Namespace: ${api.ns}`, + cancellable: false + }, + async () => { + const data = await api.actionCompile(fileTypes, flags); + if (data.status && data.status.errors && data.status.errors.length) { + console.error(data.status.summary); + throw new Error(`Compiling Namespace: ${api.ns} Error`); + } else { + vscode.window.showInformationMessage(`Compiling Namespace: ${api.ns} Success`); + } + const file = currentFile(); + return loadChanges([file]); } - const file = currentFile(); - return loadChanges(file); - }); + ); +} + +function importFiles(files) { + return Promise.all( + files.map(file => + vscode.workspace + .openTextDocument(file) + .then(currentFile) + .then(file => + Promise.resolve(file) + .then(importFile) + .then(data => { + outputChannel.appendLine('Imported file: ' + file.fileName) + return file; + }) + ) + ) + ) + .then(compile); +} + +export async function importFolder(uri: vscode.Uri): Promise { + let folder = uri.path; + if (fs.lstatSync(folder).isFile()) { + return importFiles([folder]); + } + glob( + '**/*.{cls,inc,mac,int}', + { + cwd: folder, + nocase: true + }, + (error, files) => importFiles( + files.map(name => path.join(folder, name)) + ) + ); } diff --git a/extension.ts b/extension.ts index afdf78bf..c99ebefb 100644 --- a/extension.ts +++ b/extension.ts @@ -4,7 +4,7 @@ export const OBJECTSCRIPT_FILE_SCHEMA = 'objectscript'; export const OBJECTSCRIPTXML_FILE_SCHEMA = 'objectscriptxml'; import { viewOthers } from './commands/viewOthers'; -import { importAndCompile, namespaceCompile } from './commands/compile'; +import { importAndCompile, namespaceCompile, importFolder as importFileOrFolder } from './commands/compile'; import { exportAll, exportExplorerItem } from './commands/export'; import { xml2doc } from './commands/xml2doc'; import { subclass } from './commands/subclass'; @@ -140,6 +140,7 @@ export async function activate(context: vscode.ExtensionContext): Promise vscode.commands.registerCommand('vscode-objectscript.compileWithFlags', () => importAndCompile(true)), vscode.commands.registerCommand('vscode-objectscript.compileAll', () => namespaceCompile(false)), vscode.commands.registerCommand('vscode-objectscript.compileAllWithFlags', () => namespaceCompile(true)), + vscode.commands.registerCommand('vscode-objectscript.compileFolder', importFileOrFolder), vscode.commands.registerCommand('vscode-objectscript.export', exportAll), vscode.commands.registerCommand('vscode-objectscript.viewOthers', viewOthers), vscode.commands.registerCommand('vscode-objectscript.subclass', subclass), @@ -209,4 +210,4 @@ export async function activate(context: vscode.ExtensionContext): Promise ); } -export async function deactivate() {} +export async function deactivate() { } diff --git a/package.json b/package.json index fe8ab0d5..32be1b85 100644 --- a/package.json +++ b/package.json @@ -178,6 +178,12 @@ "group": "objectscript.viewOthers", "when": "editorLangId =~ /^objectscript/ && vscode-objectscript.connectActive" } + ], + "explorer/context": [ + { + "command": "vscode-objectscript.compileFolder", + "when": "vscode-objectscript.connectActive" + } ] }, "languages": [ @@ -347,6 +353,11 @@ "category": "ObjectScript", "command": "vscode-objectscript.serverActions", "title": "Show server actions" + }, + { + "category": "ObjectScsript", + "command": "vscode-objectscript.compileFolder", + "title": "Import and compile" } ], "keybindings": [ @@ -465,6 +476,7 @@ "description": "Autocompile on save file", "type": "boolean", "default": false, + "deprecationMessage": "Always enabled, now, when connection is active", "scope": "resource" }, "objectscript.showExplorer": { diff --git a/utils/index.ts b/utils/index.ts index 6d9f11f2..a9b184d6 100644 --- a/utils/index.ts +++ b/utils/index.ts @@ -18,8 +18,8 @@ export interface CurrentFile { uri: vscode.Uri; } -export function currentFile(): CurrentFile { - const document = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.document : null; +export function currentFile(document?: vscode.TextDocument): CurrentFile { + document = document || (vscode.window.activeTextEditor.document ? vscode.window.activeTextEditor.document : null); if (!document || !document.fileName || !document.languageId || !document.languageId.startsWith('objectscript')) { return null; }