Help us understand the problem. What is going on with this article?

VSCodeのPluginをつくる。

More than 1 year has passed since last update.

初めに

Java9以前のアプリケーションの設定ファイル(Propertiesファイル)は、日本語(2バイトコード)をそのまま利用することができず、'¥u'から始まるコードに置き換える必要がありました。
Java9以前のアプリケーションをメンテナンスする立場になり、VSCodeを利用する上で、毎度、native2asciiするのが億劫で退屈な作業でした。

そこで、VScodeのプラグインでnative2asciiと同等の機能を作ることにしました。

まず、VSCodeのpluginを開発する環境を作ります。環境の作成方法は、@rmaさんの「Visual Studio Code はじめての拡張機能開発」をご覧ください。

方針

自分が調べた範囲では、VSCode上でコマンドをキックすることも、「Propertiesファイルを読んだ」イベントを拾うこともできそうになかったので(誰か情報ください。)、VSCodeのコマンドを利用して手動で変換(文字→コード化)リバース(コード→文字)をする方針で進めました。

コード化

以下のような感じで、文字→コード化を実現しました。

  1. ドキュメントからファイルの文字列を取得。
  2. 1行ごとに繰り返し、日本語を正規表現現で取得し配列を作成。
  3. 2.で作成した配列からコードを作りだし、日本語と、コードの連想配列を作成。
  4. 元の1行にreplaceメソッドで置き換える。
  5. 置き換えた文字列をまとめて新しいドキュメントを作成。
  6. エディタ内のドキュメントを5.で作成したドキュメントで置き換える。

なお、サロゲート文字には対応してません。

function ascii(e: vscode.TextEditor, d: vscode.TextDocument, sel: vscode.Selection[]) {
    console.log(d.getText());
    let text = d.getText();
    let newTest = text.split("\n");
    let replaced = "";
    newTest.forEach(val => {
        let reg = val.match(/([^\x01-\x7E])/g);
        if (reg) {
            let t = reg.map(code => {
                let unicode = code.charCodeAt(0).toString(16);
                return {code, value:`\\u${unicode}`};
            }).reduce( (v,obj) => {
                let {code, value} = obj;
                let reg = new RegExp(code);
                return v.replace(reg, value);
            }, val);
            replaced = `${replaced}${t}\n`; 
        } else {
            replaced = `${replaced}${val}\n`; 
        }
    });
    e.edit((builder)=>{
        if (e) {
            let startPos = e.document.positionAt(0);
            let endPos = e.document.positionAt(text.length);
            let allRange = new vscode.Range(startPos,endPos);
            builder.replace(allRange,replaced);
        }
    });
}

リバース

コード化したものと大差ありません。ユニコードから文字を作成しています。

function reverse(e: vscode.TextEditor, d: vscode.TextDocument, sel: vscode.Selection[]) {
        console.log(d.getText());
        let text = d.getText();
        let newTest = text.split("\n");
        let replaced = "";
        newTest.forEach(val => {
            let reg = val.match(/(\\u[0-9|a-f]{4})/g);
            if (reg) {
                let t = reg.map(unicode => {
                    let codeStrs = unicode.split("\\u");
                    let codePoints = parseInt(codeStrs[1], 16);
                    return {code:`\\${unicode}`, value:String.fromCharCode(codePoints)};
                }).reduce( (v,obj) => {
                    let {code, value} = obj;
                    let reg = new RegExp(code);
                    return v.replace(reg, value);
                }, val);
                replaced = `${replaced}${t}\n`; 
            } else {
                replaced = `${replaced}${val}\n`; 
            }
        });
        e.edit((builder)=>{
            if (e) {
                let startPos = e.document.positionAt(0);
                let endPos = e.document.positionAt(text.length);
                let allRange = new vscode.Range(startPos,endPos);
                builder.replace(allRange,replaced);
            }
        });
}

native2ascii

以下の関数を作成して、上記で作成した関数をコマンドで呼べるようにまとめました。
この関数を、registerCommandで呼び出せば完成です。

function native2ascii() {
    if (!vscode.window.activeTextEditor) {
        vscode.window.showInformationMessage('Open a file first to manipulate text selections');
        return;
    }   
    var items: vscode.QuickPickItem[] = [];

    items.push({ label: "ascii", description: "文字からUnicodeに変換" });
    items.push({ label: "reverse", description: "Unicodeから文字に変換" });

    Window.showQuickPick(items).then((selection) => {
        if (!selection) {
            return;
        }
        let e = Window.activeTextEditor;
        if (e) {
            let d = e.document;
            let sel = e.selections;
            switch (selection.label) {
                case "ascii":
                    ascii(e, d, sel);
                    break;
                case "reverse":
                    reverse(e, d, sel);
                    break;
                default:
           console.log("hum this should not have happend - no selection")
           break;
            }
        }
    });
}

VSCEでVSIXファイルを作る。

作成したpluginをパッケージングをします。
VSCEを利用しました。
以下のコマンドでインストールしました。

npm install -g vsce

インストールできたら、以下のコマンドでパッケージングします。
README.mdを書き換えないとパッケージングに失敗します。

vsce package

ソースコードはGitHubに保存しています。

まとめ

プラグインを作るための環境が充実しており、引っかかるところはなかった(@rmaさんに感謝)
typescriptは初めてだったのですが、ES2015を触っていたので違和感はありませんでした。
むしろ、VScodeの言語サポートがよくできていて、typescriptを本格的に使いたいと思いました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした