作ったもの
Markdown ファイルのコードブロック部分を選択してコマンドを入力すれば勝手に実行してくれる拡張機能を作りました。
Run Snippets in Markdown (GitHub)
作りました、と言っても、私がやったのはただ言語名部分を取り出して中身を新しい画面に貼り付けるだけで、実際のコード実行は別の拡張機能 Code Runner におまかせしています。これは開いているファイルをコンパイル & 実行してくれる拡張機能で、これも個人的にすごく便利に使わせてもらっています。
Markdown のコードブロックの中身をサクっと実行してみて確認したいと思うことはありませんか?
こういった需要はありそうなのになぜかそういう拡張を見つけられず、勉強を兼ねて自作してみることにしました。もし便利な拡張機能が既にあるようでしたら、教えてくださると嬉しいです。
モチベーション
個人的には実験用コードや例示用コードの確認に使っています。
プログラミング学習中の身なので、何か分からなかったことがあると Markdown ファイルに自分なりの理解をまとめて整理することがあります。こういうとき、ファイル内に書いた実験用のコードが (エラーなく) 正しく動くことを確認したくなります。しかしそれぞれのコードについて一々別ファイルを作って保存してコンパイルして実行して、というのは面倒ですし間違いの元になります。
機能
機能はほとんどないのですが、唯一テンプレート機能があります。
C/C++ のように main() 関数が必要となる言語では、実行する前に勝手に囲ってくれたほうが嬉しいことも多いと思い、実装してみました。
"markdown-run-snippet.mdTypeToTemplateMap": {
"rust": "fn main() {\n $snippet\n}",
"c++": "#include <iostream>\n#include <string>\nint main(void) {\n $snippet\n return 0;\n}"
}
テンプレート機能を使うと、選択したコードブロックの中身をテンプレートのプレースホルダ $snippet
に流し込むことができます。上の例のように main() 関数の中に設置しておけばいい感じに展開されるという寸法です。テンプレートに #include, import, use など盛り込んでおくという手もあります。
そして、この $snippet
は単純に置換するのではなく、この $snippet
の前にある空白の数をインデントとして、選択部分のコード全ての行の頭に追加します。これで例えば Python のようなインデントベースの言語に対するテンプレートも安心です。
例えば、 Python 用のテンプレートを次のように設定するとします。
"markdown-run-snippet.mdTypeToTemplateMap": {
"python": "if True:\n $snippet"
},
そして、ある Markdown ファイルに次のようなコードブロックが含まれているとします。このとき、コードブロック部分の全体を (マーカー ``` を含めて) 選択して Run Snippet in Markdown
を実行すると...
(何らかの Markdown ファイルの途中)
```python
print("hello");
print("world");
```
コードブロックの言語指定 python を検出し、マーカー ``` を取り払ったコード本体を python に対応するテンプレートに流し込みます。そのテンプレートでは $snippet
の頭に空白 4 つがあるため、これをインデントとしてコード本体の各行に追加します。結果として次のように展開されます。
if True:
print("hello");
print("world");
$snippet
をコード本体に単純に置換すると次のようになってしまいますが、このようにはなりません。
if True:
print("hello");
print("world");
おわりに
今回は VSCode を使ってみるということ、拡張機能を作ってみること、 github で何か公開してみることなどを目的にしてやってみました。
実は Vim を使っていたとき、 QuickRun という拡張機能を使って自分用に同様の機能を実装したことがありました。そのときは VimScript を使っていろいろしたわけですが、選択範囲を受けとる方法に苦労したり、関数が選択行数分繰り返し呼ばれたりと嵌り続けました。もともとテンプレート機能が QuickRun に備わっていたので言語判別だけだったのに、それですら大分苦労しました。
VSCode で使われる TypeScript は普通の言語で使いやすかったです。選択範囲を文字列として取得する API があることや、文字列を行ごとに split したり配列にしたりと好きなように扱えるということが本当に便利でした。 intellisense も強力で、よく知らない機能でもなんとなく使えるということは面白かったです。
拡張機能のプログラミング以前に、 yo code
したら拡張機能の雛形ができたり、vsce
でパッケージングも公開も簡単にできるというのもとても大きいです。便利でした。
とりあえず VSCode 、使ってみようと思います。