VSCodeのマクロ
エディタのマクロとは、エディタの動作をスクリプトで拡張すること。EmacsだとEmacs Lispでまあなんでも書ける。というか、ほとんどの機能が、Emacs Lispで書かれている構造。VSCodeももともとJavaScriptで書かれているはずなので、同じようにできそうなものだが、デフォルトではサポートされていない(たぶん)。
キーボードマクロを可能にするExtensionはいくつかあって、それはそれで愛用しているのだけど、これだけだと基本はキーボード操作を発行できるだけなので、繰り返しや条件分岐ができない。頑張ればできるのかもしれないけど。
スクリプトマクロ
JavaScriptが書けるマクロを探してみたところこんなのを見つけた。
このExtensionは、特定の場所に置いた特定の書き方で書いたJavaScriptをキーボードショートカットやコマンドとして実行できるもの。使ってみたところ、遅延もなくかなり快適に使えた。
- Extensionをインストール
- 適当なところにディレクトリを作成して、そこにスクリプトファイルを置く。
- settings.json でこのファイルを指定。
"vscodemacros.macroFilePath": "{HOME}/Repos/vsmacro/barmacro.js",
これでコマンドパレットから VSCMacros: Run macro
で起動できるようになる。ファイル内には複数のマクロが書けるので、それを選択する形になる。
個々のマクロの呼び出し
個々のマクロに名前を与えて、キーボードショートカットを設定する事もできる。それには、settings.json に以下のように書く。
"vscodemacros.userMacroCommands": [
{
"path": "/{HOME}/Repos/vsmacro/barmacro.js",
"name": "FooMacro"
},
...
],
このようにリストを指定すると、"vscode-macros.user1","vscode-macros.user2".. のように名前が与えられる。10個しか設定できない。
マクロの書き方
マクロファイルは、コンフィギュレーション部と本体に分かれる。
コンフィグ部にはJson形式でマクロ名と関数を宣言する。このマクロ名をsettings.jsonでも用いる。
const vscode = require('vscode');
/**
* Macro configuration settings
* { [name: string]: { ... Name of the macro
* no: number, ... Order of the macro
* func: ()=> string | undefined ... Name of the body of the macro function
* }
* }
*/
module.exports.macroCommands = {
FooMacro: {
no: 1,
func: divideFunc
},
BarMacro: {
no: 2,
func: barFunc
}
};
マクロ関数本体はこのような感じ。これは、選択したテキストの前後にダブルクォート("
)を挿入するだけの
もの。
/**
* FooMacro
*/
function fooFunc() {
const editor = vscode.window.activeTextEditor;
if (!editor) {
// Return an error message if necessary.
return 'Editor is not opening.';
}
const document = editor.document;
const selection = editor.selection;
const text = document.getText(selection);
if (text.length > 0) {
editor.edit(editBuilder => {
// To surround a selected text in double quotes(Multi selection is not supported).
editBuilder.replace(selection, `"${text}"`);
});
}
}
感想
すばらしい。けどこれはデフォルトで入っているべき機能だと思う。
また、JavaScriptのファイルが別ファイルになってしまうのは、設定ファイルの管理がとても面倒くさい。settings.jsonに埋め込めれば一番いいのだけど。JSONにはraw stringがないから無理なのか。。