vscodeの拡張機能で右クリックメニューを増やして見る
これは CureApp Advent Calendar 2023 19日目の記事です。
はじめに
弊社kexiさんがvscodeの拡張機能の作り方を紹介してくれたので、せっかくなら実際の作成例を作れたらと思い記事にしました。
環境構築
kexiさんの記事を参考に開発環境を作ります
仕様
- vscodeから自分のslackチャンネルへ通知を出したい
- slackへの通知は右クリックメニューから行いたい
- 選択した文のみ送信したい
- slack URLは設定から変更したい
実際できたコード
以下2ファイルのみの変更で出来る
ソースコード
import vscode from "vscode";
import axios from "axios";
export function activate(context: vscode.ExtensionContext) {
const cmd = vscode.commands.registerCommand(
"vscode.contextmenu.sendslack",
() => {
//アクティブなエディタのドキュメントを取得
const activeEditor = vscode.window.activeTextEditor;
const doc = activeEditor && activeEditor.document;
//選択範囲を取得
const ref = activeEditor?.selection;
sendSlack(doc?.getText(ref));
}
);
context.subscriptions.push(cmd);
}
function sendSlack(message?: string) {
const slackWebhookUrl = vscode.workspace
.getConfiguration("sendslack")
.get("sendSlackURL", "");
axios.post(
slackWebhookUrl,
{
username: "VSCode",
icon_emoji: ":ghost:",
text: message,
},
{
headers: {
"Content-Type": "application/json",
},
}
);
}
export function deactivate() {}
{
"name": "sendslack",
"displayName": "sendslack",
"description": "検索窓を増やします。ただそれだけ",
"version": "0.0.1",
"engines": {
"vscode": "^1.84.0"
},
"categories": [
"Other"
],
"main": "./dist/extension.js",
"activationEvents": [
"onStartupFinished"
],
"contributes": {
"configuration": {
"title": "sendslack",
"properties": {
"sendslack.sendSlackURL": {
"type": "string",
"default": "https://hooks.slack.com/services/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"description": "%configuration.sendSlackURL.description%"
}
}
},
"commands": [
{
"command": "vscode.contextmenu.sendslack",
"title": "選択した文字をslackに送信します"
}
],
"menus": {
"editor/context": [
{
"when": "editorFocus",
"command": "vscode.contextmenu.sendslack",
"group": "myGroup@1"
}
]
}
},
"scripts": {
"vscode:prepublish": "npm run package",
"compile": "webpack",
"watch": "webpack --watch",
"package": "webpack --mode production --devtool hidden-source-map",
"compile-tests": "tsc -p . --outDir out",
"watch-tests": "tsc -p . -w --outDir out",
"pretest": "npm run compile-tests && npm run compile && npm run lint",
"lint": "eslint src --ext ts",
"test": "vscode-test"
},
"devDependencies": {
"@types/mocha": "^10.0.6",
"@types/node": "18.x",
"@types/vscode": "^1.84.0",
"@typescript-eslint/eslint-plugin": "^6.13.1",
"@typescript-eslint/parser": "^6.13.1",
"@vscode/test-cli": "^0.0.4",
"@vscode/test-electron": "^2.3.8",
"eslint": "^8.54.0",
"ts-loader": "^9.5.1",
"typescript": "^5.3.2",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4"
},
"dependencies": {
"axios": "^1.6.2"
}
}
使い方
-
vscodeの設定に通知を出したいslackのhooks URLを登録する
(hooks URLの取得方法はこちらを参考に取得)
-
vscodeのエディター上で送信したい文を選択し右クリック
-
slackに無事通知成功
解説
package.json
作った拡張機能を有効にするトリガー設定
"activationEvents": [
"onStartupFinished"
],
設定からhooks URLを読み込ませたいので設定項目を追加
"contributes": {
"configuration": {
"title": "sendslack",
"properties": {
"sendslack.sendSlackURL": {
"type": "string",
"default": "https://hooks.slack.com/services/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"description": "%configuration.sendSlackURL.description%"
}
}
},
説明を追加したい場合はdescriptionの項目に%configuration.sendSlackURL.description%
と入力する。
package.nls.jsonというファイルに以下のように設定できる。
要らなければdescriptionに直接書くでもいいらしい(多言語対応する時に必要っぽい)
{
"configuration.sendSlackURL.description": "slack send hooks URL."
}
右クリックメニューに追加する設定を書く
"contributes": {
---略ーー
"commands": [
{
"command": "vscode.contextmenu.sendslack",
"title": "選択した文字をslackに送信します"
}
],
"menus": {
"editor/context": [
{
"when": "editorFocus",
"command": "vscode.contextmenu.sendslack",
"group": "myGroup@1"
}
]
}
"command"
は同じ文字列vscode.contextmenu
から始まる拡張機能名を入れる(これはあとでextension.tsでも記述する箇所がある)
"group":"myGroup@1"
はメニューのどこに表示するかの記述
extension.ts
slackに通知させる処理
今回はaxios
を使う。
コマンドの登録と中身
const cmd = vscode.commands.registerCommand(
"vscode.contextmenu.sendslack",
() => {
//アクティブなエディタのドキュメントを取得
const activeEditor = vscode.window.activeTextEditor;
const doc = activeEditor && activeEditor.document;
//選択範囲を取得
const ref = activeEditor?.selection;
sendSlack(doc?.getText(ref));
}
);
vscode.commands.registerCommand()
の第一引数にpackage.jsonでも記述したcommand
名を入れる。第二引数が発火した時に実行される処理
activeEditor?.selection
+getText()
で選択した文字列のみ取得できる
終わりに
ハマりどころはpackage.json
の記述方法だと思いました
親子の設定を間違えないこと、"command"は各プロパティで共通のものを設定すること
この辺注意が必要だと思います
ちなみに他の方の記事でも見かけたのですが、youtubeを埋め込むとかgoogleカレンダーを表示するとかいった類はできないようでした。(要webviewにiframe読み込みさせるような構成)
残念!!
Discussion