Blog,
VS Code mit IPython Konsole
Ich benutze gerne VS Code für die Software Entwicklung. Ich schätze an VS Code besonders:
- die scheinbar unendlichen Erweiterungsmöglichkeiten
- sehr gute Individualisierungsmöglichkeiten
- schnelles Starten
- sehr gute Python Extensions
Zuvor habe ich für die Python Entwicklung die IDE Spyder verwendet. Diese war in der Winpython Distribution enthalten. Spyder wiederum benutzt als interaktive Konsole IPython. In der Spyder IDE kann man ein Skript, das man im Editor geöffnet hat mit einem Tastendruck (F5) in der IPython Konsole starten. Wenn noch keine Konsole existiert, wird eine automatisch erstellt. Daran hatte ich mich gewöhnt.
Der Umstieg auf VS Code war daher etwas holprig. Ich wollte Winpython weiter nutzen, da es ohne Installation auskommt und eine grosse Anzahl nützlicher Pakete mitbringt. Um Winpython nutzen zu können, war in der VS Code Settings Datei der Eintrag
"python.defaultInterpreterPath":
"C:\\portable\\WPy64-3720\\python-3.7.2.amd64",
notwendig. Damit wird die Winpython-Distribution der VS Code Python-Extensions bekannt gemacht. Nun war es möglich Python Skripte auszuführen und zu debuggen. Es fehlte aber die interaktive Konsole, mit der man auch nach Programmende oder bei einem Fehler komfortabel weiter arbeiten konnte.
Nach kurzer Suche habe ich die Erweiterung IPython for VS Code gefunden. Damit ist es möglich über einen Befehl direkt eine IPython-Konsole zu starten und das Skript darin auszuführen. Die Erweiterung musste ich allerdings im Source Code anpassen, um die Winpython Distribution nutzen zu können.
Da ich keine vollständige Erweiterung schreiben wollte suchte ich nach einer alternativen Möglichkeit die VS Code Umgebung mit wenig Aufwand anpassen zu können. Die Erweiterung Power Tools ermöglicht genau dies, die Ergänzung von VS Code ohne eine komplette Erweiterung schreiben zu müssen.
So können einfach Schaltflächen hinzugefügt werden:
Ich habe mir also die zwei Schaltflächen, Send To IPython und IPython zu VS Code hinzugefügt. Dafür sind folgende Einträge in den VS Code User Settings notwendig:
"ego.power-tools": {
"buttons": [
{
"text": "IPython",
"tooltip": "Create shell and start IPython",
"action": {
"type": "script",
"script": "ipython.js"
}
}
],
"commands": {
"sendToIPython": {
"script": "sendToIPython.js",
"button": {
"text": "Send To IPython"
}
}
},
"user": {
}
},
Die beiden Skriptdateien befinden sich in meinem Benutzerverzeichnis im Unterverzeichnis .vscode-powertools
und sehen wie folgt aus. Den Pfad zur Kommandozeile der Distribution muss man natürlich anpassen:
ipython.js
exports.execute = async (args) => {
const vscode = args.require('vscode');
var ipython_shell = get_ipython_shell(vscode);
if (ipython_shell==null)
{
ipython_shell = vscode.window.createTerminal("IPython")
setTimeout(() => {
get_ipython_shell(vscode).sendText("C:\\portable\\WPy64-3720\\scripts\\cmd.bat")
setTimeout(() => {
get_ipython_shell(vscode).sendText("ipython")
}, 100);
}, 1000);
}
ipython_shell.show(false)
};
function get_ipython_shell(vscode)
{
var ipython_shell = null;
vscode.window.terminals.forEach(element => {
if (element.name=="IPython")
{
ipython_shell = element
}
});
return ipython_shell
}
sendToIPython.js:
exports.execute = async (args) => {
const vscode = args.require('vscode');
var ipython_shell = get_ipython_shell(vscode);
const editor = vscode.window.activeTextEditor;
if (editor == undefined)
{
vscode.window.showInformationMessage(
"No active Editor"
);
return
}
// save current file
let success = await vscode.commands.executeCommand('workbench.action.files.save');
const filename = editor.document.fileName;
var command_zw = null
var shebang = false
if (editor.document.lineAt(0).text[0]=="#")
{
shebang = 1
}
let startLine, endLine;
if (editor.selection.isEmpty) {
command_zw = `%run ${filename}`;
} else {
if (shebang==1)
{
startLine = editor.selection.start.line;
endLine = editor.selection.end.line;
}
else
{
startLine = editor.selection.start.line + 1;
endLine = editor.selection.end.line + 1;
}
command_zw = `%load -r ${startLine}-${endLine} ${filename}`;
}
var delay = 0;
const command = command_zw
if (ipython_shell == null)
{
delay = 1300
ipython_shell = vscode.window.createTerminal("IPython")
setTimeout(() => {
get_ipython_shell(vscode).sendText("C:\\portable\\WPy64-3720\\scripts\\cmd.bat")
setTimeout(() => {
get_ipython_shell(vscode).sendText("ipython")
}, 100);
}, 1000);
}
setTimeout(() => {
ipython_shell.show();
get_ipython_shell(vscode).sendText(command)
setTimeout(() => {
get_ipython_shell(vscode).sendText("")
}, 100);
}, delay);
};
function get_ipython_shell(vscode)
{
var ipython_shell = null;
vscode.window.terminals.forEach(element => {
if (element.name=="IPython")
{
ipython_shell = element
}
});
return ipython_shell
}
Nun kann ich über den einen Button einfach eine IPython Konsole starten. Der Button Send To IPython erzeugt wenn nicht schon vorhanden ein IPython Konsole und startet Skript aus dem aktuellen Editor Fenster. Genauso wie ich es von Spyder gewohnt war.