From 0e1dcc9bb2e470e1bd4a625642bd36c078ffbe23 Mon Sep 17 00:00:00 2001 From: ninjaguardian Date: Sat, 6 Sep 2025 11:52:08 -0500 Subject: [PATCH 1/2] Add settings to override objects that would merge with default --- README.md | 5 ++++- package.json | 24 ++++++++++++++++++++++++ src/codeManager.ts | 28 +++++++++++++++++++++++----- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e0dd796..bfedb5b 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,9 @@ Also, you could set the executor per file extension: } ``` +**Note:** All of `code-runner.executorMapByFileExtension`, `code-runner.executorMapByGlob`, and `code-runner.executorMap` merge the default setting with what you set. If you want to remove one of the defaults, you can switch your setting to use `code-runner.executorMapByFileExtensionOverride`, `code-runner.executorMapByGlobOverride`, and `code-runner.executorMapOverride` respectively. +Also, setting an override to only `{ "": "" }` may not work as expected. Make sure the key is not blank. + To set the custom command to run: ```json { @@ -127,7 +130,7 @@ To set the custom command to run: } ``` -To set the the working directory: +To set the working directory: ```json { "code-runner.cwd": "path/to/working/directory" diff --git a/package.json b/package.json index 075781c..0f6ca36 100644 --- a/package.json +++ b/package.json @@ -129,6 +129,12 @@ "description": "Set the executor by glob.", "scope": "resource" }, + "code-runner.executorMapByGlobOverride": { + "type": "object", + "default": {}, + "description": "If set, overrides `code-runner.executorMapByGlob` without merging the default settings.", + "scope": "resource" + }, "code-runner.executorMap": { "type": "object", "default": { @@ -193,6 +199,12 @@ "description": "Set the executor of each language.", "scope": "resource" }, + "code-runner.executorMapOverride": { + "type": "object", + "default": {}, + "description": "If set, overrides `code-runner.executorMap` without merging the default settings.", + "scope": "resource" + }, "code-runner.executorMapByFileExtension": { "type": "object", "default": { @@ -236,6 +248,12 @@ "description": "Set the executor of each file extension.", "scope": "resource" }, + "code-runner.executorMapByFileExtensionOverride": { + "type": "object", + "default": {}, + "description": "If set, overrides `code-runner.executorMapByFileExtension` without merging the default settings.", + "scope": "resource" + }, "code-runner.customCommand": { "type": "string", "default": "echo Hello", @@ -252,6 +270,12 @@ "description": "Set the mapping of languageId to file extension.", "scope": "resource" }, + "code-runner.languageIdToFileExtensionMapOverride": { + "type": "object", + "default": {}, + "description": "If set, overrides `code-runner.languageIdToFileExtensionMap` without merging the default settings.", + "scope": "resource" + }, "code-runner.defaultLanguage": { "type": "string", "default": "", diff --git a/src/codeManager.ts b/src/codeManager.ts index 3de6e2e..a43a1e3 100644 --- a/src/codeManager.ts +++ b/src/codeManager.ts @@ -95,7 +95,7 @@ export class CodeManager implements vscode.Disposable { public runByLanguage(): void { this._appInsightsClient.sendEvent("runByLanguage"); const config = this.getConfiguration("code-runner"); - const executorMap = config.get("executorMap"); + const executorMap = this.getExecutorMap(config); vscode.window.showQuickPick(Object.keys(executorMap), { placeHolder: "Type or select language to run" }).then((languageId) => { if (languageId !== undefined) { this.run(languageId); @@ -220,7 +220,10 @@ export class CodeManager implements vscode.Disposable { private createRandomFile(content: string, folder: string, fileExtension: string) { let fileType = ""; - const languageIdToFileExtensionMap = this._config.get("languageIdToFileExtensionMap"); + let languageIdToFileExtensionMap = this._config.get("languageIdToFileExtensionMapOverride"); + if (!languageIdToFileExtensionMap || Object.keys(languageIdToFileExtensionMap).length === 0) { + languageIdToFileExtensionMap = this._config.get("languageIdToFileExtensionMap"); + } if (this._languageId && languageIdToFileExtensionMap[this._languageId]) { fileType = languageIdToFileExtensionMap[this._languageId]; } else { @@ -251,7 +254,11 @@ export class CodeManager implements vscode.Disposable { } if (executor == null) { - const executorMapByGlob = this._config.get("executorMapByGlob"); + let executorMapByGlob = this._config.get("executorMapByGlobOverride", {}); + if (!executorMapByGlob || Object.keys(executorMapByGlob).length === 0) { + executorMapByGlob = this._config.get("executorMapByGlob"); + } + if (executorMapByGlob) { const fileBasename = basename(this._document.fileName); for (const glob of Object.keys(executorMapByGlob)) { @@ -263,7 +270,7 @@ export class CodeManager implements vscode.Disposable { } } - const executorMap = this._config.get("executorMap"); + const executorMap = this.getExecutorMap(this._config); if (executor == null) { executor = executorMap[this._languageId]; @@ -271,7 +278,10 @@ export class CodeManager implements vscode.Disposable { // executor is undefined or null if (executor == null && fileExtension) { - const executorMapByFileExtension = this._config.get("executorMapByFileExtension"); + let executorMapByFileExtension = this._config.get("executorMapByFileExtensionOverride", {}); + if (!executorMapByFileExtension || Object.keys(executorMapByFileExtension).length === 0) { + executorMapByFileExtension = this._config.get("executorMapByFileExtension"); + } executor = executorMapByFileExtension[fileExtension]; if (executor != null) { this._languageId = fileExtension; @@ -285,6 +295,14 @@ export class CodeManager implements vscode.Disposable { return executor; } + private getExecutorMap(config: vscode.WorkspaceConfiguration): any { + const executorMapOverride = config.get("executorMapOverride", {}); + if (!executorMapOverride || Object.keys(executorMapOverride).length === 0) { + return config.get("executorMap"); + } + return executorMapOverride; + } + private executeCommand(executor: string, appendFile: boolean = true) { if (this._config.get("runInTerminal")) { this.executeCommandInTerminal(executor, appendFile); From 6a064fe5a9c40cdd54b4913c4b97b9f360ca015a Mon Sep 17 00:00:00 2001 From: ninjaguardian Date: Sat, 6 Sep 2025 12:46:30 -0500 Subject: [PATCH 2/2] Handle empty keys --- README.md | 1 - src/codeManager.ts | 50 +++++++++++++++++++++------------------------- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index bfedb5b..af858a0 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,6 @@ Also, you could set the executor per file extension: ``` **Note:** All of `code-runner.executorMapByFileExtension`, `code-runner.executorMapByGlob`, and `code-runner.executorMap` merge the default setting with what you set. If you want to remove one of the defaults, you can switch your setting to use `code-runner.executorMapByFileExtensionOverride`, `code-runner.executorMapByGlobOverride`, and `code-runner.executorMapOverride` respectively. -Also, setting an override to only `{ "": "" }` may not work as expected. Make sure the key is not blank. To set the custom command to run: ```json diff --git a/src/codeManager.ts b/src/codeManager.ts index a43a1e3..8be5cfe 100644 --- a/src/codeManager.ts +++ b/src/codeManager.ts @@ -220,18 +220,15 @@ export class CodeManager implements vscode.Disposable { private createRandomFile(content: string, folder: string, fileExtension: string) { let fileType = ""; - let languageIdToFileExtensionMap = this._config.get("languageIdToFileExtensionMapOverride"); - if (!languageIdToFileExtensionMap || Object.keys(languageIdToFileExtensionMap).length === 0) { - languageIdToFileExtensionMap = this._config.get("languageIdToFileExtensionMap"); - } - if (this._languageId && languageIdToFileExtensionMap[this._languageId]) { - fileType = languageIdToFileExtensionMap[this._languageId]; - } else { - if (fileExtension) { - fileType = fileExtension; - } else { - fileType = "." + this._languageId; + if (this._languageId && this._languageId !== "") { + let languageIdToFileExtensionMap = this._config.get("languageIdToFileExtensionMapOverride", {}); + if (Object.keys(languageIdToFileExtensionMap).length === 0) { + languageIdToFileExtensionMap = this._config.get("languageIdToFileExtensionMap", {}); } + + fileType = languageIdToFileExtensionMap[this._languageId] ?? fileExtension ?? ("." + this._languageId); + } else { + fileType = fileExtension ?? ("." + (this._languageId || "")); } const temporaryFileName = this._config.get("temporaryFileName"); const tmpFileNameWithoutExt = temporaryFileName ? temporaryFileName : "temp" + this.rndName(); @@ -255,17 +252,16 @@ export class CodeManager implements vscode.Disposable { if (executor == null) { let executorMapByGlob = this._config.get("executorMapByGlobOverride", {}); - if (!executorMapByGlob || Object.keys(executorMapByGlob).length === 0) { - executorMapByGlob = this._config.get("executorMapByGlob"); + if (Object.keys(executorMapByGlob).length === 0) { + executorMapByGlob = this._config.get("executorMapByGlob", {}); } - if (executorMapByGlob) { - const fileBasename = basename(this._document.fileName); - for (const glob of Object.keys(executorMapByGlob)) { - if (micromatch.isMatch(fileBasename, glob)) { - executor = executorMapByGlob[glob]; - break; - } + executorMapByGlob = Object.fromEntries(Object.entries(executorMapByGlob).filter(([key]) => key !== "")) + const fileBasename = basename(this._document.fileName); + for (const glob of Object.keys(executorMapByGlob)) { + if (micromatch.isMatch(fileBasename, glob)) { + executor = executorMapByGlob[glob]; + break; } } } @@ -277,10 +273,10 @@ export class CodeManager implements vscode.Disposable { } // executor is undefined or null - if (executor == null && fileExtension) { + if (executor == null && fileExtension && fileExtension !== "") { let executorMapByFileExtension = this._config.get("executorMapByFileExtensionOverride", {}); - if (!executorMapByFileExtension || Object.keys(executorMapByFileExtension).length === 0) { - executorMapByFileExtension = this._config.get("executorMapByFileExtension"); + if (Object.keys(executorMapByFileExtension).length === 0) { + executorMapByFileExtension = this._config.get("executorMapByFileExtension", {}); } executor = executorMapByFileExtension[fileExtension]; if (executor != null) { @@ -296,11 +292,11 @@ export class CodeManager implements vscode.Disposable { } private getExecutorMap(config: vscode.WorkspaceConfiguration): any { - const executorMapOverride = config.get("executorMapOverride", {}); - if (!executorMapOverride || Object.keys(executorMapOverride).length === 0) { - return config.get("executorMap"); + let executorMap = config.get("executorMapOverride", {}); + if (Object.keys(executorMap).length === 0) { + executorMap = config.get("executorMap", {}); } - return executorMapOverride; + return Object.fromEntries(Object.entries(executorMap).filter(([key]) => key !== "")); } private executeCommand(executor: string, appendFile: boolean = true) {