From 8cf3b6640a32b2ee707e4c3eb840ded7529cd5aa Mon Sep 17 00:00:00 2001 From: ex61wi <54616262+dutchie031@users.noreply.github.com> Date: Sat, 4 Apr 2026 16:31:39 +0200 Subject: [PATCH 1/8] wip --- compiler/src/ScriptCompiler.ts | 48 ++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/compiler/src/ScriptCompiler.ts b/compiler/src/ScriptCompiler.ts index cdab2dd..58389df 100644 --- a/compiler/src/ScriptCompiler.ts +++ b/compiler/src/ScriptCompiler.ts @@ -57,7 +57,7 @@ export class ScriptCompiler { } private parseFile(filePath: string, content: string, fullPath: string): ParsedFile { - const dependencies: string[] = []; + const dependencies: Dependency[] = []; const newLines: string[] = [`do --${filePath}`]; content = stripLuaMultilineComments(content); @@ -113,7 +113,7 @@ export class ScriptCompiler { const requireMatch = line.match(/require\(['"](.+?)['"]\)/); if (requireMatch) { const requiredModule = fileReferenceToLuaVariable(requireMatch[1]); - dependencies.push(requiredModule); + dependencies.push(new Dependency(requiredModule, fullPath, i + 1)); line = line.replace(requireMatch[0], requiredModule); } @@ -241,6 +241,15 @@ function stripLuaMultilineComments(content: string): string { return content.replace(/--\[(=*)\[[\s\S]*?\]\1\]/g, ''); } +class Dependency { + + constructor( + public readonly name: string, + public readonly filePath: string, + public readonly requiredAtLine: number + ){} +} + class ParsedFile { public readonly fileKey: string; @@ -248,7 +257,7 @@ class ParsedFile { public readonly filePath: string, public readonly fullPath: string, public readonly lines: string[], - public readonly dependencies: string[] + public readonly dependencies: Dependency[] ) { this.fileKey = fileReferenceToLuaVariable(filePath); } @@ -302,23 +311,24 @@ class Writer { outputLines.push(...this.getStartLines()); - const writeFileRecursive = (fileKey: string) => { - if (writtenFiles.has(fileKey)) { - return; - } + const writeFileRecursive = (parsedFile: ParsedFile) => { - const file = this.files.get(fileKey); - if (!file) { - throw new Error(`File not found in compiler: ${fileKey}`); - } - // Write dependencies first - for (const dep of file.dependencies) { - writeFileRecursive(dep); + for (const dep of parsedFile.dependencies) { + const depFile = this.files.get(dep.name); + if (depFile) { + writeFileRecursive(depFile); + } else { + this.onError?.({ + filePath: parsedFile.fullPath, + line: 0, + message: `Missing dependency: ${dep}` + }); + } } - outputLines.push(...file.lines); - writtenFiles.add(fileKey); + outputLines.push(...parsedFile.lines); + writtenFiles.add(parsedFile.fileKey); }; //Check for circular dependencies before writing @@ -347,7 +357,7 @@ class Writer { const file = this.files.get(key); if (file) { for (const dep of file.dependencies) { - if (checkCircular(dep)) { + if (checkCircular(dep.name)) { return true; } } @@ -362,8 +372,8 @@ class Writer { } // Write all files in dependency order - for (const fileKey of this.files.keys()) { - writeFileRecursive(fileKey); + for (const parsedFile of this.files.values()) { + writeFileRecursive(parsedFile); } fs.mkdirSync(path.dirname(this.location), { recursive: true }); From 9e64c6b8d27f9c1a2e4d1d99b1663a00616e74cc Mon Sep 17 00:00:00 2001 From: ex61wi <54616262+dutchie031@users.noreply.github.com> Date: Sun, 5 Apr 2026 22:56:09 +0200 Subject: [PATCH 2/8] wip --- compiler/src/ScriptCompiler.ts | 176 ++++++++++++++---- dutchies-dcs-scripting-tools/package.json | 15 +- dutchies-dcs-scripting-tools/src/extension.ts | 27 ++- package-lock.json | 38 ++-- package.json | 7 +- 5 files changed, 201 insertions(+), 62 deletions(-) diff --git a/compiler/src/ScriptCompiler.ts b/compiler/src/ScriptCompiler.ts index 58389df..4324e0e 100644 --- a/compiler/src/ScriptCompiler.ts +++ b/compiler/src/ScriptCompiler.ts @@ -4,6 +4,8 @@ import * as path from 'path'; export interface CompilationError { filePath: string; line: number; + charStart?: number; + charEnd?: number; message: string; } @@ -15,48 +17,92 @@ export interface ScriptCompilerOptions { onError?: (error: CompilationError) => void } +export interface ICompilationLogger { + info(message: string): void; + error(message: string): void; + writeLine(message: string): void; +} + +class Metrics { + public totalLinesRead : number = 0; + public totalLinesWritten: number = 0; + public readTimeMs : number = 0; + public writeTimeMs : number = 0; + public totalTimeMs : number = 0; + public filesRead : number = 0; + public filesWritten : number = 0; + + log(logger: ICompilationLogger){ + logger.writeLine("Compilation Metrics: ") + logger.writeLine(`=====================`) + logger.writeLine(`Lines Read: ${this.totalLinesRead}`) + logger.writeLine(`Lines Written: ${this.totalLinesWritten}`) + logger.writeLine(`Files Processed: ${this.filesRead} | ${this.filesWritten}`) + logger.writeLine(`=====================`) + logger.writeLine(`Read Time (ms): ${this.readTimeMs} ms`) + logger.writeLine(`Write Time (ms): ${this.writeTimeMs} ms`) + logger.writeLine(`Total Time (ms): ${this.totalTimeMs} ms`) + } +} + const LUA_SCRIPT_GLOBAL_KEYWORD = 'ScriptGlobals'; export class ScriptCompiler { - constructor(private options: ScriptCompilerOptions) { + constructor(private options: ScriptCompilerOptions, private logger: ICompilationLogger) { if (options.outputFileName === undefined) { this.options.outputFileName = 'compiled.lua'; } } public async compile(): Promise { + const start = Date.now(); + const metricsMeter = new Metrics(); const entries = fs.readdirSync(this.options.sourcePath, { recursive: true, withFileTypes: true }); const parsedFiles: Map = new Map(); + const readStart = Date.now(); for (const entry of entries) { if (entry.isFile() && entry.name.endsWith('.lua')) { const fullPath = path.join(entry.parentPath ?? entry.path, entry.name); const relativePath = path.relative(this.options.sourcePath, fullPath); const content = fs.readFileSync(fullPath, 'utf-8'); - const parsedFile = this.parseFile(relativePath, content, fullPath); + const parsedFile = this.parseFile(relativePath, content, fullPath, metricsMeter); parsedFiles.set(parsedFile.fileKey, parsedFile); + metricsMeter.filesRead++; } } + const readEnd = Date.now(); + metricsMeter.readTimeMs = readEnd - readStart; const writer = new Writer( path.join(this.options.outputPath, this.options.outputFileName!), parsedFiles, + this.logger, this.options.onError ); + + const writeStart = Date.now(); + writer.write(metricsMeter); + const writeEnd = Date.now(); + metricsMeter.writeTimeMs = (writeEnd - writeStart); - writer.write(); - console.log(`Compilation complete. Output written to ${path.join(this.options.outputPath, this.options.outputFileName!)}`); + writer.logDependencyTree(); + this.logger.info(`Compilation complete. Output written to ${path.join(this.options.outputPath, this.options.outputFileName!)}`); + const end = Date.now(); + + metricsMeter.totalTimeMs = (end-start); + metricsMeter.log(this.logger); } - private reportError(filePath: string, line: number, message: string): void { + private reportError(filePath: string, line: number, charStart: number | undefined, charEnd: number | undefined, message: string): void { if (this.options.onError) { - this.options.onError({ filePath, line, message }); + this.options.onError({ filePath, line, charStart, charEnd, message }); } } - private parseFile(filePath: string, content: string, fullPath: string): ParsedFile { + private parseFile(filePath: string, content: string, fullPath: string, metricsMeter: Metrics): ParsedFile { const dependencies: Dependency[] = []; const newLines: string[] = [`do --${filePath}`]; @@ -83,6 +129,7 @@ export class ScriptCompiler { }; for (let i = 0; i < lines.length; i++) { + metricsMeter.totalLinesRead++; let line = lines[i]; const trimmedLine = line.trim(); @@ -103,7 +150,7 @@ export class ScriptCompiler { } newLines.push(line); } else { - this.reportError(fullPath, i, `Code found after module-level return: ${trimmedLine}`); + this.reportError(fullPath, i, undefined, undefined, `Code found after module-level return: ${trimmedLine}`); newLines.push(line); // Continue processing despite error } continue; @@ -112,8 +159,10 @@ export class ScriptCompiler { // Handle require statements const requireMatch = line.match(/require\(['"](.+?)['"]\)/); if (requireMatch) { - const requiredModule = fileReferenceToLuaVariable(requireMatch[1]); - dependencies.push(new Dependency(requiredModule, fullPath, i + 1)); + const textMatch = requireMatch[1]; + const requiredModule = fileReferenceToLuaVariable(textMatch); + + dependencies.push(new Dependency(textMatch, i, requireMatch.index ?? 0, (requireMatch.index ?? 0) + requireMatch[0].length)); line = line.replace(requireMatch[0], requiredModule); } @@ -164,7 +213,7 @@ export class ScriptCompiler { const afterReturn = trimmedLine.substring(afterReturnPos).trim(); if (afterReturn === '') { - this.reportError(fullPath, i, 'Empty return statement at module level'); + this.reportError(fullPath, i, afterReturnPos, afterReturnPos, 'Empty return statement at module level'); continue; } @@ -207,7 +256,7 @@ export class ScriptCompiler { } if (hasMultipleValues) { - this.reportError(fullPath, i, `Multiple return values not supported: ${trimmedLine}`); + this.reportError(fullPath, i, afterReturnPos, afterReturnPos + afterReturn.length, `Multiple return values not supported: ${trimmedLine}`); } else { // Replace return with assignment const moduleVariable = fileReferenceToLuaVariable(filePath); @@ -242,12 +291,17 @@ function stripLuaMultilineComments(content: string): string { } class Dependency { - + public readonly fileKey: string; + constructor( - public readonly name: string, - public readonly filePath: string, - public readonly requiredAtLine: number - ){} + public readonly requiredModule: string, + public readonly requiredAtLine: number, + public readonly charStart: number, + public readonly charEnd: number + ) + { + this.fileKey = fileReferenceToLuaVariable(requiredModule); + } } class ParsedFile { @@ -298,38 +352,52 @@ class Writer { constructor( public location: string, public files: Map, + private readonly logger: ICompilationLogger, public onError?: (error: CompilationError) => void ) {} private getStartLines(): string[] { - return [`local ${LUA_SCRIPT_GLOBAL_KEYWORD} = {}`]; + return [ + `-- Transpiled at (UTC): ${new Date().toISOString()}`, + `local ${LUA_SCRIPT_GLOBAL_KEYWORD} = {}` + ]; } - write(): void { + logDependencyTree(): void { + const visited: Set = new Set(); + const depth : number = 1; + this.logger.writeLine('Dependency Tree :'); + const logFileRecursive = (parsedFile: ParsedFile, currentDepth: number) => { + if (visited.has(parsedFile.fileKey)) { + return; + } + visited.add(parsedFile.fileKey); + let padding = ' '.repeat(currentDepth); + if (currentDepth > 0) { + padding = ' '.repeat(currentDepth) + '└─>'; + } + const printable = parsedFile.fileKey.replace(LUA_SCRIPT_GLOBAL_KEYWORD + '.', ''); + this.logger.writeLine(padding + printable); + for (const dep of parsedFile.dependencies) { + const depFile = this.files.get(dep.fileKey); + if (depFile) { + logFileRecursive(depFile, currentDepth + 1); + } + } + } + + for (const parsedFile of this.files.values()) { + logFileRecursive(parsedFile, depth); + } + }; + + write(metrics: Metrics): void { const writtenFiles: Set = new Set(); const outputLines: string[] = []; - outputLines.push(...this.getStartLines()); - - const writeFileRecursive = (parsedFile: ParsedFile) => { - - // Write dependencies first - for (const dep of parsedFile.dependencies) { - const depFile = this.files.get(dep.name); - if (depFile) { - writeFileRecursive(depFile); - } else { - this.onError?.({ - filePath: parsedFile.fullPath, - line: 0, - message: `Missing dependency: ${dep}` - }); - } - } - - outputLines.push(...parsedFile.lines); - writtenFiles.add(parsedFile.fileKey); - }; + const startLines = this.getStartLines(); + metrics.totalLinesWritten+=startLines.length; + outputLines.push(...startLines); //Check for circular dependencies before writing const visited: Set = new Set(); @@ -357,7 +425,7 @@ class Writer { const file = this.files.get(key); if (file) { for (const dep of file.dependencies) { - if (checkCircular(dep.name)) { + if (checkCircular(dep.fileKey)) { return true; } } @@ -371,6 +439,32 @@ class Writer { } } + const writeFileRecursive = (parsedFile: ParsedFile) => { + if (writtenFiles.has(parsedFile.fileKey)) { + return; + } + + // Write dependencies first + for (const dep of parsedFile.dependencies) { + const depFile = this.files.get(dep.fileKey); + if (depFile) { + writeFileRecursive(depFile); + } else { + this.onError?.({ + filePath: parsedFile.fullPath, + line: dep.requiredAtLine, + charStart: dep.charStart, + charEnd: dep.charEnd, + message: `Missing dependency: ${dep.fileKey}` + }); + } + } + metrics.totalLinesWritten += parsedFile.lines.length; + outputLines.push(...parsedFile.lines); + writtenFiles.add(parsedFile.fileKey); + metrics.filesWritten++; + }; + // Write all files in dependency order for (const parsedFile of this.files.values()) { writeFileRecursive(parsedFile); diff --git a/dutchies-dcs-scripting-tools/package.json b/dutchies-dcs-scripting-tools/package.json index c3baa5d..8b56cb2 100644 --- a/dutchies-dcs-scripting-tools/package.json +++ b/dutchies-dcs-scripting-tools/package.json @@ -22,6 +22,17 @@ "activationEvents": [], "main": "./dist/extension.js", "contributes": { + "configuration": { + "title": "Dutchies DCS Scripting Tools Settings", + "properties": { + "dutchiesDcsScriptingTools.compileAt" : { + "type": "string", + "enum": ["onSave", "onCompileCommand"], + "default": "onCompileCommand", + "description": "When to compile the Lua scripts" + } + } + }, "grammars": [ { "path": "./syntaxes/lua-slocal.json", @@ -56,9 +67,7 @@ "lua-addons/**/*", "syntaxes/**/*" ], - "dependencies": { - "dcs-script-compiler" : "*" - }, + "dependencies": {}, "scripts": { "vscode:prepublish": "npm run build -w compiler && npm run package", "compile": "npm run check-types && npm run lint && node esbuild.js", diff --git a/dutchies-dcs-scripting-tools/src/extension.ts b/dutchies-dcs-scripting-tools/src/extension.ts index f261035..15a43c6 100644 --- a/dutchies-dcs-scripting-tools/src/extension.ts +++ b/dutchies-dcs-scripting-tools/src/extension.ts @@ -1,7 +1,8 @@ // The module 'vscode' contains the VS Code extensibility API // Import the module and reference it with the alias vscode in your code below import * as vscode from 'vscode'; -import { ScriptCompiler, ScriptCompilerOptions, CompilationError } from 'dcs-script-compiler'; +import { ScriptCompiler, ScriptCompilerOptions, CompilationError, ICompilationLogger } from 'dcs-script-compiler'; +import { Logger } from './logger'; const luaWorkSpaceSettingKey = "Lua.workspace"; const librarySettingsKey = "library"; @@ -9,6 +10,7 @@ const diagnosticCollection = vscode.languages.createDiagnosticCollection('lua-tr let pluginPath : string | undefined; +const logger = new Logger(); // This method is called when your extension is activated // Your extension is activated the very first time the command is executed @@ -36,12 +38,12 @@ export function activate(context: vscode.ExtensionContext) { const start = Date.now(); await compileLuaScripts(); const end = Date.now(); - console.log(`Lua scripts compiled in ${(end - start) / 1000} seconds.`); vscode.window.showInformationMessage(`Lua scripts compiled successfully in ${(end - start) / 1000} seconds.`); }catch(err){ vscode.window.showErrorMessage('Error compiling Lua scripts: ' + (err as Error).message); } }); + } // This method is called when your extension is deactivated @@ -50,6 +52,22 @@ export function deactivate() removePluginPathFromSettings(); } +class CompilationLogger implements ICompilationLogger { + + constructor( + private readonly logger: Logger) { + } + info(message: string): void { + this.logger.info(message); + } + error(message: string): void { + this.logger.error(message); + } + writeLine(message: string): void { + this.logger.log(message); + } +} + async function compileLuaScripts() { const config = vscode.workspace.getConfiguration('dcsScriptingTools'); @@ -74,7 +92,8 @@ async function compileLuaScripts() { } }; - const compiler = new ScriptCompiler(options); + const compilationLogger = new CompilationLogger(logger); + const compiler = new ScriptCompiler(options, compilationLogger); try { await compiler.compile(); } catch (err) { @@ -86,7 +105,7 @@ async function compileLuaScripts() { for (const [filePath, errors] of errorsByFile) { const uri = vscode.Uri.file(filePath); const diagnostics = errors.map(error => { - const range = new vscode.Range(error.line, 0, error.line, 0); + const range = new vscode.Range(error.line, error.charStart ?? 0, error.line, error.charEnd ?? 0); const diagnostic = new vscode.Diagnostic(range, error.message, vscode.DiagnosticSeverity.Error); diagnostic.source = 'DCS Lua Transpiler'; return diagnostic; diff --git a/package-lock.json b/package-lock.json index 1203ade..d39b303 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,15 @@ "workspaces": [ "compiler", "dutchies-dcs-scripting-tools" - ] + ], + "devDependencies": { + "@types/node": "^25.5.2" + } }, "compiler": { "name": "dcs-script-compiler", "version": "1.0.0", + "extraneous": true, "devDependencies": { "@types/node": "^22.0.0", "typescript": "^5.9.3" @@ -21,9 +25,6 @@ "dutchies-dcs-scripting-tools": { "version": "0.0.1", "license": "MIT", - "dependencies": { - "dcs-script-compiler": "*" - }, "devDependencies": { "@types/mocha": "^10.0.10", "@types/node": "22.x", @@ -40,6 +41,16 @@ "vscode": "^1.108.1" } }, + "dutchies-dcs-scripting-tools/node_modules/@types/node": { + "version": "22.19.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz", + "integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, "node_modules/@bcoe/v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", @@ -832,15 +843,22 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.19.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.7.tgz", - "integrity": "sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==", + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz", + "integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.18.0" } }, + "node_modules/@types/node/node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/vscode": { "version": "1.108.1", "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.108.1.tgz", @@ -1713,10 +1731,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/dcs-script-compiler": { - "resolved": "compiler", - "link": true - }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", diff --git a/package.json b/package.json index f50bb0b..6256f4e 100644 --- a/package.json +++ b/package.json @@ -4,5 +4,8 @@ "workspaces": [ "compiler", "dutchies-dcs-scripting-tools" - ] -} \ No newline at end of file + ], + "devDependencies": { + "@types/node": "^25.5.2" + } +} From 299b61a4970198c3c2696bed975cdbe3a7ad8307 Mon Sep 17 00:00:00 2001 From: ex61wi <54616262+dutchie031@users.noreply.github.com> Date: Mon, 6 Apr 2026 00:53:50 +0200 Subject: [PATCH 3/8] wip --- dutchies-dcs-scripting-tools/src/logger.ts | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 dutchies-dcs-scripting-tools/src/logger.ts diff --git a/dutchies-dcs-scripting-tools/src/logger.ts b/dutchies-dcs-scripting-tools/src/logger.ts new file mode 100644 index 0000000..a80a7d5 --- /dev/null +++ b/dutchies-dcs-scripting-tools/src/logger.ts @@ -0,0 +1,26 @@ +import * as vscode from 'vscode'; + +export class Logger { + + private outputChannel: vscode.OutputChannel; + + constructor(){ + this.outputChannel = vscode.window.createOutputChannel('DCS Scripting Tools'); + } + + log(message: string) { + this.outputChannel.appendLine(message); + } + + info(message: string) { + this.outputChannel.appendLine(`[${new Date().toISOString()}][INFO] ${message}`); + } + + error(message: string) { + this.outputChannel.appendLine(`[${new Date().toISOString()}][ERROR] ${message}`); + } + + dispose() { + this.outputChannel.dispose(); + } +} \ No newline at end of file From aa0bc83c3266f66b61551c18ea9ba6f0c1415d72 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Mon, 6 Apr 2026 01:03:52 +0200 Subject: [PATCH 4/8] wip --- dutchies-dcs-scripting-tools/package.json | 2 +- dutchies-dcs-scripting-tools/src/extension.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dutchies-dcs-scripting-tools/package.json b/dutchies-dcs-scripting-tools/package.json index 8b56cb2..5ceca6c 100644 --- a/dutchies-dcs-scripting-tools/package.json +++ b/dutchies-dcs-scripting-tools/package.json @@ -25,7 +25,7 @@ "configuration": { "title": "Dutchies DCS Scripting Tools Settings", "properties": { - "dutchiesDcsScriptingTools.compileAt" : { + "dutchies-dcs-scripting-tools.compileAt" : { "type": "string", "enum": ["onSave", "onCompileCommand"], "default": "onCompileCommand", diff --git a/dutchies-dcs-scripting-tools/src/extension.ts b/dutchies-dcs-scripting-tools/src/extension.ts index 15a43c6..09339d8 100644 --- a/dutchies-dcs-scripting-tools/src/extension.ts +++ b/dutchies-dcs-scripting-tools/src/extension.ts @@ -12,9 +12,13 @@ let pluginPath : string | undefined; const logger = new Logger(); +const extensionName = 'dutchies-dcs-scripting-tools'; + // This method is called when your extension is activated // Your extension is activated the very first time the command is executed export function activate(context: vscode.ExtensionContext) { + + pluginPath = context.asAbsolutePath('lua-addons'); vscode.commands.registerCommand('dutchies-dcs-scripting-tools.enable', () => { @@ -43,7 +47,6 @@ export function activate(context: vscode.ExtensionContext) { vscode.window.showErrorMessage('Error compiling Lua scripts: ' + (err as Error).message); } }); - } // This method is called when your extension is deactivated From 3d9ea1f24eeddb4e159acc0ee59eee84452b7600 Mon Sep 17 00:00:00 2001 From: ex61wi <54616262+dutchie031@users.noreply.github.com> Date: Mon, 6 Apr 2026 20:59:36 +0200 Subject: [PATCH 5/8] wip --- .vscode/settings.json | 6 +- compiler/package.json | 13 +++ compiler/src/ScriptCompiler.ts | 2 + dutchies-dcs-scripting-tools/package.json | 31 +++++++- dutchies-dcs-scripting-tools/src/extension.ts | 79 +++++++++++++------ dutchies-dcs-scripting-tools/src/logger.ts | 4 + 6 files changed, 107 insertions(+), 28 deletions(-) create mode 100644 compiler/package.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 5c5ac48..456a965 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,5 +9,9 @@ "dist": true // set this to false to include "dist" folder in search results }, // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off" + "typescript.tsc.autoDetect": "off", + "cSpell.words": [ + "dutchie", + "dutchies" + ] } \ No newline at end of file diff --git a/compiler/package.json b/compiler/package.json new file mode 100644 index 0000000..1223d4a --- /dev/null +++ b/compiler/package.json @@ -0,0 +1,13 @@ +{ + "name": "dcs-mission-scripting-tools-compiler", + "devDependencies": { + "@types/node": "25.5.2" + }, + "scripts": { + "build": "tsc -p . --outDir dist", + "watch": "tsc -p . --outDir dist --watch" + }, + "files": [ + "dist/**/*" + ] +} \ No newline at end of file diff --git a/compiler/src/ScriptCompiler.ts b/compiler/src/ScriptCompiler.ts index 4324e0e..160038b 100644 --- a/compiler/src/ScriptCompiler.ts +++ b/compiler/src/ScriptCompiler.ts @@ -64,6 +64,8 @@ export class ScriptCompiler { const readStart = Date.now(); for (const entry of entries) { if (entry.isFile() && entry.name.endsWith('.lua')) { + + const fullPath = path.join(entry.parentPath ?? entry.path, entry.name); const relativePath = path.relative(this.options.sourcePath, fullPath); const content = fs.readFileSync(fullPath, 'utf-8'); diff --git a/dutchies-dcs-scripting-tools/package.json b/dutchies-dcs-scripting-tools/package.json index 5ceca6c..d818eca 100644 --- a/dutchies-dcs-scripting-tools/package.json +++ b/dutchies-dcs-scripting-tools/package.json @@ -19,18 +19,38 @@ "categories": [ "Other" ], - "activationEvents": [], + "activationEvents": [ + "onLanguage:lua", + "workspaceContains:**/*.lua" + ], "main": "./dist/extension.js", "contributes": { "configuration": { - "title": "Dutchies DCS Scripting Tools Settings", + "title": "Dutchies DCS Tools", + "type" : "object", "properties": { + "dutchies-dcs-scripting-tools.dcsTypes": { + "type": "boolean", + "default": true, + "description": "Enable or disable DCS Types (adds types for DCS functions and objects)" + }, + "dutchies-dcs-scripting-tools.spearheadTypes": { + "type": "boolean", + "default": false, + "description": "(Coming Soon) Enable or disable Spearhead Types (requires DCS Types to be enabled)" + }, "dutchies-dcs-scripting-tools.compileAt" : { "type": "string", "enum": ["onSave", "onCompileCommand"], "default": "onCompileCommand", - "description": "When to compile the Lua scripts" + "description": "When to compile the Lua script" + }, + "dutchies-dcs-scripting-tools.includeDevelopmentScript": { + "type": "boolean", + "default": false, + "description": "Adds an additional script. This can be referenced from DCS through doScriptFile. This will then execute the compiles script. This way you don't have to reinsert the script on each change, but can just hit 'restart'." } + } }, "grammars": [ @@ -41,6 +61,11 @@ } ], "commands": [ + { + "command": "dutchies-dcs-scripting-tools.openSettings", + "title": "Open Settings", + "category": "Dutchies DCS Tools" + }, { "command": "dutchies-dcs-scripting-tools.enable", "title": "Enable", diff --git a/dutchies-dcs-scripting-tools/src/extension.ts b/dutchies-dcs-scripting-tools/src/extension.ts index 09339d8..0075b7b 100644 --- a/dutchies-dcs-scripting-tools/src/extension.ts +++ b/dutchies-dcs-scripting-tools/src/extension.ts @@ -13,46 +13,75 @@ let pluginPath : string | undefined; const logger = new Logger(); const extensionName = 'dutchies-dcs-scripting-tools'; +const publisherName = 'dutchie031'; +const extensionSettingsFilter = `@ext:${publisherName}.${extensionName}`; + +//TODO: +// - ENABLE/DISABLE with settings instead of commands (or both) // This method is called when your extension is activated // Your extension is activated the very first time the command is executed export function activate(context: vscode.ExtensionContext) { - pluginPath = context.asAbsolutePath('lua-addons'); - - vscode.commands.registerCommand('dutchies-dcs-scripting-tools.enable', () => { - addPluginPathToSettings(); - vscode.commands.executeCommand( - "lua.startServer" - ); - vscode.window.showInformationMessage('Dutchies DCS Scripting Tools enabled.'); - }); - vscode.commands.registerCommand('dutchies-dcs-scripting-tools.disable', () => { - removePluginPathFromSettings(); - vscode.commands.executeCommand( - "lua.startServer" - ); - vscode.window.showInformationMessage('Dutchies DCS Scripting Tools disabled.'); - }); + context.subscriptions.push( + vscode.commands.registerCommand('dutchies-dcs-scripting-tools.enable', () => { + addPluginPathToSettings(); + vscode.commands.executeCommand( + "lua.startServer" + ); + vscode.window.showInformationMessage('Dutchies DCS Scripting Tools enabled.'); + }) + ); - vscode.commands.registerCommand('dutchies-dcs-scripting-tools.compileLuaScripts', async () => { - try{ - const start = Date.now(); - await compileLuaScripts(); - const end = Date.now(); - vscode.window.showInformationMessage(`Lua scripts compiled successfully in ${(end - start) / 1000} seconds.`); - }catch(err){ - vscode.window.showErrorMessage('Error compiling Lua scripts: ' + (err as Error).message); + context.subscriptions.push( + vscode.commands.registerCommand('dutchies-dcs-scripting-tools.disable', () => { + removePluginPathFromSettings(); + vscode.commands.executeCommand( + "lua.startServer" + ); + vscode.window.showInformationMessage('Dutchies DCS Scripting Tools disabled.'); + }) + ); + + context.subscriptions.push( + vscode.commands.registerCommand('dutchies-dcs-scripting-tools.openSettings', () => { + vscode.commands.executeCommand("workbench.action.openSettings", `@ext:${extensionSettingsFilter}`); + })); + + context.subscriptions.push( + vscode.commands.registerCommand('dutchies-dcs-scripting-tools.compileLuaScripts', async () => { + try{ + const start = Date.now(); + await compileLuaScripts(); + const end = Date.now(); + vscode.window.showInformationMessage(`Lua scripts compiled successfully in ${(end - start) / 1000} seconds.`); + }catch(err){ + vscode.window.showErrorMessage('Error compiling Lua scripts: ' + (err as Error).message); + } + }) + ); + + vscode.workspace.onDidSaveTextDocument(async(document) => { + logger.info(`Document saved: ${document.uri.fsPath} | Language: ${document.languageId}`); + if (document.languageId === 'lua') { + const config = vscode.workspace.getConfiguration(extensionName); + const compileAt = config.get('compileAt') || "undefined"; + if (compileAt === 'onSave') { + await compileLuaScripts(); + } } }); + + logger.info('Dutchies DCS Scripting Tools extension activated'); } // This method is called when your extension is deactivated export function deactivate() { removePluginPathFromSettings(); + logger.info('Dutchies DCS Scripting Tools extension deactivated'); } class CompilationLogger implements ICompilationLogger { @@ -72,6 +101,8 @@ class CompilationLogger implements ICompilationLogger { } async function compileLuaScripts() { + logger.clear(); + logger.info("Compiling..."); const config = vscode.workspace.getConfiguration('dcsScriptingTools'); const sourcePath = config.get('luaSourcePath') || '${workspaceFolder}/src'; diff --git a/dutchies-dcs-scripting-tools/src/logger.ts b/dutchies-dcs-scripting-tools/src/logger.ts index a80a7d5..99d4a09 100644 --- a/dutchies-dcs-scripting-tools/src/logger.ts +++ b/dutchies-dcs-scripting-tools/src/logger.ts @@ -20,6 +20,10 @@ export class Logger { this.outputChannel.appendLine(`[${new Date().toISOString()}][ERROR] ${message}`); } + clear() { + this.outputChannel.clear(); + } + dispose() { this.outputChannel.dispose(); } From 9b1ebd85a6fe3a37bb207fad93acfcda5724dd0d Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Mon, 6 Apr 2026 21:12:42 +0200 Subject: [PATCH 6/8] fixed node types errors --- compiler/package.json | 13 ------------- dutchies-dcs-scripting-tools/tsconfig.json | 3 +++ package-lock.json | 5 +++++ 3 files changed, 8 insertions(+), 13 deletions(-) delete mode 100644 compiler/package.json diff --git a/compiler/package.json b/compiler/package.json deleted file mode 100644 index 1223d4a..0000000 --- a/compiler/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "dcs-mission-scripting-tools-compiler", - "devDependencies": { - "@types/node": "25.5.2" - }, - "scripts": { - "build": "tsc -p . --outDir dist", - "watch": "tsc -p . --outDir dist --watch" - }, - "files": [ - "dist/**/*" - ] -} \ No newline at end of file diff --git a/dutchies-dcs-scripting-tools/tsconfig.json b/dutchies-dcs-scripting-tools/tsconfig.json index 8a4afe0..1816a24 100644 --- a/dutchies-dcs-scripting-tools/tsconfig.json +++ b/dutchies-dcs-scripting-tools/tsconfig.json @@ -10,6 +10,9 @@ "paths": { "dcs-script-compiler": ["../compiler/src/ScriptCompiler.ts"] }, + "types": [ + "node" + ], /* Additional Checks */ "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ diff --git a/package-lock.json b/package-lock.json index d39b303..e76ebb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -911,6 +911,7 @@ "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", @@ -1143,6 +1144,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2079,6 +2081,7 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -5168,6 +5171,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -5298,6 +5302,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" From 3083cf4b0b85c2d0599b34a384b166e6533e0898 Mon Sep 17 00:00:00 2001 From: ex61wi <54616262+dutchie031@users.noreply.github.com> Date: Tue, 7 Apr 2026 09:30:35 +0200 Subject: [PATCH 7/8] Better error handling --- compiler/src/ScriptCompiler.ts | 17 ++++---- compiler/tsconfig.json | 14 +++++++ dutchies-dcs-scripting-tools/src/extension.ts | 40 ++++++++++++++++--- dutchies-dcs-scripting-tools/tsconfig.json | 3 +- package-lock.json | 6 +-- package.json | 11 ++++- 6 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 compiler/tsconfig.json diff --git a/compiler/src/ScriptCompiler.ts b/compiler/src/ScriptCompiler.ts index 160038b..2ce632b 100644 --- a/compiler/src/ScriptCompiler.ts +++ b/compiler/src/ScriptCompiler.ts @@ -64,9 +64,7 @@ export class ScriptCompiler { const readStart = Date.now(); for (const entry of entries) { if (entry.isFile() && entry.name.endsWith('.lua')) { - - - const fullPath = path.join(entry.parentPath ?? entry.path, entry.name); + const fullPath = path.join(entry.parentPath, entry.name); const relativePath = path.relative(this.options.sourcePath, fullPath); const content = fs.readFileSync(fullPath, 'utf-8'); @@ -90,7 +88,7 @@ export class ScriptCompiler { const writeEnd = Date.now(); metricsMeter.writeTimeMs = (writeEnd - writeStart); - writer.logDependencyTree(); + // writer.logDependencyTree(); this.logger.info(`Compilation complete. Output written to ${path.join(this.options.outputPath, this.options.outputFileName!)}`); const end = Date.now(); @@ -370,16 +368,19 @@ class Writer { const depth : number = 1; this.logger.writeLine('Dependency Tree :'); const logFileRecursive = (parsedFile: ParsedFile, currentDepth: number) => { - if (visited.has(parsedFile.fileKey)) { + if(currentDepth === 0 && visited.has(parsedFile.fileKey)) { return; } + visited.add(parsedFile.fileKey); - let padding = ' '.repeat(currentDepth); + let padding = ' '.repeat(currentDepth * 2); if (currentDepth > 0) { - padding = ' '.repeat(currentDepth) + '└─>'; + padding += '└─>'; } + const printable = parsedFile.fileKey.replace(LUA_SCRIPT_GLOBAL_KEYWORD + '.', ''); - this.logger.writeLine(padding + printable); + const lastPart = printable.split('.').pop(); + this.logger.writeLine(`${padding} ${lastPart} ${' '.repeat(Math.max(0, 64 - padding.length - (lastPart ? lastPart.length : 0)))} ${printable}`); for (const dep of parsedFile.dependencies) { const depFile = this.files.get(dep.fileKey); if (depFile) { diff --git a/compiler/tsconfig.json b/compiler/tsconfig.json new file mode 100644 index 0000000..a3ea781 --- /dev/null +++ b/compiler/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "module": "Node16", + "target": "ES2022", + "lib": ["ES2022"], + "strict": true, + "sourceMap": true, + "types": ["node"], + "esModuleInterop": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src/**/*"] +} diff --git a/dutchies-dcs-scripting-tools/src/extension.ts b/dutchies-dcs-scripting-tools/src/extension.ts index 0075b7b..82517c1 100644 --- a/dutchies-dcs-scripting-tools/src/extension.ts +++ b/dutchies-dcs-scripting-tools/src/extension.ts @@ -26,9 +26,9 @@ export function activate(context: vscode.ExtensionContext) { pluginPath = context.asAbsolutePath('lua-addons'); context.subscriptions.push( - vscode.commands.registerCommand('dutchies-dcs-scripting-tools.enable', () => { + vscode.commands.registerCommand('dutchies-dcs-scripting-tools.enable', async () => { addPluginPathToSettings(); - vscode.commands.executeCommand( + await vscode.commands.executeCommand( "lua.startServer" ); vscode.window.showInformationMessage('Dutchies DCS Scripting Tools enabled.'); @@ -36,9 +36,9 @@ export function activate(context: vscode.ExtensionContext) { ); context.subscriptions.push( - vscode.commands.registerCommand('dutchies-dcs-scripting-tools.disable', () => { + vscode.commands.registerCommand('dutchies-dcs-scripting-tools.disable', async () => { removePluginPathFromSettings(); - vscode.commands.executeCommand( + await vscode.commands.executeCommand( "lua.startServer" ); vscode.window.showInformationMessage('Dutchies DCS Scripting Tools disabled.'); @@ -46,8 +46,8 @@ export function activate(context: vscode.ExtensionContext) { ); context.subscriptions.push( - vscode.commands.registerCommand('dutchies-dcs-scripting-tools.openSettings', () => { - vscode.commands.executeCommand("workbench.action.openSettings", `@ext:${extensionSettingsFilter}`); + vscode.commands.registerCommand('dutchies-dcs-scripting-tools.openSettings', async () => { + await vscode.commands.executeCommand("workbench.action.openSettings", `@ext:${extensionSettingsFilter}`); })); context.subscriptions.push( @@ -74,6 +74,18 @@ export function activate(context: vscode.ExtensionContext) { } }); + vscode.workspace.onDidChangeConfiguration(async(event) => { + if (event.affectsConfiguration(`${extensionName}.dcsTypes`)) { + const config = vscode.workspace.getConfiguration(extensionName); + const dcsTypesEnabled = config.get('dcsTypes') || false; + if (dcsTypesEnabled) { + addPluginPathToSettings(); + } else { + removePluginPathFromSettings(); + } + } + }); + logger.info('Dutchies DCS Scripting Tools extension activated'); } @@ -148,6 +160,22 @@ async function compileLuaScripts() { } } +async function enableIntellisense() { + addPluginPathToSettings(); + await vscode.commands.executeCommand( + "lua.startServer" + ); + vscode.window.showInformationMessage('Dutchies DCS Scripting Tools enabled.'); +} + +async function disableIntellisense() { + removePluginPathFromSettings(); + await vscode.commands.executeCommand( + "lua.startServer" + ); + vscode.window.showInformationMessage('Dutchies DCS Scripting Tools disabled.'); +} + function addPluginPathToSettings() { if (pluginPath) { const luaSettings = vscode.workspace.getConfiguration(luaWorkSpaceSettingKey); diff --git a/dutchies-dcs-scripting-tools/tsconfig.json b/dutchies-dcs-scripting-tools/tsconfig.json index 1816a24..b413cb5 100644 --- a/dutchies-dcs-scripting-tools/tsconfig.json +++ b/dutchies-dcs-scripting-tools/tsconfig.json @@ -11,7 +11,8 @@ "dcs-script-compiler": ["../compiler/src/ScriptCompiler.ts"] }, "types": [ - "node" + "node", + "mocha" ], /* Additional Checks */ "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ diff --git a/package-lock.json b/package-lock.json index e76ebb0..1a0b4f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dutchies-dcs-scripting-tools" ], "devDependencies": { + "@types/mocha": "^10.0.10", "@types/node": "^25.5.2" } }, @@ -911,7 +912,6 @@ "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", @@ -1144,7 +1144,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2081,7 +2080,6 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -5171,7 +5169,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -5302,7 +5299,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 6256f4e..d8351ff 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,15 @@ "dutchies-dcs-scripting-tools" ], "devDependencies": { - "@types/node": "^25.5.2" + "@types/vscode": "^1.108.1", + "@types/mocha": "^10.0.10", + "@types/node": "22.x", + "typescript-eslint": "^8.52.0", + "eslint": "^9.39.2", + "esbuild": "^0.27.2", + "npm-run-all": "^4.1.5", + "typescript": "^5.9.3", + "@vscode/test-cli": "^0.0.12", + "@vscode/test-electron": "^2.5.2" } } From fddf8e3946a16e21e0af7ba932c939c954799860 Mon Sep 17 00:00:00 2001 From: ex61wi <54616262+dutchie031@users.noreply.github.com> Date: Tue, 7 Apr 2026 10:46:17 +0200 Subject: [PATCH 8/8] Updated settings and script compilnig --- compiler/src/ScriptCompiler.ts | 23 ++++++++++-- dutchies-dcs-scripting-tools/README.md | 5 +++ dutchies-dcs-scripting-tools/package.json | 13 ++++++- dutchies-dcs-scripting-tools/src/extension.ts | 37 +++++++++++-------- 4 files changed, 57 insertions(+), 21 deletions(-) diff --git a/compiler/src/ScriptCompiler.ts b/compiler/src/ScriptCompiler.ts index 2ce632b..9ff433d 100644 --- a/compiler/src/ScriptCompiler.ts +++ b/compiler/src/ScriptCompiler.ts @@ -55,7 +55,7 @@ export class ScriptCompiler { } } - public async compile(): Promise { + public async compile(includeDevScript: boolean): Promise { const start = Date.now(); const metricsMeter = new Metrics(); const entries = fs.readdirSync(this.options.sourcePath, { recursive: true, withFileTypes: true }); @@ -84,7 +84,7 @@ export class ScriptCompiler { ); const writeStart = Date.now(); - writer.write(metricsMeter); + writer.write(includeDevScript, metricsMeter); const writeEnd = Date.now(); metricsMeter.writeTimeMs = (writeEnd - writeStart); @@ -394,7 +394,7 @@ class Writer { } }; - write(metrics: Metrics): void { + write(includeDevScript: boolean, metrics: Metrics): void { const writtenFiles: Set = new Set(); const outputLines: string[] = []; @@ -475,5 +475,22 @@ class Writer { fs.mkdirSync(path.dirname(this.location), { recursive: true }); fs.writeFileSync(this.location, outputLines.join('\n'), 'utf-8'); + + if(includeDevScript) { + const devFileLocation = this.location.replace('.lua', '.dev.lua'); + this.writeDevScript(devFileLocation, this.location); + } + } + + private writeDevScript(devFileLocation: string, actualFileLocation: string){ + const devLines = [ + `-- DEV SCRIPT - NOT FOR PRODUCTION USE`, + `-- This script can be referenced in DCS. Compiled script will then be loaded dynamically.`, + `-- This way you can test the compiled output without having to re-import the script into the mission every time.`, + `-- This file will only have to be re-imported when the name or location of the compiled script file changes.`, + `assert(loadfile("${actualFileLocation}"))()` + ]; + fs.writeFileSync(devFileLocation, devLines.join('\n'), 'utf-8'); + this.logger.info(`Development script written to ${devFileLocation}`); } } \ No newline at end of file diff --git a/dutchies-dcs-scripting-tools/README.md b/dutchies-dcs-scripting-tools/README.md index 67cd679..e4b526f 100644 --- a/dutchies-dcs-scripting-tools/README.md +++ b/dutchies-dcs-scripting-tools/README.md @@ -11,6 +11,11 @@ Direct DCS API checking and a Transpiler that can help keep huge complex scripts ## Release Notes +### 0.0.2 + +- Improved error handling and reporting in the script compiler. +- Added Output channel for compilation logs and errors. +- Improved Settings for better user experience. ### 0.0.1 diff --git a/dutchies-dcs-scripting-tools/package.json b/dutchies-dcs-scripting-tools/package.json index d818eca..2686a55 100644 --- a/dutchies-dcs-scripting-tools/package.json +++ b/dutchies-dcs-scripting-tools/package.json @@ -49,8 +49,17 @@ "type": "boolean", "default": false, "description": "Adds an additional script. This can be referenced from DCS through doScriptFile. This will then execute the compiles script. This way you don't have to reinsert the script on each change, but can just hit 'restart'." - } - + }, + "dutchies-dcs-scripting-tools.luaSrcDirectory" : { + "type":"string", + "default": "${workspaceFolder}/src", + "description": "Where the source files start. default: ${workspaceFolder}/src" + }, + "dutchies-dcs-scripting-tools.luaOutputPath" : { + "type":"string", + "default": "${workspaceFolder}/dist", + "description": "Where the compiled Lua files will be output. default: ${workspaceFolder}/dist" + } } }, "grammars": [ diff --git a/dutchies-dcs-scripting-tools/src/extension.ts b/dutchies-dcs-scripting-tools/src/extension.ts index 82517c1..e2f903d 100644 --- a/dutchies-dcs-scripting-tools/src/extension.ts +++ b/dutchies-dcs-scripting-tools/src/extension.ts @@ -27,21 +27,13 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.commands.registerCommand('dutchies-dcs-scripting-tools.enable', async () => { - addPluginPathToSettings(); - await vscode.commands.executeCommand( - "lua.startServer" - ); - vscode.window.showInformationMessage('Dutchies DCS Scripting Tools enabled.'); + enableIntellisense(); }) ); context.subscriptions.push( vscode.commands.registerCommand('dutchies-dcs-scripting-tools.disable', async () => { - removePluginPathFromSettings(); - await vscode.commands.executeCommand( - "lua.startServer" - ); - vscode.window.showInformationMessage('Dutchies DCS Scripting Tools disabled.'); + disableIntellisense(); }) ); @@ -116,11 +108,10 @@ async function compileLuaScripts() { logger.clear(); logger.info("Compiling..."); - const config = vscode.workspace.getConfiguration('dcsScriptingTools'); - const sourcePath = config.get('luaSourcePath') || '${workspaceFolder}/src'; + const config = vscode.workspace.getConfiguration(extensionName); + const sourcePath = config.get('luaSrcDirectory') || '${workspaceFolder}/src'; const outputPath = config.get('luaOutputPath') || '${workspaceFolder}/dist'; - const minify = config.get('minifyLuaScripts') || false; - + const resolvedSourcePath = sourcePath.replace('${workspaceFolder}', vscode.workspace.workspaceFolders?.[0].uri.fsPath || ''); const resolvedOutputPath = outputPath.replace('${workspaceFolder}', vscode.workspace.workspaceFolders?.[0].uri.fsPath || ''); @@ -130,7 +121,7 @@ async function compileLuaScripts() { const options: ScriptCompilerOptions = { sourcePath: resolvedSourcePath, outputPath: resolvedOutputPath, - minify: minify, + minify: false, onError: (error: CompilationError) => { const errors = errorsByFile.get(error.filePath) || []; errors.push(error); @@ -140,8 +131,11 @@ async function compileLuaScripts() { const compilationLogger = new CompilationLogger(logger); const compiler = new ScriptCompiler(options, compilationLogger); + + const includeDevScript = config.get('includeDevelopmentScript') || false; + try { - await compiler.compile(); + await compiler.compile(includeDevScript); } catch (err) { vscode.window.showErrorMessage('Compilation failed: ' + (err as Error).message); } @@ -161,6 +155,12 @@ async function compileLuaScripts() { } async function enableIntellisense() { + + const config = vscode.workspace.getConfiguration(extensionName); + if (config.get("dcsTypes") === false) { + config.update("dcsTypes", true, vscode.ConfigurationTarget.Workspace); + } + addPluginPathToSettings(); await vscode.commands.executeCommand( "lua.startServer" @@ -169,6 +169,11 @@ async function enableIntellisense() { } async function disableIntellisense() { + const config = vscode.workspace.getConfiguration(extensionName); + if (config.get("dcsTypes") === true) { + config.update("dcsTypes", false, vscode.ConfigurationTarget.Workspace); + } + removePluginPathFromSettings(); await vscode.commands.executeCommand( "lua.startServer"