Skip to content

Commit

Permalink
Resolve #88: Run file through context menu of file explorer
Browse files Browse the repository at this point in the history
  • Loading branch information
formulahendry committed Oct 25, 2017
1 parent 3571b9d commit 7b7dccb
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 50 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### 0.8.0 (2017-10-25)
* [#88](https://github.com/formulahendry/vscode-code-runner/issues/88): Run file through context menu of file explorer

### 0.7.4 (2017-10-20)
* [#191](https://github.com/formulahendry/vscode-code-runner/issues/191): Stop running code when VS Code is closed

Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ If you like this extension, you could donate via **[PayPal](https://www.paypal.m
## Features

* Run code file of current active Text Editor
* Run code file through context menu of file explorer
* Run selected code snippet in Text Editor
* Run custom command
* Stop code running
Expand All @@ -23,8 +24,16 @@ If you like this extension, you could donate via **[PayPal](https://www.paypal.m

## Usages

* Open code file or select code snippet in Text Editor, then use shortcut `Ctrl+Alt+N`, or press `F1` and then select/type `Run Code`, or right click the Text Editor and then click `Run Code` in editor context menu, or click `Run Code` button in editor title menu, the code will run and the output will be shown in the Output Window.
* To stop the running code, use shortcut `Ctrl+Alt+M`, or press `F1` and then select/type `Stop Code Run`, or right click the Output Channel and then click `Stop Code Run` in context menu
* To run code:
* use shortcut `Ctrl+Alt+N`
* or press `F1` and then select/type `Run Code`,
* or right click the Text Editor and then click `Run Code` in editor context menu
* or click `Run Code` button in editor title menu
* or click `Run Code` button in context menu of file explorer
* To stop the running code:
* use shortcut `Ctrl+Alt+M`
* or press `F1` and then select/type `Stop Code Run`
* or right click the Output Channel and then click `Stop Code Run` in context menu

![Usage](images/usage.gif)

Expand Down
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "code-runner",
"displayName": "Code Runner",
"description": "Run C, C++, Java, JS, PHP, Python, Perl, Ruby, Go, Lua, Groovy, PowerShell, CMD, BASH, F#, C#, VBScript, TypeScript, CoffeeScript, Scala, Swift, Julia, Crystal, OCaml, R, AppleScript, Elixir, VB.NET, Clojure, Haxe, Objective-C, Rust, Racket, AutoHotkey, AutoIt, Kotlin, Dart, Pascal, Haskell, Nim, D",
"version": "0.7.4",
"version": "0.8.0",
"publisher": "formulahendry",
"icon": "images/logo.png",
"engines": {
Expand Down Expand Up @@ -94,6 +94,13 @@
"command": "code-runner.run",
"group": "navigation"
}
],
"explorer/context": [
{
"when": "!explorerResourceIsFolder",
"command": "code-runner.run",
"group": "navigation"
}
]
},
"configuration": {
Expand Down
4 changes: 2 additions & 2 deletions src/appInsightsClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ export class AppInsightsClient {
this._enableAppInsights = config.get<boolean>("enableAppInsights");
}

public sendEvent(eventName: string): void {
public sendEvent(eventName: string, properties?: { [key: string]: string; }): void {
if (this._enableAppInsights) {
for (const i in compilers) {
if (eventName.indexOf(compilers[i] + " ") >= 0) {
eventName = compilers[i];
break;
}
}
this._client.trackEvent(eventName === "" ? "bat" : eventName);
this._client.trackEvent(eventName === "" ? "bat" : eventName, properties);
}
}
}
102 changes: 59 additions & 43 deletions src/codeManager.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use strict";
import * as fs from "fs";
import * as os from "os";
import { dirname, join } from "path";
import { dirname, extname, join } from "path";
import * as vscode from "vscode";
import { AppInsightsClient } from "./appInsightsClient";

Expand All @@ -16,6 +16,8 @@ export class CodeManager implements vscode.Disposable {
private _isTmpFile: boolean;
private _languageId: string;
private _cwd: string;
private _runFromExplorer: boolean;
private _document: vscode.TextDocument;
private _workspaceFolder: string;
private _config: vscode.WorkspaceConfiguration;
private _appInsightsClient: AppInsightsClient;
Expand All @@ -30,29 +32,36 @@ export class CodeManager implements vscode.Disposable {
this._terminal = null;
}

public run(languageId: string = null): void {
public async run(languageId: string = null, fileUri: vscode.Uri = null) {
if (this._isRunning) {
vscode.window.showInformationMessage("Code is already running!");
return;
}

const editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showInformationMessage("No code found or selected.");
return;
if (fileUri) {
this._runFromExplorer = true;
this._document = await vscode.workspace.openTextDocument(fileUri);
} else {
const editor = vscode.window.activeTextEditor;
if (editor) {
this._document = editor.document;
} else {
vscode.window.showInformationMessage("No code found or selected.");
return;
}
}

this.initialize(editor);
this.initialize();

const fileExtension = this.getFileExtension(editor);
const fileExtension = extname(this._document.fileName);
const executor = this.getExecutor(languageId, fileExtension);
// undefined or null
if (executor == null) {
vscode.window.showInformationMessage("Code language not supported or defined.");
return;
}

this.getCodeFileAndExecute(editor, fileExtension, executor);
this.getCodeFileAndExecute(fileExtension, executor);
}

public runCustomCommand(): void {
Expand All @@ -62,13 +71,17 @@ export class CodeManager implements vscode.Disposable {
}

const editor = vscode.window.activeTextEditor;
this.initialize(editor);
if (editor) {
this._document = editor.document;
}

this.initialize();

const executor = this._config.get<string>("customCommand");

if (editor) {
const fileExtension = this.getFileExtension(editor);
this.getCodeFileAndExecute(editor, fileExtension, executor, false);
if (this._document) {
const fileExtension = extname(this._document.fileName);
this.getCodeFileAndExecute(fileExtension, executor, false);
} else {
this.executeCommand(executor, false);
}
Expand Down Expand Up @@ -102,16 +115,16 @@ export class CodeManager implements vscode.Disposable {
}
}

private initialize(editor: vscode.TextEditor): void {
private initialize(): void {
this._config = this.getConfiguration();
this._cwd = this._config.get<string>("cwd");
if (this._cwd) {
return;
}
this._workspaceFolder = this.getWorkspaceFolder(editor);
this._workspaceFolder = this.getWorkspaceFolder();
if ((this._config.get<boolean>("fileDirectoryAsCwd") || !this._workspaceFolder)
&& editor && !editor.document.isUntitled) {
this._cwd = dirname(editor.document.fileName);
&& this._document && !this._document.isUntitled) {
this._cwd = dirname(this._document.fileName);
} else {
this._cwd = this._workspaceFolder;
}
Expand All @@ -122,18 +135,17 @@ export class CodeManager implements vscode.Disposable {
}

private getConfiguration(): vscode.WorkspaceConfiguration {
const editor = vscode.window.activeTextEditor;
if (editor && editor.document) {
return vscode.workspace.getConfiguration("code-runner", editor.document.uri);
if (this._document) {
return vscode.workspace.getConfiguration("code-runner", this._document.uri);
} else {
return vscode.workspace.getConfiguration("code-runner");
}
}

private getWorkspaceFolder(editor: vscode.TextEditor): string {
private getWorkspaceFolder(): string {
if (vscode.workspace.workspaceFolders) {
if (editor && editor.document) {
const workspaceFolder = vscode.workspace.getWorkspaceFolder(editor.document.uri);
if (this._document) {
const workspaceFolder = vscode.workspace.getWorkspaceFolder(this._document.uri);
if (workspaceFolder) {
return workspaceFolder.uri.fsPath;
}
Expand All @@ -144,13 +156,17 @@ export class CodeManager implements vscode.Disposable {
}
}

private getCodeFileAndExecute(editor: vscode.TextEditor, fileExtension: string, executor: string, appendFile: boolean = true): any {
const selection = editor.selection;
private getCodeFileAndExecute(fileExtension: string, executor: string, appendFile: boolean = true): any {
let selection;
const activeTextEditor = vscode.window.activeTextEditor;
if (activeTextEditor) {
selection = activeTextEditor.selection;
}
const ignoreSelection = this._config.get<boolean>("ignoreSelection");

if ((selection.isEmpty || ignoreSelection) && !editor.document.isUntitled) {
if ((this._runFromExplorer || !selection || selection.isEmpty || ignoreSelection) && !this._document.isUntitled) {
this._isTmpFile = false;
this._codeFile = editor.document.fileName;
this._codeFile = this._document.fileName;

if (this._config.get<boolean>("saveAllFilesBeforeRun")) {
return vscode.workspace.saveAll().then(() => {
Expand All @@ -159,12 +175,13 @@ export class CodeManager implements vscode.Disposable {
}

if (this._config.get<boolean>("saveFileBeforeRun")) {
return editor.document.save().then(() => {
return this._document.save().then(() => {
this.executeCommand(executor, appendFile);
});
}
} else {
let text = (selection.isEmpty || ignoreSelection) ? editor.document.getText() : editor.document.getText(selection);
let text = (this._runFromExplorer || !selection || selection.isEmpty || ignoreSelection) ?
this._document.getText() : this._document.getText(selection);

if (this._languageId === "php") {
text = text.trim();
Expand All @@ -174,7 +191,7 @@ export class CodeManager implements vscode.Disposable {
}

this._isTmpFile = true;
const folder = editor.document.isUntitled ? this._cwd : dirname(editor.document.fileName);
const folder = this._document.isUntitled ? this._cwd : dirname(this._document.fileName);
this.createRandomFile(text, folder, fileExtension);
}

Expand Down Expand Up @@ -205,7 +222,7 @@ export class CodeManager implements vscode.Disposable {
}

private getExecutor(languageId: string, fileExtension: string): string {
this._languageId = languageId === null ? vscode.window.activeTextEditor.document.languageId : languageId;
this._languageId = languageId === null ? this._document.languageId : languageId;
const executorMap = this._config.get<any>("executorMap");
let executor = executorMap[this._languageId];
// executor is undefined or null
Expand All @@ -224,16 +241,6 @@ export class CodeManager implements vscode.Disposable {
return executor;
}

private getFileExtension(editor: vscode.TextEditor): string {
const fileName = editor.document.fileName;
const index = fileName.lastIndexOf(".");
if (index !== -1) {
return fileName.substr(index);
} else {
return "";
}
}

private executeCommand(executor: string, appendFile: boolean = true) {
if (this._config.get<boolean>("runInTerminal")) {
this.executeCommandInTerminal(executor, appendFile);
Expand Down Expand Up @@ -376,7 +383,7 @@ export class CodeManager implements vscode.Disposable {
}
this._terminal.show(this._config.get<boolean>("preserveFocus"));
executor = this.changeExecutorFromCmdToPs(executor);
this._appInsightsClient.sendEvent(executor);
this.sendRunEvent(executor, true);
let command = this.getFinalCommandToRunCodeFile(executor, appendFile);
command = this.changeFilePathForBashOnWindows(command);
if (this._config.get<boolean>("clearPreviousOutput") && !isNewTerminal) {
Expand All @@ -402,7 +409,7 @@ export class CodeManager implements vscode.Disposable {
if (showExecutionMessage) {
this._outputChannel.appendLine("[Running] " + command);
}
this._appInsightsClient.sendEvent(executor);
this.sendRunEvent(executor, false);
const startTime = new Date();
this._process = exec(command, { cwd: this._cwd });

Expand All @@ -428,4 +435,13 @@ export class CodeManager implements vscode.Disposable {
}
});
}

private sendRunEvent(executor: string, runFromTerminal: boolean) {
const properties = {
runFromTerminal: runFromTerminal.toString(),
runFromExplorer: this._runFromExplorer.toString(),
isTmpFile: this._isTmpFile.toString(),
};
this._appInsightsClient.sendEvent(executor, properties);
}
}
4 changes: 2 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export function activate(context: vscode.ExtensionContext) {
codeManager.onDidCloseTerminal();
});

const run = vscode.commands.registerCommand("code-runner.run", () => {
codeManager.run();
const run = vscode.commands.registerCommand("code-runner.run", (fileUri: vscode.Uri) => {
codeManager.run(null, fileUri);
});

const runCustomCommand = vscode.commands.registerCommand("code-runner.runCustomCommand", () => {
Expand Down

0 comments on commit 7b7dccb

Please sign in to comment.