のらてつの雑記帳 検索除外

VSCode拡張機能開発ノート

9 コメント
views
0 フォロー

あくまで自分用のメモです。自分なりの工夫を色々書くと思いますが一般的な書き方ではない可能性があります(その可能性がとても高いです)。

参照

INDEX

>> 2コマンド(Commands)

>> 4メッセージ(Notifications)

noratetsu
作成: 2023/04/17 (月) 08:39:33
最終更新: 2023/04/18 (火) 16:40:14
通報 ...
1
noratetsu 2023/04/17 (月) 08:46:11

extension.tsの最も基本的な構造

import * as vscode from 'vscode';

// アクティブ化時に実行(実行するものは全てこの中に書く)
export function activate(context: vscode.ExtensionContext) { }

// 無効化時に実行
export function deactivate() { }
2
noratetsu 2023/04/17 (月) 08:59:08 修正

コマンド登録

(activate関数の中で実行する)
詳細→Commands | Visual Studio Code Extension API

基本形

// コマンド登録の基本形はこの形
vscode.commands.registerCommand('hoge.foo', () => { console.log('コマンド実行'); });

オブジェクトにまとめてみる

コマンドを沢山作るとなると一箇所で管理できたほうがいい気がする。
Tree Viewでコマンド登録することがあるので、コマンド名を直に打たないで変数にしておいたほうが把握しやすい。

const command = {
  foo: {
    name: 'hoge.foo',
    func() {
      console.log('コマンド実行');
    }
  },
}

vscode.commands.registerCommand(command.foo.name, command.foo.func);

ラッパーを作ってみる

処理を簡単にする関数を作る。

const registerCommand = (data: { name: string, func: () => void }) => vscode.commands.registerCommand(data.name, data.func);

registerCommand(command.foo);
3
noratetsu 2023/04/17 (月) 09:07:08 修正 >> 2

コマンドをコマンドパレットから呼び出せるようにする

package.jsonの編集

予めpackage.jsonにコマンドを書いておく必要がある。

{
  // 前後に色々ある

  "contributes": {
    "commands": [
      {
        "command": "hoge.foo",
        "title": "コマンド実行テスト"
      }
    ],

  // 前後に色々ある
}

extension.tsの記述

その上で、extension.tsのactivate関数の中に以下の形で記述。
なおregisterCommand関数とcommandオブジェクトは>> 2で作ったもの。こうするのが一般的というのではない。

export function activate(context: vscode.ExtensionContext) {
  context.subscriptions.push(registerCommand(command.foo));
}

例に普通書かれているのはこうとか↓

context.subscriptions.push(vscode.commands.registerCommand('hoge.foo', () => { console.log('コマンド実行'); }));

こう↓

const command = 'hoge.foo';
const commandHandler = () => { console.log('コマンド実行'); };
context.subscriptions.push(vscode.commands.registerCommand(command, commandHandler));
4
noratetsu 2023/04/17 (月) 21:40:03 修正

メッセージの表示

右下にぴょこんと出るやつ。その際に選択を求めることも可能。
Notifications | Visual Studio Code Extension API
vscode-extension-samples/extension.ts at main · microsoft/vscode-extension-samples

Information

vscode.window.showInformationMessage('Hello World!');

Warning

vscode.window.showWarningMessage('Warning');

Error

vscode.window.showErrorMessage('Error');
5
noratetsu 2023/04/18 (火) 19:29:30 >> 4

選択肢を出すには

普通のInformationメッセージにa,b,cの三択をくっつける

vscode.window.showInformationMessage('Hello World!', 'a', 'b', 'c')
  .then((select) => { if(select) vscode.window.showInformationMessage(select); });
7
noratetsu 2023/04/18 (火) 22:03:03 >> 6

簡単なラッパーを作ってみる

function createQuickPick(items: vscode.QuickPickItem[], selectHandler: (quickPick: vscode.QuickPick<vscode.QuickPickItem>) => void, defaultValue: string) {
    const quickPick = vscode.window.createQuickPick();
    quickPick.items = items;
    quickPick.value = defaultValue;
    quickPick.onDidAccept(() => selectHandler(quickPick));
    return quickPick;
}

QuickPickには色々メソッドやプロパティがあるのでこれでは不十分だが、とりあえず練習として。

8
noratetsu 2023/04/18 (火) 22:05:50 >> 7

このラッパーを使ってファイルピッカー?を作る

function showFilePicker(root: string, defaultValue: string, query: string) {
    const selectHandler = (quickPick: vscode.QuickPick<vscode.QuickPickItem>) => {
        const selected = quickPick.selectedItems[0].label;
        const path = vscode.Uri.parse(root + encodeURI(selected));
        vscode.workspace.openTextDocument(path)
            .then(doc => vscode.window.showTextDocument(doc));
        quickPick.hide();
    };
    vscode.workspace.findFiles(query)
        .then(urls => { return urls.map(url => decodeURI(url.toString().replace(root, ''))); })
        .then(map => {
            const items = map.map(url => { return { label: url }; });
            const quickPick = createQuickPick(items, selectHandler, defaultValue);
            quickPick.show();
        });
}
9
noratetsu 2023/04/18 (火) 22:32:31

アクティブファイルの変更時に実行

アクティブなファイルが変わった時
vscode.window.onDidChangeActiveTextEditor(handler)

アクティブなファイルの内容が変わった時(でいいのか?)
vscode.window.onDidChangeTextEditorVisibleRanges(handler)