diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e219aa..99ee51e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,4 +37,13 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how ## [1.0.2] ### Fixed -- Fix buttons getting separated by other extensions. \ No newline at end of file +- Fix buttons getting separated by other extensions. + +## [1.1.0] + +### Added +- Option to display return in a json side window, 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 diff --git a/package.json b/package.json index c0d961e..327a430 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.0.2", + "version": "1.1.0", "icon": "docs/img/icon.png", "repository": { "type": "git", @@ -16,7 +16,9 @@ "Programming Languages", "Debuggers" ], - "activationEvents": [], + "activationEvents": [ + "onLanguage:lua" + ], "main": "./out/extension.js", "contributes": { "configuration": { @@ -56,6 +58,17 @@ "type": "boolean", "default": true, "description": "Execute in mission or GUI Scripting Environment." + }, + "dcsLuaRunner.returnDisplay": { + "type": "string", + "enum": ["Console Output", "Json File"], + "default": "Console Output", + "description": "How data returned from DCS is displayed." + }, + "dcsLuaRunner.showQuickButtons": { + "type": "boolean", + "default": false, + "description": "Show buttons to quickly switch settings beside the run button." } } }, @@ -68,22 +81,22 @@ }, { "command": "dcs-lua-runner.set-local-button", - "when": "editorLangId == lua && config.dcsLuaRunner.runCodeLocally == false", + "when": "editorLangId == lua && config.dcsLuaRunner.runCodeLocally == false && config.dcsLuaRunner.showQuickButtons == true", "group": "navigation@-5" }, { "command": "dcs-lua-runner.set-remote-button", - "when": "editorLangId == lua && config.dcsLuaRunner.runCodeLocally == true", + "when": "editorLangId == lua && config.dcsLuaRunner.runCodeLocally == true && config.dcsLuaRunner.showQuickButtons == true", "group": "navigation@-5" }, { "command": "dcs-lua-runner.set-missionEnv-button", - "when": "editorLangId == lua && config.dcsLuaRunner.runInMissionEnv == false", + "when": "editorLangId == lua && config.dcsLuaRunner.runInMissionEnv == false && config.dcsLuaRunner.showQuickButtons == true", "group": "navigation@-4" }, { "command": "dcs-lua-runner.set-guiEnv-button", - "when": "editorLangId == lua && config.dcsLuaRunner.runInMissionEnv == true", + "when": "editorLangId == lua && config.dcsLuaRunner.runInMissionEnv == true && config.dcsLuaRunner.showQuickButtons == true", "group": "navigation@-4" } ], diff --git a/src/extension.ts b/src/extension.ts index 19269c2..c5471f7 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -2,10 +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 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; @@ -15,6 +17,34 @@ async function runLua(lua: string, outputChannel: vscode.OutputChannel, filename const authPassword = config.get('webAuthPassword') as string; const protocol = useHttps ? 'https' : 'http'; const envName = runInMissionEnv ? 'Mission' : 'GUI'; + + const displayOutput = async (output: Object) => { + if (returnDisplay === 'Console 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') { + const activeEditor = vscode.window.activeTextEditor; + const workspaceFolder = vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders[0].uri.fsPath : ''; + const filePath = `${workspaceFolder}/.vscode/dcs_lua_output.json`; + // Create the file if it doesn't exist + if (!fs.existsSync(filePath)) { + fs.writeFileSync(filePath, ''); + } + + const document = await vscode.workspace.openTextDocument(vscode.Uri.file(filePath)); + 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)); + }); + await document.save(); + + if (activeEditor) { + vscode.window.showTextDocument(activeEditor.document, activeEditor.viewColumn); + } + } + } + try { const response = await axios.get(`${protocol}://${serverAddress}:${serverPort}/${lua_base64}?env=default`, { auth: { @@ -26,14 +56,14 @@ async function runLua(lua: string, outputChannel: vscode.OutputChannel, filename outputChannel.show(true); if (response.data.hasOwnProperty('result')) { - outputChannel.appendLine(`[DCS] ${new Date().toLocaleString()} (${envName}@${serverAddress}:${serverPort} <- ${filename}):\n${JSON.stringify(response.data.result, null, 2)}`); + displayOutput(response.data.result); } else { - outputChannel.appendLine(`[DCS] ${new Date().toLocaleString()} (${envName}@${serverAddress}:${serverPort} <- ${filename}):\n`); + displayOutput({"SUCCESSFUL EXECUTION": "NO RETURN VALUE"}); } } catch (error: any) { if (error.response && error.response.status === 500) { vscode.window.showErrorMessage('Internal server error occurred.'); - outputChannel.appendLine(`[DCS] ${new Date().toLocaleString()} (${envName}@${serverAddress}:${serverPort} <- ${filename}):\n${JSON.stringify(error.response.data.error, null, 2)}`); + displayOutput(error.response.data.error); } else { vscode.window.showErrorMessage(`Error: ${error}`); } @@ -58,6 +88,7 @@ function getCurrentFileLua() { } export function activate(context: vscode.ExtensionContext) { + const config = vscode.workspace.getConfiguration('dcsLuaRunner'); let outputChannel = vscode.window.createOutputChannel("DCS Lua Runner"); context.subscriptions.push(vscode.commands.registerCommand('dcs-lua-runner.open-settings', () => { @@ -99,8 +130,12 @@ export function activate(context: vscode.ExtensionContext) { const runEnv = runInMissionEnv ? 'mission' : 'GUI'; const serverAddress = runCodeLocally ? '127.0.0.1' : config.get('serverAddress') as string; const serverPort = runCodeLocally ? 12080 : config.get('serverPort') as number + (runInMissionEnv ? 0 : 1); - outputChannel.show(true); - outputChannel.appendLine(`[DCS] Settings: Run code in ${runEnv} environment on ${runTarget} (${serverAddress}:${serverPort}).`); + if (config.get('returnDisplay') === 'Console Output') { + outputChannel.show(true); + outputChannel.appendLine(`[DCS] Settings: Run code in ${runEnv} environment on ${runTarget} (${serverAddress}:${serverPort}).`); + } else { + vscode.window.showInformationMessage(`Run code in ${runEnv} environment on ${serverAddress}:${serverPort}`); + } }; const updateSetting = async (setting: string, targetState: boolean) => { @@ -140,6 +175,53 @@ export function activate(context: vscode.ExtensionContext) { if (vscode.window.activeTextEditor) { vscode.commands.executeCommand('setContext', 'luaFileActive', vscode.window.activeTextEditor.document.languageId === 'lua'); } + let statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100); + statusBarItem.tooltip = 'DCS Lua Runner: Click to change settings'; + statusBarItem.show(); + statusBarItem.command = 'extension.showQuickPick'; + context.subscriptions.push(statusBarItem); + + function updateStatusBarItem() { + const config = vscode.workspace.getConfiguration('dcsLuaRunner'); + const editor = vscode.window.activeTextEditor; + const isLuaFile = editor && editor.document.languageId === 'lua'; + const runCodeLocally = config.get('runCodeLocally') ? 'Local' : 'Remote'; + const runInMissionEnv = config.get('runInMissionEnv') ? 'Mission' : 'GUI'; + + if (isLuaFile) { + statusBarItem.text = `DCS: ${runCodeLocally}, Env: ${runInMissionEnv}`; + statusBarItem.show(); + } else { + statusBarItem.hide(); + } + } + + vscode.commands.registerCommand('extension.showQuickPick', () => { + const items = [ + { label: 'DCS Lua: Set Run Code on Local Machine', command: 'dcs-lua-runner.set-local' }, + { label: 'DCS Lua: Set Run Code on Remote Server', command: 'dcs-lua-runner.set-remote' }, + { label: 'DCS Lua: Set Run Code in Mission Environment', command: 'dcs-lua-runner.set-missionEnv' }, + { label: 'DCS Lua: Set Run Code in GUI Environment', command: 'dcs-lua-runner.set-guiEnv' }, + { label: 'DCS Lua: Open Settings', command: 'dcs-lua-runner.open-settings' } + ]; + vscode.window.showQuickPick(items).then(selection => { + // the user picked an item from the list + if (!selection) { + return; + } + + // execute the selected command + vscode.commands.executeCommand(selection.command); + }); + }); + + // Update the status bar when the configuration changes or the active text editor changes + context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(updateStatusBarItem)); + context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(updateStatusBarItem)); + context.subscriptions.push(vscode.workspace.onDidOpenTextDocument(updateStatusBarItem)); + context.subscriptions.push(vscode.workspace.onDidCloseTextDocument(updateStatusBarItem)); + + updateStatusBarItem(); } export function deactivate() {} \ No newline at end of file