From ab91dde4c81790083c76bfb01b116b40daabf228 Mon Sep 17 00:00:00 2001 From: Alexander Millin Date: Wed, 18 Jan 2017 13:23:22 +0300 Subject: [PATCH] Add new feature: Run Selection in Django Shell. 1) If Django project founded in workspace, add "Run Selection in Django Shell" to selection context menu; 2) Fix issue with Run Selection, that happens if LF file selection run on Windows and CRLF run on Unix. --- package.json | 11 +++++ src/client/common/constants.ts | 1 + src/client/extension.ts | 36 ++++++++++++++- .../providers/execInTerminalProvider.ts | 45 +++++++++++++++---- 4 files changed, 84 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 45bf867d5930..a201154793f9 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "onCommand:python.selectAndDebugTestMethod", "onCommand:python.runFailedTests", "onCommand:python.execSelectionInTerminal", + "onCommand:python.execSelectionInDjangoShell", "onCommand:jupyter.runSelectionLine", "onCommand:jupyter.execCurrentCell", "onCommand:jupyter.execCurrentCellAndAdvance", @@ -174,6 +175,11 @@ "title": "Run Selection in Python Terminal", "category": "Python" }, + { + "command": "python.execSelectionInDjangoShell", + "title": "Run Selection in Django Shell", + "category": "Python" + }, { "command": "jupyter.runSelectionLine", "title": "Run Selection/Line", @@ -230,6 +236,11 @@ "group": "Python", "when": "editorHasSelection && editorLangId == python" }, + { + "command": "python.execSelectionInDjangoShell", + "group": "Python", + "when": "editorHasSelection && editorLangId == python && python.isDjangoProject" + }, { "when": "resourceLangId == python", "command": "python.execInTerminal", diff --git a/src/client/common/constants.ts b/src/client/common/constants.ts index 16bfe28e93da..6be3f5a095fd 100644 --- a/src/client/common/constants.ts +++ b/src/client/common/constants.ts @@ -5,6 +5,7 @@ export namespace Commands { export const Set_Interpreter = 'python.setInterpreter'; export const Exec_In_Terminal = 'python.execInTerminal'; export const Exec_Selection_In_Terminal = 'python.execSelectionInTerminal'; + export const Exec_Selection_In_Django_Shell = 'python.execSelectionInDjangoShell'; export const Tests_View_UI = 'python.viewTestUI'; export const Tests_Picker_UI = 'python.selectTestToRun'; export const Tests_Picker_UI_Debug = 'python.selectTestToDebug'; diff --git a/src/client/extension.ts b/src/client/extension.ts index cbf1336e59c6..a0a9d5243002 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -26,6 +26,7 @@ import { activateFormatOnSaveProvider } from './providers/formatOnSaveProvider'; import { WorkspaceSymbols } from './workspaceSymbols/main'; import { BlockFormatProviders } from './typeFormatters/blockFormatProvider'; import * as os from 'os'; +import * as fs from 'fs'; const PYTHON: vscode.DocumentFilter = { language: 'python', scheme: 'file' }; @@ -36,6 +37,7 @@ let jupMain: jup.Jupyter; export function activate(context: vscode.ExtensionContext) { let pythonSettings = settings.PythonSettings.getInstance(); + let pythonExt = new PythonExt() const hasPySparkInCompletionPath = pythonSettings.autoComplete.extraPaths.some(p => p.toLowerCase().indexOf('spark') >= 0); telemetryHelper.sendTelemetryEvent(telemetryContracts.EVENT_LOAD, { CodeComplete_Has_ExtraPaths: pythonSettings.autoComplete.extraPaths.length > 0 ? 'true' : 'false', @@ -119,4 +121,36 @@ export function activate(context: vscode.ExtensionContext) { // this method is called when your extension is deactivated export function deactivate() { -} \ No newline at end of file +} + +class PythonExt { + + private _isDjangoProject: ContextKey; + + constructor() { + this._isDjangoProject = new ContextKey('python.isDjangoProject'); + this._ensureState(); + } + + private _ensureState(): void { + // context: python.isDjangoProject + this._isDjangoProject.set(fs.existsSync(vscode.workspace.rootPath.concat("/manage.py"))); + } +} + +class ContextKey { + private _name: string; + private _lastValue: boolean; + + constructor(name:string) { + this._name = name; + } + + public set(value:boolean): void { + if (this._lastValue === value) { + return; + } + this._lastValue = value; + vscode.commands.executeCommand('setContext', this._name, this._lastValue); + } +} diff --git a/src/client/providers/execInTerminalProvider.ts b/src/client/providers/execInTerminalProvider.ts index 50c1bb49bcfe..69c15d44ee87 100644 --- a/src/client/providers/execInTerminalProvider.ts +++ b/src/client/providers/execInTerminalProvider.ts @@ -10,6 +10,7 @@ export function activateExecInTerminalProvider(): vscode.Disposable[] { const disposables: vscode.Disposable[] = []; disposables.push(vscode.commands.registerCommand(Commands.Exec_In_Terminal, execInTerminal)); disposables.push(vscode.commands.registerCommand(Commands.Exec_Selection_In_Terminal, execSelectionInTerminal)); + disposables.push(vscode.commands.registerCommand(Commands.Exec_Selection_In_Django_Shell, execSelectionInDjangoShell)); disposables.push(vscode.window.onDidCloseTerminal((closedTermina: vscode.Terminal) => { if (terminal === closedTermina) { terminal = null; @@ -79,17 +80,45 @@ function execSelectionInTerminal() { return; } const code = vscode.window.activeTextEditor.document.getText(new vscode.Range(selection.start, selection.end)); - terminal = terminal ? terminal : vscode.window.createTerminal(`Python`); const launchArgs = settings.PythonSettings.getInstance().terminal.launchArgs; - const launchArgsString = launchArgs.length > 0 ? " ".concat(launchArgs.join(" ")) : ""; + terminal = terminal ? terminal : vscode.window.createTerminal(`Python`, currentPythonPath, launchArgs); + const unix_code = code.replace(/\r\n/g, "\n") if (IS_WINDOWS) { - // Multi line commands don't work the same way on windows terminals as it does on other OS - // So just start the Python REPL, then send the commands - terminal.sendText(`"${currentPythonPath}"${launchArgsString}`); - terminal.sendText(code); + terminal.sendText(unix_code.replace(/\n/g, "\r\n")); } - else { - terminal.sendText(`${currentPythonPath}${launchArgsString} -c "${code}"`); + else + { + terminal.sendText(unix_code) + } + terminal.show(); +} + +function execSelectionInDjangoShell() { + const currentPythonPath = settings.PythonSettings.getInstance().pythonPath; + const activeEditor = vscode.window.activeTextEditor; + const workspaceRoot = vscode.workspace.rootPath; + const djangoShellCmd = [ + workspaceRoot.concat("/manage.py"), + "shell" + ] + + if (!activeEditor) { + return; + } + + const selection = vscode.window.activeTextEditor.selection; + if (selection.isEmpty) { + return; + } + const code = vscode.window.activeTextEditor.document.getText(new vscode.Range(selection.start, selection.end)); + terminal = terminal ? terminal : vscode.window.createTerminal(`Django Shell`, currentPythonPath, djangoShellCmd); + const unix_code = code.replace(/\r\n/g, "\n") + if (IS_WINDOWS) { + terminal.sendText(unix_code.replace(/\n/g, "\r\n")); + } + else + { + terminal.sendText(unix_code) } terminal.show(); } \ No newline at end of file