diff --git a/.vscode/settings.json b/.vscode/settings.json index 34bb6a0..0313b05 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,7 @@ "reimplementation" ], "Lua.diagnostics.globals": [ - "net" + "net", + "log" ] } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 99ee51e..3cee0b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,16 +34,25 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how ### Fixed - Fix link to original DCS Fiddle install instructions. -## [1.0.2] +## [1.0.2] - 2024-01-16 ### Fixed - Fix buttons getting separated by other extensions. -## [1.1.0] +## [1.1.0] - 2024-01-31 ### Added -- Option to display return in a json side window, taking advantage of syntax highlighting. +- Option to display return in a json side window (file), taking advantage of syntax highlighting. - Status bar item to quickly switch between local and remote DCS server, mission and GUI environment, and open settings . ### Changed -- Quick switch buttons next to the run code button is now hidden by default, superseded by the status bar item. These buttons take up too much space, especially when displaying return in json side window mode. \ No newline at end of file +- Quick switch buttons next to the run code button is now hidden by default, superseded by the status bar item. These buttons take up too much space, especially when displaying return in json side window mode. + +## [1.1.1] - 2024-02-02 + +### Added +- Option to display return in Lua table format, both in side window (file) and output panel. +(Experimental feature, please report any issue.) + +### Changed +- Change default return display to file to take advantage of syntax highlight. \ No newline at end of file diff --git a/README.md b/README.md index 50f9b05..6123943 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # DCS Lua Runner -A VS Code extension to run lua code in DCS World (local or remote server). A reimplementation of the [DCS Fiddle](https://github.com/JonathanTurnock/dcsfiddle) web lua console. +A VS Code extension to run lua code in DCS World (on local or remote server, in mission or GUI environment). A reimplementation of the [DCS Fiddle](https://github.com/JonathanTurnock/dcsfiddle) web lua console. Allows for quick development and debugging of running scripted missions directly from the comfort of VS Code. -![Demo1](docs/img/demo1.png) +![Demo1](docs/img/demo1-new.png) ![Demo2-1](docs/img/demo2-1.png) ![Demo2-2](docs/img/demo2-2.png) @@ -35,7 +35,7 @@ For even better security, put the Fiddle port behind a reverse proxy with HTTPS. ## Extension Settings -This extension contributes the following settings: +This extension has the following settings: - `dcsLuaRunner.serverAddress`: Remote DCS server address. It can be an IP address or a domain. @@ -57,9 +57,10 @@ This setting can be quickly changed with the buttons on the upper-right of a lua - `dcsLuaRunner.runInMissionEnv`: Specifies whether to execute in mission or GUI Scripting Environment. This setting can be quickly changed with the buttons on the upper-right of a lua file. -## Known Issues +**NEW:** +- `dcsLuaRunner.returnDisplay`: Wether to use output panel or file (which supports syntax highlight) to display return value. -The return value is displayed on in the output window, which unfortunately does not support syntax highlight. Possibilities to display return in other ways are being looked into. +- `dcsLuaRunner.returnDisplayFormat`: Display return value as JSON or Lua table. (Experimental feature, please report any issue.) ## Release Notes diff --git a/docs/img/demo1-new.png b/docs/img/demo1-new.png new file mode 100644 index 0000000..af78825 Binary files /dev/null and b/docs/img/demo1-new.png differ diff --git a/package.json b/package.json index 327a430..9d19098 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Quickly run lua code in DCS World (local or remote server). A reimplementation of the DCS Fiddle lua console in VS Code.", "license": "MIT", "publisher": "omltcat", - "version": "1.1.0", + "version": "1.1.1", "icon": "docs/img/icon.png", "repository": { "type": "git", @@ -61,10 +61,16 @@ }, "dcsLuaRunner.returnDisplay": { "type": "string", - "enum": ["Console Output", "Json File"], - "default": "Console Output", + "enum": ["Output Panel (Scrolling Plain Text)", "Show File (Syntax Highlight)"], + "default": "Show File (Syntax Highlight)", "description": "How data returned from DCS is displayed." }, + "dcsLuaRunner.returnDisplayFormat": { + "type": "string", + "enum": ["Lua Table", "JSON"], + "default": "JSON", + "description": "Note: Experimental feature! Original returned data is in JSON. Conversion to Lua table is done after receiving data and may not be 100% accurate. Please report any issues." + }, "dcsLuaRunner.showQuickButtons": { "type": "boolean", "default": false, diff --git a/src/extension.ts b/src/extension.ts index c5471f7..e09afea 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -2,12 +2,12 @@ import * as vscode from 'vscode'; import axios from 'axios'; import * as fs from 'fs'; import * as path from 'path'; -import { config } from 'process'; async function runLua(lua: string, outputChannel: vscode.OutputChannel, filename: string = 'none') { const lua_base64 = Buffer.from(lua).toString('base64'); const config = vscode.workspace.getConfiguration('dcsLuaRunner'); - const returnDisplay = config.get('returnDisplay') as string; + const returnDisplay = config.get('returnDisplay') === 'Output Panel (Scrolling Plain Text)' ? 'output' : 'file' as string; + const returnDisplayFormat = config.get('returnDisplayFormat') === 'JSON' ? 'json' : 'lua' as string; const runCodeLocally = config.get('runCodeLocally') as boolean; const runInMissionEnv = config.get('runInMissionEnv') as boolean; const serverAddress = runCodeLocally ? '127.0.0.1' : config.get('serverAddress') as string; @@ -18,14 +18,16 @@ async function runLua(lua: string, outputChannel: vscode.OutputChannel, filename const protocol = useHttps ? 'https' : 'http'; const envName = runInMissionEnv ? 'Mission' : 'GUI'; + const logInfo = `${envName}@${serverAddress}:${serverPort} <- ${filename}` + const displayOutput = async (output: Object) => { - if (returnDisplay === 'Console Output') { + if (returnDisplay === 'output') { outputChannel.show(true); - outputChannel.appendLine(`[DCS] ${new Date().toLocaleString()} (${envName}@${serverAddress}:${serverPort} <- ${filename}):\n${JSON.stringify(output, null, 2)}`); - } else if (returnDisplay === 'Json File') { + outputChannel.appendLine(`[DCS] ${new Date().toLocaleString()} (${logInfo}):\n${format(JSON.stringify(output, null, 4))}`); + } else if (returnDisplay === 'file') { const activeEditor = vscode.window.activeTextEditor; const workspaceFolder = vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders[0].uri.fsPath : ''; - const filePath = `${workspaceFolder}/.vscode/dcs_lua_output.json`; + const filePath = `${workspaceFolder}/.vscode/dcs_lua_output.${returnDisplayFormat}`; // Create the file if it doesn't exist if (!fs.existsSync(filePath)) { fs.writeFileSync(filePath, ''); @@ -35,7 +37,7 @@ async function runLua(lua: string, outputChannel: vscode.OutputChannel, filename const viewColumn = vscode.window.activeTextEditor && vscode.window.activeTextEditor.viewColumn === vscode.ViewColumn.Two ? vscode.ViewColumn.Two : vscode.ViewColumn.Beside; const editor = await vscode.window.showTextDocument(document, viewColumn); await editor.edit(editBuilder => { - editBuilder.replace(new vscode.Range(document.lineAt(0).range.start, document.lineAt(document.lineCount - 1).range.end), JSON.stringify(output, null, 2)); + editBuilder.replace(new vscode.Range(document.lineAt(0).range.start, document.lineAt(document.lineCount - 1).range.end), format(JSON.stringify(output, null, 4))); }); await document.save(); @@ -44,6 +46,26 @@ async function runLua(lua: string, outputChannel: vscode.OutputChannel, filename } } } + const format = (jsonString: string): string => { + if (returnDisplayFormat === 'json') { + return jsonString; + } + + let luaString = jsonString; + // Replace JSON syntax with Lua syntax + luaString = luaString.replace(/"([^"]+)":/g, '["$1"] ='); // Replace "key": with ["key"] = + luaString = luaString.replace(/"_([0-9]+)":/g, '[$1] ='); // Replace "_n": with [n] = + luaString = luaString.replace(/null/g, 'nil'); // Replace null with nil + luaString = luaString.replace(/\[\n/g, '{\n'); // Replace [ followed by a line break with { followed by a line break + luaString = luaString.replace(/]\n/g, '}\n'); // Replace ] followed by a line break with } followed by a line break + luaString = luaString.replace(/],/g, '},'); // Replace ], with }, + luaString = luaString.replace(/]\s*$/g, '}'); // Replace ] at the end of the string with } + + if (returnDisplay === 'file') { + luaString = `return --${logInfo}\n` + luaString; + } + return luaString; + } try { const response = await axios.get(`${protocol}://${serverAddress}:${serverPort}/${lua_base64}?env=default`, { @@ -58,7 +80,7 @@ async function runLua(lua: string, outputChannel: vscode.OutputChannel, filename if (response.data.hasOwnProperty('result')) { displayOutput(response.data.result); } else { - displayOutput({"SUCCESSFUL EXECUTION": "NO RETURN VALUE"}); + displayOutput("SUCCESSFUL EXECUTION - NO RETURN VALUE"); } } catch (error: any) { if (error.response && error.response.status === 500) {