![logo](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F223255%2Ff091ce3d-9e1a-a12b-78e7-19521f2700d3.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=574511803d595248f180bd38e62a230a)
TL;DR
vscodeでライブラリを簡単にコピペするための拡張機能を作りました。
Demo
Command Palette (Cmd + Shift + P
)でInsert Template
を選択(または、ショートカットCtrl + Shift + I
)で特定のディレクトリ以下のファイルを選択できます。選択されたファイルがアクティブなファイルに挿入されます。
設定
テンプレートファイルを検索するディレクトリはデフォルトで~/.vscode-templates
になっていますが、settings.json
にinsertTemplate.directory
を設定することで変更できます。挿入するファイルの候補としたくないファイルはinsertTemplate.ignore
にglobパターンの配列を指定できます。
"insertTemplate.directory": "~/prg/competitive-programming",
"insertTemplate.ignore": ["**/*.md", "**/tmp/**"],
背景
最近またatcoderをやっています。vscode 競技プログラミング
等で調べるとライブラリのコピペはスニペットを使う方法が紹介されていますが、JSONはメンテナンスが難しいなと思っていました。
やりたいことは、特定のディレクトリにライブラリを記述したファイルを配置しておいて、ファイル単位でそのままアクティブなファイルに貼り付けるということです。ライブラリはそのままgitで管理できる形が良いなと思いました。
vimキーバインドであれば:r path/to/file
で達成できますが、できるだけ簡単に、インクリメンタルサーチとか使える感じで解決したかったので、車輪の再発明っぽいですが、拡張機能を作ることにしました。
vscode拡張機能の作り方
環境
- macOS 10.14.6
- Visual Studio Code 1.43.2
ソースコードは以下です。
helloworldする
メニューバーから[Run]->[Start Debugging]
でデバッグ実行ができ、DEBUG CONSOLEにconsole.log
が出力されることが重要。
APIをさがす
今回は、以下のAPIを使いました。
-
vscode.workspace.getConfiguration
:settings.json
から設定を取得 -
vscode.window.showQuickPick
: ユーザーが選択候補の中から1つの候補を選択(テンプレートファイルを選択する際に使用) -
vscode.workspace.openTextDocument
: 新しいファイルを作成、既存ファイルを開く(アクティブなファイルがない場合は新しいファイルを作成する、またテンプレートファイルを開く際に使用) -
vscode.window.showTextDocument
: ドキュメントを表示(新しく作ったファイルを表示する際に使用) -
vscode.window.activeTextEditor
: アクティブなテキストエディタを取得 -
vscode.window.showInformationMessage
: 警告メッセージを表示 -
vscode.window.showErrorMessage
: エラーメッセージを表示
package.jsonを整理する
- Extension Manifest | Visual Studio Code Extension API
- Contribution Points | Visual Studio Code Extension API
必須ではないですが見栄えが良くなるので、以下のプロパティを追加、修正。
-
author.name
: 追加 -
icon
: 追加。最低128x128 -
galleryBanner
-
color
: マーケットプレイスのヘッダーの背景色 -
theme
: ヘッダーの文字色。light
だと黒。dark
だと白
-
-
contributes
: 書いておくと拡張機能のFeature Contributions
に表示される-
commands.title
: 拡張機能のコマンド名 -
keybindings
: 拡張機能のコマンドをキーバインドにアサイン -
menus.editor/context
: エディターの右クリックメニューにコマンドを追加 -
configuration
:settings.json
で設定できるプロパティ
-
-
license
: 追加 -
bugs
: 追加 -
repository
: 追加 -
homepage
: 追加
README.mdにバッジをつける
-
VSMarketplaceBadge
- バッジはかっこいいのでつけます。マーケットプレイスに登録してからのほうがわかりやすいかもしれません
CHANGELOG.mdを整理する
-
Keep a Changelog
- ベストエフォートで書きます
マーケットプレイスに登録する
-
Publishing Extensions | Visual Studio Code Extension API
-
vsce create-publisher
するとPersonal Access Token (PAT)
を入力を求められます
-
ハマった点
デバッグ実行では問題ないのに、マーケットからインストールするとcommand 'extension.insertTemplate' not found
で動かない。
ローカルでパッケージからインストール
いちいちマーケットにアップロードしてデバッグするのは辛いので、ローカルでプロダクションバージョンをインストールする。
vsce package # vscode-insert-template-x.x.x.vsixが生成される
code --install-extension vscode-insert-template-x.x.x.vsix
vscodeは拡張機能を自動でアップデートしてしまうので、デバッグ中は無効にしておくと良いです。
"extensions.autoUpdate": false,
Toggle Developer Tools
メニューバーから[Help]->[Toggle Developer Tools]
を選択するとChromeのデベロッパーツールが表示されるのでConsole
でログを確認する。
abstractExtensionService.ts:396 Activating extension 'yskoht.vscode-insert-template' failed: Cannot find module 'glob'
Require stack:
- /Users/yskoht/.vscode/extensions/yskoht.vscode-insert-template-0.0.6/out/extension.js
- /Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/loader.js
- /Applications/Visual Studio Code.app/Contents/Resources/app/out/bootstrap-amd.js
- /Applications/Visual Studio Code.app/Contents/Resources/app/out/bootstrap-fork.js.
glob
が見つかってない🤮
devDependencies
-> dependencies
glob
のインストール先がdevDependencies
になっていたのでdependencies
に変更。無事に動作するようになりました。
diff --git a/package.json b/package.json
index b2b480e..d229d9a 100644
--- a/package.json
+++ b/package.json
@@ -70,6 +70,9 @@
"pretest": "npm run compile && npm run lint",
"test": "node ./out/test/runTest.js"
},
+ "dependencies": {
+ "glob": "^7.1.6"
+ },
"devDependencies": {
"@types/glob": "^7.1.1",
"@types/mocha": "^7.0.1",
@@ -78,7 +81,6 @@
"@typescript-eslint/eslint-plugin": "^2.18.0",
"@typescript-eslint/parser": "^2.18.0",
"eslint": "^6.8.0",
- "glob": "^7.1.6",
"mocha": "^7.0.1",
"typescript": "^3.7.5",
"vscode-test": "^1.3.0"
Your extension folder
macOSだと~/.vscode/extensions
に拡張機能が保存される。古いバージョンが溜まっていくことがあるので手動で消してもよいかもしれない。
まとめ
- タイトルに競技プログラミングと付けたけど、あまり関係なかったかもしれない。でも他のファイルをコピペしたいというユースケースは競プロぐらいしかないような気もする
- もっとスマートな解決方法があれば教えて下さい。とても車輪の再発明感を感じます
- vscodeの拡張機能は簡単に作れてとてもよいです。ロゴ作ったり、README書いたり、CHANGELOG書いたりするのが一番たいへん