Posted at

VS Code 拡張機能のコマンドタイトル名をローカライズしてみる

More than 1 year has passed since last update.

VS Code 拡張機能で提供するコマンド・タイトルに英語表記以外の各言語を割り当ててローカライズしてみる。

提供するコマンドのタイトル名は、package.json の contributes ポイントにある commands セクションに定義され、Yeoman の generator-code (yo code) で作成される Hello World サンプルを見てみると下記のようになっています。

package.json:

    "contributes": {

"commands": [{
"command": "extension.sayHello",
"title": "Hello World"
}]
},

コマンドパレットから extension.sayHello を実行するには、Hello World を見つけて選択すれば実行されることがわかりますね。

この Hello World がコマンドのタイトル名になります。


package.nls.json と package.nls.ja.json

Hello World のままでも良いのですが、このタイトルを日本語にローカライズしてみるのが目的となります。

拡張機能の package.json に定義される "title" は、全ての言語で共通に利用されますが、package.json と同一のディレクトリに下記のファイルを配置することで言語毎にローカライズされたタイトルなどを追加することが可能になります。


  • package.nls.json


  • package.nls.ja.json: (本記事では日本語をターゲットにしているため、ja のみ絞ります)


まず、package.json の変更:


  • ローカライズしたい文字列を %extension.sayHello.title% のように % で囲まれた文字列に置き換えます。これがキーになります

  • 本記事では "category": を追加し、コマンドパレット上では category: title のように表示するようにします。ここでは、"Hello World sample" というカテゴリ名を設定しておきます。


修正後の package.json:


    "contributes": {

"commands": [{
"command": "extension.sayHello",
"title": "%extension.sayHello.title%",
"category": "Hello World sample"
}]
},


続いて、package.nls.json を作成:

package.json で設定したローカライズ用のキーにマッピングするための値を、下記のように追加します。

このファイルを用意することで、VS Code の言語が英語(en)に設定されているか、英語以外のローカライズ情報が用意されていない場合にこのファイルに記載されている情報が利用されることになります。


package.nls.json:


{

"extension.sayHello.title": "Hello World"
}


最後にローカライズ用の値が格納された packahe.nls.ja.json を作成

最後に用意するのがローカライズされた値を格納したファイル packahe.nls.ja.json (ここでは、ja = 日本語をターゲットにしてます)を作成します。

"extension.sayHello.title": に、"こんにちは!" を指定することで、package.json に定義した "%extension.sayHello.title%" が置きかわるという仕組みです。


packahe.nls.ja.json:


{

"extension.sayHello.title": "こんにちは!"
}

表示例です。

コマンドパレットに Hello World sample: こんにちは! と表示されています。。

更に、コンテキストメニューにも出してみました。


"*.category" をローカライズしてしまうと・・・

VS Code の built-in Markdown 機能で、コマンドパレットに markdon と入力しても markdown 関連のコマンドがヒットしないのなぜかなーっと思って調べてみると、"markdown.category": "マークダウン" と設定されていました。

https://github.com/Microsoft/vscode/blob/master/i18n/jpn/extensions/markdown/package.i18n.json#L6-L10

{

"markdown.category": "マークダウン",
"markdown.preview.title": "プレビューを開く",
"markdown.previewSide.title": "プレビューを横に表示",
"markdown.showSource.title": "ソースの表示"
}

これだと、言語に ja が設定されている環境では、マークダウン と入力しないと候補が出てこないことになります。

このように "category" プロパティを追加し、そのコマンドが属するカテゴリを指定することができます。

こちらも %extension.sayHello.category% の様に % で囲まれた文字列とし、ローカライズ用のファイルで定義することも可能であることがわかりますが、"title" 共々、ローカライズされた値を設定してしまうと、コマンドパレットからはローカライズされた値でなければ検索対象としてヒットしなくなるため、ローカライズする時は気をつけたいところです。

ちなみに、この Issue #16087 は VS Code 1.8.0-insider 2bd85b8 で修正済みとなりました。


設定の概要もローカライズしてみる

settings.json では、拡張機能毎に様々プロパティが提供され、分かり易くするためにプロパティに概要をつけられるていることが多いです。

この概要のローカライズも、似たような作業で簡単に行うことができます。

contributes.configuration を参考に、settings.json へ設定項目を追加してみます。

項目だけとなりますので、気軽に試してみてください。


package.json に追加:


まずは、肝心のプロパティを追加します。

ここでは、sayHello というプロパティをでっちあげます。

そして、"description" には、やはり % で括った文字列 "%extension.sayHello.setting.desc%" を指定します。

    "configuration": {

"type": "object",
"title": "Hello World sample",
"properties": {
"sayHello": {
"type": ["string", "null"],
"default": null,
"description": "%extension.sayHello.setting.desc%"
}
}
}


package.nls.json に追加:


ja 以外では、概要に "Hello World setting" と表示するようにします。

  "extension.sayHello.setting.desc": "Hello World setting"


packahe.nls.ja.json に追加:


ja では、概要に "こんにちは! の設定項目です" と表示するようにします。

  "extension.sayHello.setting.desc": "こんにちは! の設定項目です"

実行結果は、

"locale: "en" の場合

"locale: "ja" の場合

とっても簡単です。

ちなみに、この画面は開発中の VS Code Insiders (1.8) のものとなりますが、Default Settings の画面が大きく変更されています。


Microsoft/vscode-nls

この実装は、下記のモジュールで実現されているようです。

用意できる言語は、Display Language で確認でき、ファイル名は下記を準備し、その言語でメッセージを用意することになります。


  • package.json

  • package.nls.json

  • package.nls.de.json

  • package.nls.es.json

  • package.nls.fr.json

  • package.nls.it.json

  • package.nls.ja.json

  • package.nls.ko.json

  • package.nls.ru.json

  • package.nls.zh-cn.json

  • package.nls.zh-tw.json

コマンドパレットに英語とローカライズされた値を同時に出力する場合は、vscode-nls を利用し、拡張機能の中でラベルとして扱う必要があるみたい。


参考