VSCode + Python で複数行の Run Selection がしたい
概要
macOS (10.15.4) + VSCode (1.44.2) + Python extension (2020.4.76186) という環境下で以下のコードを実行することを考える。
for i in range(2): print('hoge') print('fuga')
アクティブなターミナルで iPython を起動&エディタで上記のコードを選択した状態で、上記を python.execSelectionInTerminal
を用いて実行すると
In [1]: for i in range(2): ...: print('hoge') ...: print('fuga') File "<ipython-input-2-fea876064538>", line 3 print('fuga') ^ IndentationError: unexpected indent
と、3 行目に謎のインデントが挿入され IndentationError が発生してしまう。アクティブなターミナルで (iPython ではなく) Python を起動している場合、あるいは同様の作業を Windows で行っている場合だと生じない不具合ということもあり、どうしてこんな挙動になるのかさっぱりわからない。
これは以前から指摘されていた問題らしく こちら などで熱い議論が交わされている。当該 issue は最終的に何らかが merge されて close されているものの、少なくとも手元の環境では直っていないので方法を考えることにした。
解決策
上記のように python.execSelectionInTerminal
で実行するのではなく、コードをエディタからコピー → ターミナルにフォーカス → ターミナルにペースト という手順を踏めばどうやらインデントの問題は発生しないようである。いちいちこれを実行するのはあまりにも面倒なので、これを Shift
+ Return
で一発でできるようにしたい。
今回は拡張機能 geddski.macros
をインストールすることによりこの動作を実現する。これは複数の Command をまとめて一つの Command を定義できるようにするものであり、今回の場合は settings.json
に以下を追記すれば上記の動作を copySelectionAndPasteToActiveTerminal
という Command にまとめることができる。
[ "macros": { "copySelectionAndPasteToActiveTerminal": [ "editor.action.clipboardCopyAction", "workbench.action.terminal.focus", "workbench.action.terminal.paste", ] } ]
あとは Keyboard Shortcuts の設定で copySelectionAndPasteToActiveTerminal
に Shift
+ Return
を割り振ればいいだけである。クリップボードが汚れてしまう形になるので微妙だが、とりあえずこれでちゃんと動作するようにはなる。
In [3]: for i in range(2): ...: print('hoge') ...: print('fuga') ...: hoge fuga hoge fuga
やったね!