に参加して、VS Code の AI 支援開発について学びましょう。

2018年6月 (バージョン 1.25)

更新 1.25.1: この更新では、これらの問題に対処しています。

ダウンロード: Windows: x64 | Mac: Intel | Linux 64-bit: deb rpm tarball | 32-bit: deb rpm tarball


Visual Studio Code の2018年6月リリースへようこそ。先月プレビュー版として発表されたいくつかの機能が安定版に移行したことを大変嬉しく思います。主なハイライトは以下のとおりです。

これらのリリースノートをオンラインで読みたい場合は、code.visualstudio.com更新 にアクセスしてください。
この 1.25 リリースに関するハイライトビデオも、Cloud Developer Advocate のBrian Clark氏が公開しています。

リリースノートは、VS Codeの重点分野に関連する以下のセクションにまとめられています。さらに詳しい更新は以下の通りです。

  • ワークベンチ - ファイルとフォルダーを空の Explorer にドロップ、統一された履歴ナビゲーション。
  • エディター - スマートな提案選択、スニペットのプレースホルダー変換。
  • 言語 - フォルダーの名前変更時に JS/TS インポートを更新、CSS の擬似セレクターと要素。
  • プレビュー機能 - Windows でのユーザー設定、Windows および Linux 用のカスタムツールバーとメニューバー。
  • 拡張機能の作成 - グリッドエディターレイアウトを提供、補完項目の事前選択。
  • 新しいコマンド - 新しいグリッドエディターレイアウトコマンドとキーボードショートカット。

Insiders: 新しい機能をできるだけ早く見たいですか?毎日のInsidersビルドをダウンロードして、利用可能になり次第最新のアップデートを試すことができます。Visual Studio Codeの最新ニュース、アップデート、コンテンツについては、Twitterで@codeをフォローしてください!

Workbench

グリッドエディターレイアウト

エディターを垂直方向と水平方向の両方に配置できるようになり、3つ以上のエディターを並べて表示できるようになりました。

Grid Editor Layout

柔軟なレイアウトをサポートするために、空のエディターグループを作成できます。デフォルトでは、エディターグループの最後のエディターを閉じると、グループ自体も閉じられますが、この動作は新しい設定workbench.editor.closeEmptyGroups: falseで変更できます。

Grid Empty

新しいView > Editor Layoutメニューには、事前に定義されたエディターレイアウトのセットがあります。

Grid Editor Layout Menu

横に開くエディター (例えば、エディターツールバーのSplit Editorアクションをクリックするなど) は、デフォルトでアクティブなエディターの右側に開きます。アクティブなエディターの下にエディターを開くことを希望する場合は、新しい設定workbench.editor.openSideBySideDirection: downを構成してください。

キーボードだけでエディターレイアウトを調整するための新しいコマンドはたくさんありますが、マウスを使用する方が好ましい場合は、ドラッグアンドドロップでエディターを任意の方向に素早く分割できます。

Grid Editor Drag and Drop

エディターグループは無制限になり、さまざまな方法で配置できるため、OPEN EDITORSビューではエディターグループにLeftCenterRightのラベルは付けられなくなりました。代わりに、エディターグループは作成時間に応じて番号でラベル付けされます。最後に作成されたエディターグループは、常にOPEN EDITORSリストの最後に表示されます。私たちはこれが、レイアウト内でエディターグループを移動する際にリストの変更を最小限に抑える良いモデルであると判断しました。

Grid Open Editors View

拡張機能とテーマへの影響については拡張機能の作成セクションを、新しいグリッドエディターレイアウトコマンドのリストについては新しいコマンドを参照してください。

プロのヒント: エディターを分割するツールバーアクションの上にマウスを置き、Altキーを押しながらホバーすると、別の向きに分割するオプションが表示されます。これは、右または下に素早く分割する便利な方法です。

Grid Alt Click

グリッドレイアウトの作業により、中央揃えのエディターレイアウトの動作が変更されました。

  • 中央揃えのエディターレイアウト内で任意のエディターレイアウトを開くことができるようになりました。これにより、ユーザーにさらなる柔軟性が提供されます。
  • 中央揃えのエディターレイアウトは、レイアウトに基づいて自動的に有効化/無効化されなくなりました。これは時々混乱を招き、予期しない動作につながるためです。

アウトラインビュー

アウトラインビューはプレビュー版からリリースされ、デフォルトで有効になりました。ファイルエクスプローラーの下部に独立したセクションとして表示されます。展開すると、現在アクティブなエディターのシンボルツリーが表示されます。

アウトラインビューには、さまざまな並べ替え順モード、オプションのカーソルトラッキング、および通常の開くジェスチャーがサポートされています。また、入力中にシンボルを検索またはフィルターする入力ボックスも含まれています。エラーと警告もアウトラインビューに表示され、問題の場所を一目で確認できます。

Outline view

アウトラインビューには、アイコンの有効/無効の切り替え、エラーと警告の表示制御 (すべてデフォルトで有効) を可能にするいくつかの設定があります。

  • outline.icons - アウトライン要素をアイコンでレンダリングするかどうかを切り替えます。
  • outline.problems.enabled - アウトライン要素にエラーと警告を表示します。
  • outline.problems.badges - エラーと警告にバッジを使用するかどうかを切り替えます。
  • outline.problems.colors - エラーと警告に色を使用するかどうかを切り替えます。

拡張機能の作成者向けの新しい API もあります。

ポータブルモード

VS Code がポータブルモードをサポートするようになりました。これにより、VS Code によって作成および維持されるすべてのデータがインストール場所の近くに配置されます。これにより、VS Code の設定を USB ドライブやファイル共有を介して、異なる環境間で簡単に移動できます。ポータブルモードは、Windows および Linux の ZIP ダウンロード、および macOS の通常のアプリケーションダウンロードでサポートされています。詳細はこちらをクリックしてください。

空のファイルエクスプローラーにファイルやフォルダーをドロップ

ファイル、フォルダー、および VS Code ワークスペースファイルを空の Explorer にドロップして開くことができるようになりました。

empty drop

履歴ナビゲーション

入力履歴のナビゲーションが、VS Code 全体でより自然で一貫性のあるものになりました。UpArrow (history.showPrevious) および DownArrow (history.showNext) キーを使用して、検索ビューと問題ビューの入力ボックス、およびエディター、ターミナル、Web ビューの検索ウィジェットをナビゲートできます。

シンプルさと一貫性のために、入力ボックス間のナビゲーションのデフォルトキーバインディングをUpArrowDownArrowからCtrl+UpArrow (macOSではCmd+UpArrow) とCtrl+DownArrow (macOSではCmd+DownArrow) にそれぞれ変更しました。 ⌘↑ (Windows, Linux Ctrl+Up)⌘↓ (Windows, Linux Ctrl+Down) および ⌘↑ (Windows, Linux Ctrl+Up) のキーバインディングを更新することで、以前の動作に戻すことができます。

: 既存の18個の履歴ナビゲーションコマンドもすべて削除し、history.showPrevioushistory.showNextの2つのコマンドに統合しました。

Editor

ホバー表示オプション

エディターのテキストを覆うホバーの提案がない方が良いというユーザーもいるため、エディターのホバーは3つの追加設定でカスタマイズできるようになりました。editor.hover.enabledを使用してエディターのホバーを切り替え、editor.hover.delayを使用してホバーが表示されるまでの時間をカスタマイズし、editor.hover.stickyを使用してマウスをホバーの上に移動したときにホバーが常に表示されるように変更できます。

サブワードのサポート

サブワードナビゲーションとサブワード削除のための新しいコマンドが追加されました。これらのコマンドは、キャメルケースの位置とアンダースコア (_) で停止します。

editor sub-word navigation

それらをバインドする方法の例を次に示します。

{ "key": "ctrl+alt+right",          "command": "cursorWordPartRight",
                                       "when": "textInputFocus" },
{ "key": "ctrl+shift+alt+right",    "command": "cursorWordPartRightSelect",
                                       "when": "textInputFocus" },
{ "key": "ctrl+alt+left",           "command": "cursorWordPartStartLeft",
                                       "when": "textInputFocus" },
{ "key": "ctrl+shift+alt+left",      "command": "cursorWordPartStartLeftSelect",
                                       "when": "textInputFocus" },
{ "key": "ctrl+alt+backspace",       "command": "deleteWordPartLeft",
                                       "when": "textInputFocus && !editorReadonly" },
{ "key": "ctrl+shift+alt+backspace", "command": "deleteWordPartRight",
                                       "when": "textInputFocus && !editorReadonly" },

提案の選択

言語 IntelliSense プロバイダーは、どの提案が最適であるかをよく知っており、このバージョンの VS Code では、提案を事前に選択できるようになりました。事前に選択された提案のための新しいAPIがあり、利用可能な場合、エディターはリストの最初の提案ではなく、その提案を選択します。

suggestion selection

スニペットプレースホルダー変換

スニペットがようやくプレースホルダー変換をサポートしました。プレースホルダー変換は変数変換に似ていますが、より動的です。変換は、あるプレースホルダーから次のプレースホルダーに切り替えるときに適用され、その文法ルールは次のとおりです: ${_int_**/_regex_**/_format_string_**/_opts_**}**。

以下は、「Hello World」をドイツ語の対応する単語に置き換えるサンプルです。

"HelloWorld": {
  "prefix": "say_hello",
  "body": "${1} ${2} -> ${1/Hello/Hallo/} ${2/World/Welt/}"
}

snippet placeholder transformation

変換の可能性を最大限に引き出す方法と詳細については、スニペット文法を参照してください。

統合ターミナル

パフォーマンスの向上

統合ターミナルのパーサーが、ANSI準拠性の向上と受信データの処理速度を約30%向上させるために、ゼロから再記述されました。これは、xterm.jsへのアップストリームコミュニティからの貢献として提供されました。

太字の明るい色の設定

現在、ターミナルはすべての太字テキストを明るい色のバリアントを使用するように変換します。これはターミナルエミュレーター間で一貫性がなく、主にレガシーな理由によるものです。この自動変換をオフにすることで、太字テキストに明るくない色を使用できるようになりました。

{
  "terminal.integrated.drawBoldTextInBrightColors": false
}

これは、xterm.jsへのアップストリームコミュニティからの貢献として提供されました。

デバッグ

フローティングデバッグツールバー

前回のマイルストーンで、デバッグビューにデバッグツールバーをドッキングする新しい設定 ("debug.toolBarLocation": "docked") を導入しました。このマイルストーンでは、ユーザーからのフィードバックを検討し、フローティングツールバーの動作も改善しようと試みました ("debug.toolBarLocation": "floating")。

フィードバックから得られたコンセンサスは、ツールバーが常に表示されるべきであり (アクティブなビューに関係なく)、何も隠すべきではない (例えば、エディタータブなど) というものでした。そのため、フローティングツールバーをエディター領域にドラッグできるようにすることで「解放」しました。これは、エディタータブを頻繁に使用するが、デバッグツールバーも常に表示したいユーザーに役立つはずです。

debug toolbar

既存のdebug.hideActionBar設定はdebug.toolBarLocation設定で値hiddenによって処理されるため、debug.hideActionBar削除されます

言語

TypeScript 2.9.2

VS Code が TypeScript 2.9.2 を同梱するようになりました。このマイナーリリースでは、多くのバグが修正され、安定性が向上しています。変更点の完全なセットはこちらで確認できます。

フォルダーの名前変更時にインポートパスを更新

前回のリリースでは、JavaScript または TypeScript ファイルを移動または名前変更したときに、インポートパスが自動的に更新されるようになりました。この機能は、ディレクトリを移動または名前変更した場合にも機能するようになりました。ここでも、デフォルトでは、VS Code はパスを更新できるかどうかを尋ねます。javascript.updateImportsOnFileMove.enabledおよびtypescript.updateImportsOnFileMove.enabledの設定で、プロンプトの動作を制御できます。

有効な値は次のとおりです

  • "prompt" - デフォルト。パスを更新するかどうかを尋ねます。
  • "always" - 常に自動的にパスを更新します。
  • "never" - 自動的にパスを更新せず、プロンプトも表示しません。

階層型 Markdown ドキュメントシンボル

組み込みの Markdown サポートは、新しいDocumentSymbol API を使用して、Markdown の見出しがアウトラインビューで適切にネストされるようにします。

The Outline view for a Markdown document

MDN からの新しい CSS 擬似セレクターと擬似要素

4月のリリースでは、最新の CSS/SCSS/Less サポートのために Mozilla Developer Network からデータソースを開始しました。今回のリリースでは、以下の擬似セレクター/要素を追加しました。

  • :defined | :dir | :focus-visible | :focus-within | :placeholder-shown
  • ::-moz-range-progress | ::-moz-range-thumb | ::-moz-range-track | ::-webkit-progress-inner-value | ::grammar-error | ::placeholder

CSS Pseudo Selectors and Elements

ブラウザ互換性データの精度向上

mdn/browser-compat-dataのおかげで、MDN からこのセクションを CSS/SCSS/Less 補完に追加しました。

CSS justify-items

justify-itemsプロパティは、CSS グリッドレイアウトの他の多くの CSS プロパティとともに、Edge バージョン16以降でサポートされています。VS Code は、MDN からデータを取得することで、CSS 機能のブラウザ互換性データを最新の状態に保っています。

未知のアットルールを適切に処理

CSS プリプロセッサを使用している人は、ビルド時に有効な CSS にコンパイルされるカスタムアットルールを使用する場合があります。以前は、VS Code はそのようなアットルールを解析したり処理したりできませんでした。このリリースでは、アットルールをより適切にサポートし、以下のことができるようになりました。

  • CSS 構文に準拠しているため、正しい構文ハイライトを受け取ります。
  • 間違った場所でエラーを生成しなくなります。
  • css.lint.unknownAtRulesで制御できる正しいエラーを生成します。

CSS Unknown At-Rules

拡張機能

拡張機能ビューの新しいデフォルト表示

これまで、拡張機能ビューのデフォルト表示には、インストール済み拡張機能と推奨拡張機能のセクションが含まれていました。インストールされているが無効な拡張機能が有効な拡張機能の中に混在しているため、後者の操作が困難でした。今回、新しいデフォルト表示を提供し、まず有効な拡張機能が表示され、次に推奨拡張機能のセクション、そして最後に無効な拡張機能の折りたたまれたセクションが表示されるようになりました。

Default Extensions View

これらのセクションは、拡張機能ビューのコンテキストメニューを使用して、いつでも並べ替え、折りたたみ/展開、または非表示にできます。また、ViewメニューのOpen View...コマンドを使用して、これらのセクションを表示/非表示にすることもできます。

Customize Extensions View

拡張機能の推奨事項を却下

開いているファイルとワークスペース環境に基づいて、拡張機能をお勧めします。すべての推奨事項がプロジェクトに適しているとは限らないことを理解しているため、特定の推奨事項を却下できるようになりました。

推奨事項を却下するには、拡張機能項目をクリックして詳細ペインを開き、Ignore Recommendationボタンを押します。無視された推奨事項は、今後あなたに推奨されなくなります。

Dismiss Recommendations

ワークスペースの推奨事項を管理

extensions.jsonファイル内のワークスペース推奨事項を使用して、ワークスペースのユーザー向けに推奨される拡張機能のセットを既に構成できました。これらの推奨事項の管理がはるかに簡単になりました。拡張機能ビューの任意の拡張機能をクリックして詳細ペインを開きます。その後、以下の新しいコマンドを使用して、推奨事項を追加したり、ワークスペースのユーザーに推奨したくない特定の拡張機能を禁止したりできます。

  • 拡張機能: 推奨拡張機能に追加 (ワークスペース)
  • 拡張機能: 推奨拡張機能に追加 (ワークスペースフォルダー)
  • 拡張機能: 推奨拡張機能を無視 (ワークスペース)
  • 拡張機能: 推奨拡張機能を無視 (ワークスペースフォルダー)

言語パック

VS Code は現在、表示言語として英語のみを同梱しており、他の言語は VS Code Marketplaceからインストール可能な言語パックに依存しています。VS Code のバージョン1.23または1.24でプロンプトが表示されたときに言語パックをインストールした場合、この変更に気づかないはずです。古いバージョンの VS Code からアップグレードする場合、または新規インストールの場合、OS の UI 言語の言語パックをインストールするようプロンプトが表示されます。追加の言語パックは、拡張機能ビュー (⇧⌘X (Windows, Linux Ctrl+Shift+X)) を使用して Marketplace からインストールできます。

まとめると

  • VS Code バージョン 1.22 以前から 1.25 に更新する場合、表示言語は英語になり、Marketplace に利用可能な言語パックがある場合、VS Code は OS の UI 言語の言語パックをインストールするようプロンプトを表示します。
  • 1.23 または 1.24 から 1.25 に更新した場合、すでに UI 言語の言語パックをインストールするようプロンプトが表示されているはずです。その場合、1.25 は通常どおり起動し、表示言語は選択された UI 言語として表示されます。言語パックをインストールしなかった場合は、インストールするようプロンプトが表示されます。
  • VS Code バージョン 1.25 以降の新規インストールでは、適切な言語パックが Marketplace に利用可能な場合、言語パックをインストールするようプロンプトが表示されます。

プレビュー機能

プレビュー機能はリリース準備ができていませんが、使用できる程度には機能しています。開発段階での皆様の早期フィードバックをお待ちしております。

新しい設定エディター

このマイルストーンでは、設定を編集するための GUI の作業を継続しました。まだプレビュー版ですが、試してみたい場合は、基本設定: 設定を開く (プレビュー)コマンドで開くことができます。ご意見をお聞かせください。 こちらの GitHub issue に残していただけます。

New Settings Editor

先月からの新しい変更点の一部を以下に示します。

  • 設定を新しいカテゴリに整理する「目次」(TOC)。
  • 設定行のレイアウトが整理され、刷新されました。
  • 「リセット」ボタンが削除されました。設定をデフォルト値に編集すると、settings.jsonから削除されます。

また、設定の検索中に「目次」の3つの異なるオプション (showhidefilter) を表示するには、"workbench.settings.settingsSearchTocBehavior"設定を試して、どのオプションがお好みかお知らせください。

Windows 用のユーザー設定

Windows ユーザー向けに、管理者権限なしでインストールできる新しいプレビューセットアップパッケージが利用可能になりました。このセットアップパッケージは、よりスムーズなバックグラウンド更新エクスペリエンスも提供します。この機能は今のところ Insiders 版でのみ利用可能であり、Stable ユーザーベースに最高のエクスペリエンスを提供するために、7月中にさらなるフィードバックをいただきたいと考えています。

Insiders ユーザーセットアップパッケージのダウンロードリンクはこちらです。

Windows/Linux 用のカスタムタイトルバーとメニュー

Windows および Linux ユーザーは、window.titleBarStyle設定値customを使用できるようになり、それに合わせて新しいメニューバーを実装しました。この設定はまだデフォルトでは有効になっていませんが、window.titleBarStyle設定でオンにすることができます。

Windows と Linux で設定が有効になると、古いメニューバーは、ライトまたはダークテーマに一致する新しいメニューバーに置き換えられます。新しいメニューバーには、矢印キーによるトップレベルのキーボードナビゲーションなどのいくつかの機能強化も含まれています。最後に、製品全体のメニューも新しいメニューバーに一致します。

Custom title bar and menu bar

新しいメニューとタイトルバーの改善を継続し、workbench-title または workbench-menu のラベルが付いた問題にも対処していきます。

ターミナル: 動的テクスチャアトラス

ターミナルキャンバスに新しい「動的テクスチャアトラス」を有効にする実験的な設定が追加されました。これにより、ターミナルが文字グリフを保存するために使用するキャッシュ戦略が変更されます。デフォルトの背景に固定されたグリフのセットではなく、グリフは必要に応じて、使用されている背景に関係なくテクスチャアトラスに追加されるようになりました。これにより、最初のターミナル起動時間が短縮され、デフォルトの背景を使用しない文字のレンダリング時間が短縮され、全体的なレンダリングパフォーマンスも向上するはずです。

これは最終的にデフォルトになりますが、今のところ以下の設定でオプトインできます。

{
  "terminal.integrated.experimentalTextureCachingStrategy": "dynamic"
}

これは、xterm.jsへのアップストリームコミュニティからの貢献として提供されました。

拡張機能の作成

グリッドエディターレイアウト: ViewColumn

新しいグリッドエディターレイアウト機能をサポートするために、API の調整はわずかです。最も注目すべきは、アクティブなエディターの横にエディターを開くために使用できる新しいViewColumn.Besideアクションです。グリッドエディターレイアウトでは、開いているエディターの数に制限がなくなったため、そのオプションを使用すると、横にスペースがない限り、常にアクティブなエディターの横に新しいエディターが作成されます。ユーザー設定workbench.editor.openSideBySideDirectionに応じて、これはエディターの右側または下側になります。

テキストエディターとウェブビューのViewColumn値は、以下に示すように、エディター領域での表示順序(左から右)に従います。

Grid Editor Numbering

ViewColumn列挙型はViewColumn.Nineまで拡張されましたが、TextEditorはグリッドに含まれている限り、常にビュー列として番号が割り当てられます。

エディターグループが移動されたり、エディターグループが閉じられたりすると、以前と同様にonDidChangeTextEditorViewColumnイベントが発生します。

グリッドエディターレイアウト: 新しいコマンド

新しいグリッドエディターレイアウトをサポートするための API への変更は最小限ですが、拡張機能は追加された新しいコマンドを利用することでグリッドエディターレイアウトを活用できます (完全な概要は新しいコマンドセクションを参照してください)。

新しいvscode.setEditorLayoutは、単一のコマンドと引数でエディター全体のレイアウトを変更できるため、少し説明が必要です。レイアウトは、初期の(オプションの)方向(0 = 水平、1 = 垂直)と、その中のエディターgroupsの配列を持つオブジェクトとして記述されます。各エディターグループは、sizeと、方向に対して直交するように配置されるエディターgroupsの別の配列を持つことができます。エディターグループのサイズが提供される場合、行または列ごとに適用するために、合計が1である必要があります。

2x2 グリッドの例

{
  "orientation": 0,
  "groups": [
    { "groups": [{}, {}], "size": 0.5 },
    { "groups": [{}, {}], "size": 0.5 }
  ]
}

エディターはデフォルトでアクティブな ViewColumn に開きます

テキストエディターまたはウェブビューを開くときにViewColumnが指定されていない場合、VS Code はデフォルトでViewColumn.Oneではなく、現在アクティブなエディターグループに開くようになりました。以前の動作を維持したい場合は、開くときにViewColumn.Oneを渡してください。

事前に選択された補完項目

補完項目を提供する拡張機能は、それらを「事前に選択済み」としてマークできるようになりました。これは、多くの補完が存在するが、一部が選択される可能性が高い場合に役立ちます。この例として、ユーザーが既知の変数型を割り当てる場合が挙げられます。この機能により、拡張機能は、console.dirxmlよりもconsole.logを優先するなど、より一般的に使用される補完を選択することもできます。

API の追加は'CompletionItem#preselect: boolean'であり、事前に選択された項目が複数存在する場合は、ランクが最も高いものが選択されます。

ドキュメントシンボル

新しいアウトラインビューツリーを最大限に活用するには、拡張機能はDocumentSymbolProvidersを変更してDocumentSymbolsを返す必要があります。これは、アウトラインツリーのニーズに合わせて追加された新しい型です。ドキュメントシンボルの階層を表現し、シンボルを定義する範囲とシンボルを識別する選択範囲を区別できます。


         +--/**
         |   * Some Comment
<range>--|   */
         |  export function fooFunction() {
         |                  +----------+
         +--}                   |
                                |
                          <selection range>

読み取り専用ファイルシステムプロバイダー

ファイルシステムプロバイダーをreadonlyとして登録できるようになりました。VS Code はこのフラグを尊重し、そのファイルシステムプロバイダーからのリソースに対するすべての変更コマンドを無効にします。また、これらの読み取り専用リソースのエディターも読み取り専用モードで開かれます。

カスタムビュー

ツリービューの可視性

ツリービューが表示されているかどうかを、TreeViewに追加された以下の新しいプロパティとイベントを使用して確認できるようになりました。

/**
 * `true` if the [tree view](#_TreeView) is visible otherwise `false`.
 */
readonly visible: boolean;

/**
 * Event that is fired when [visibility](TreeView.visible) has changed
 */
readonly onDidChangeVisibility: Event<TreeViewVisibilityChangeEvent>;

/**
 * The event that is fired when there is a change in [tree view's visibility](#_TreeView.visible)
 */
export interface TreeViewVisibilityChangeEvent {

  /**
   * `true` if the [tree view](#_TreeView) is visible otherwise `false`.
   */
  readonly visible: boolean;

}

選択リスナー

ツリービューに新しい選択変更イベントが追加され、選択変更をリッスンできるようになりました。

/**
 * Event that is fired when the [selection](#_TreeView.selection) has changed
 */
readonly onDidChangeSelection: Event<TreeViewSelectionChangeEvent<T>>;

/**
 * The event that is fired when there is a change in [tree view's selection](#_TreeView.selection)
 */
export interface TreeViewSelectionChangeEvent<T> {

  /**
   * Selected elements.
  */
  readonly selection: T[];

}

表示とフォーカス

reveal API を呼び出すときに、フォーカスオプションをtrueに設定することで、ツリービューの要素を表示してフォーカスできるようになりました。

reveal(element: T, options?: { select?: boolean, focus?: boolean }): Thenable<void>;

新しいテーマカラー

グリッドエディターレイアウトのサポート作業から生まれた機能として、空のエディターグループの背景色に2つの新しいテーマカラーが追加されました。

  • editorGroup.emptyBackground: 空のエディターグループの背景色。
  • editorGroup.focusedEmptyBorder: フォーカスされた空のエディターグループの枠線色。

Grid Editor Group Background

  • editorPane.background: 中央揃えのエディターレイアウトの左右に表示されるエディターペインの背景色。

Editor Pane Background

非推奨のテーマカラー

グリッドエディターレイアウト機能の導入に伴い、テーマカラーeditorGroup.backgroundはサポートされなくなりました。

名前変更コマンド

名前変更コマンド(editor.action.rename)は、UriPositionを付けて呼び出すことができるようになり、エディターはそれに応じて名前変更操作を開始します。例:

vscode.commands.executeCommand('editor.action.rename', [
  vscode.Uri.file('/my/file.abc'),
  new vscode.Position(14, 7)
]);

診断タグ

診断タグを使用すると、拡張機能は診断に関する追加のメタデータを添付できます。VS Code はこのメタデータを使用して、これらの診断のレンダリング方法を調整します。

const diag = new vscode.Diagnostic(new Range(0, 0, 0, 10), 'Unused');
diag.tags = [vscode.Diagnostic.Unnecessary];

DiagnosticTag.Unnecessaryは、診断が参照されていない、または到達不可能なソースコード用であることを示します。DiagnosticTag.Unnecessaryでマークされたソースコードは、フェードアウトしてレンダリングされます。フェードの量は"editorUnnecessaryCode.opacity"テーマカラーによって制御されます。たとえば、"editorUnnecessaryCode.opacity": "#000000c0"は、コードを75%の不透明度でレンダリングします。ハイコントラストテーマの場合、"editorUnnecessaryCode.border"テーマカラーを使用して、不要なコードをフェードアウトする代わりに下線を表示します。

WebviewPanel.active と WebviewPanel.visible

Webview パネルには2つの新しい読み取り専用プロパティがあります。

  • active - パネルがフォーカスされたときに追跡します。
  • visible- パネルが画面上にあるときに追跡します。

ウェブビューの永続化

ウェブビュー API が拡張され、ウェブビューの状態を保存および復元するサポートが追加されました。

ウェブビューコンテキスト内のgetStateおよびsetState API を使用すると、ウェブビューは状態を保存し、ウェブビュー自体がバックグラウンドタブに移動しても永続化される状態オブジェクトを取得できます。

// Inside a webview's JavaScript
const vscode = acquireVsCodeApi();

// Look up old state (will be undefined if no state is set)
const oldState = vscode.getState();

// Update the persisted state.
// You can save off any json serializable object.
if (oldState) {
  vscode.setState({ count: oldState.count + 1 });
} else {
  vscode.setState({ count: 1 });
}

さらに、拡張機能はWebviewPanelSerializerを登録でき、これにより、特定の種類のウェブビューが VS Code の再起動をまたいで永続化されることが可能になります。これを有効にするには、拡張機能はアクティベーションメソッドでvscode.window.registerWebviewPanelSerializerを呼び出す必要があります。

export function activate(context: vscode.ExtensionContext) {
    ...

    vscode.window.registerWebviewPanelSerializer('myWebviewType', {
        async deserializeWebviewPanel(webviewPanel: vscode.WebviewPanel, state: any) {
            // `state` is the state persisted using `setState` inside the webview
            console.log(`Got state: ${state}`);

            new MyWebview(webviewPanel);
        }
    });
}

拡張機能は、onWebviewPanelアクティベーションイベントも追加する必要があります。

"activationEvents": [
    ...,
    "onWebviewPanel:catCoding"
]

新しいウェブビュー永続化 API は、ウェブビュー拡張機能作成ページに文書化されています。サンプルウェブビュー拡張機能も、これらの新しい API の使用方法を示しています。

言語パック: 最小限の翻訳

VS Code は、利用可能な言語パックを、その言語パックの言語でユーザーに促すようになりました。以下は、簡体字中国語と英語で簡体字中国語の言語パックを推奨する例です。

Language Pack recommendation

この表示には、言語パックの作成者が言語パック内で次の最小限の翻訳文字列を翻訳する必要があります。

{
   showLanguagePackExtensions: localize('showLanguagePackExtensions', "Search language packs in the Marketplace to change the display language to {0}."),
   searchMarketplace: localize('searchMarketplace', "Search Marketplace"),
   installAndRestartMessage: localize('installAndRestartMessage', "Install language pack to change the display language to {0}."),
   installAndRestart: localize('installAndRestart', "Install and Restart")
}

言語サーバプロトコルインスペクター

vscode-languageclientを使用する言語サーバーは、ロギングサポートを受け取るために[langId].trace.server設定を指定できます。生成されるログは VS Code と言語サーバー間の LSP 通信を理解するために貴重ですが、ログが長く、有用な情報を抽出するのが難しい場合があります。

新しい LSP Inspector を使用すると、LSP ログを理解するのに役立つツールが手に入ります: https://microsoft.github.io/language-server-protocol/inspector/

インスペクターでは、次のことができます。

  • Language Client と Server 間のリクエスト、レスポンス、通知をスキャンします。
  • 検索または事前定義されたフィルターを使用してログをフィルタリングし、有用な情報を見つけます。

LSP Inspector

Inspector は言語拡張機能のデバッグに役立ちます。ユーザーに LSP ログをバグレポートに添付するように依頼し、Inspector を使用してログを分析できます。

言語サーバーガイドが更新され、ロギングサポートと LSP インスペクターの機能に関するセクションが含まれるようになりました。

言語サーバー: エンドツーエンドテスト

エンドツーエンドテストに関するセクションが言語サーバーガイドに追加されました。

言語サーバーのコンポーネントを単体テストするのと比較して、エンドツーエンドテストは VS Code でワークスペースを開き、拡張機能ホストで言語拡張機能を起動し、言語拡張機能の実際の動作に対してアサーションを行います。これにより、ワークスペースと VS Code の状態のモックが容易になり、実際の VS Code の動作が確認できます。

言語サーバー: 更新されたガイド

言語サーバーガイドが更新されました。主な改善点は次のとおりです。

  • 上記で述べたロギングとテストに関するセクション。
  • Language Server Protocol、Language Server、およびそれらの関係についての説明。
  • LSP と Language Server の更新された図。
  • 更新されたlsp-sampleサンプルコード。
  • LSP ウェブサイトへのより多くの参照。

提案された拡張API

各マイルストーンには新しい提案APIが付属しており、拡張機能開発者はこれらを試すことができます。いつものように、皆様からのフィードバックをお待ちしております。提案APIを試すには、次の手順を実行します。

  • 提案APIは頻繁に変更されるため、Insiders版を使用する必要があります。
  • 拡張機能のpackage.jsonファイルに次の行が必要です: "enableProposedApi": true
  • vscode.proposed.d.tsファイルの最新バージョンをプロジェクトにコピーします。

提案APIを使用する拡張機能は公開できないことに注意してください。次回のリリースでは互換性のない変更が行われる可能性があり、既存の拡張機能を壊すことは決して望ましくありません。

WorkspaceEdit でファイルの作成/名前変更/削除が可能に

WorkspaceEditを拡張し、ファイルまたはフォルダの作成、名前変更、削除に使用できる提案APIを追加しました。これは、複雑なリファクタリング(例えば、型の名前変更時にファイルの名前を変更するなど)に役立ち、他のシナリオも可能にするはずです。

ローカル名前変更イベント

名前変更が発生する前と後に発生する2つのイベントを提案しています。これらはonWillRenameFileonDidRenameFileと呼ばれ、拡張機能が名前変更に反応または参加できるようにします。

QuickInput API

新しいQuickPickおよびInputBox API は、既存のshowQuickPickおよびshowInputBox API よりも柔軟なユーザー入力の収集を可能にします。新しい API では、入力オブジェクトの新しいインスタンスを作成し、その上にイベントハンドラーを登録し、使用ケースに応じてプロパティを設定します。

export namespace window {
  export function createQuickPick<T extends QuickPickItem>(): QuickPick<T>;
  export function createInputBox(): InputBox;
}

サンプル拡張機能に QuickInput API の使用例があります。

マルチステップ入力サンプル

Multi-step input sample

既存のshowQuickPickshowInputBox API が十分に柔軟でない場合は、新しいQuickPickInputBox API を使用してください。そうでなければ、既存の API を使用すれば、より早く作業が完了します。

フィードバックと議論には#53327を使用してください。

ターミナルレンダラー

ターミナル「レンダラー」の概念が提案されています。ターミナルレンダラーは基本的にターミナルパネル内のターミナルインスタンスですが、バックエンドプロセスはなく、代わりに拡張機能がプロセスとして機能します。これは、拡張機能が何らかのプロセスの入出力パイプにアクセスでき、それらがターミナルレンダラーに接続される VS Code 内でターミナルマルチプレクサを実装するのに役立ちます。Live Share 拡張機能は、共有ターミナルサポートの安定性と保守性を向上させるために、この新しい API の使用を計画しています。

export namespace window {
  export function createTerminalRenderer(name: string): TerminalRenderer;
}

export interface TerminalRenderer {
  name: string;
  dimensions: TerminalDimensions | undefined;
  readonly maximumDimensions: TerminalDimensions | undefined;
  readonly terminal: Terminal;
  readonly onDidAcceptInput: Event<string>;
  readonly onDidChangeMaximumDimensions: Event<TerminalDimensions>;
  write(text: string): void;
}

export interface TerminalDimensions {
  readonly columns: number;
  readonly rows: number;
}

もう一つの使用例は、拡張機能が独自の REPL を作成する場合です。これは、拡張機能が各文字の入力をリッスンし、Enterキーが押されたときに動作することで機能します。

const shell = vscode.window.createTerminalRenderer('My Extension REPL');
shell.write('Type and press enter to echo the text\r\n\r\n');
shell.terminal.show();

let line = '';
shell.onDidAcceptInput(data => {
  if (data === '\r') {
    shell.write(`\r\necho: "${line}"\r\n\n`);
    line = '';
  } else {
    line += data;
    shell.write(data);
  }
});

アクティブなターミナルの追跡

統合ターミナル向けに、window.activeTextEditorおよびwindow.onDidChangeActiveTextEditorと同様に、アクティブなターミナルを追跡できる新しい拡張機能 API を提案しています。

export namespace
  export const activeTerminal: Terminal | undefined;
  export const onDidChangeActiveTerminal: Event<Terminal | undefined>;
}

Terminal.onData が名前変更

Terminal.onDataは、当社の命名ガイドラインに合わせるため、onDidWriteDataに名前が変更されました。

export interface Terminal {
  onDidWriteData: Event<string>;
}

定義リンクにより、定義プロバイダーは定義に追加のメタデータを返すことができます。

export interface DefinitionLink {
  /**
   * Span of the symbol being defined in the source file.
   *
   * Used as the underlined span for mouse definition hover. Defaults to the word range at
   * the definition position.
   */
  origin?: Range;

  /**
   * The resource identifier of the definition.
   */
  uri: Uri;

  /**
   * The full range of the definition.
   *
   * For a class definition for example, this would be the entire body of the class definition.
   */
  range: Range;

  /**
   * The span of the symbol definition.
   *
   * For a class definition, this would be the class name itself in the class definition.
   */
  selectionRange?: Range;
}

この追加情報は、VS Code によって定義へ移動アクションのユーザーエクスペリエンスを向上させるために使用されます。

DefinitionLinkを使用するには、現在DefinitionProviderprovideDefinition2メソッドを実装する必要があります。DefinitionLink API が安定化されると、provideDefinition2を削除し、通常のDefinitionProvider.provideDefinitionメソッドを更新してDefinitionLinkも返せるようにする予定です。

新コマンド

キー コマンド コマンド ID
⌘K ⌘\ (Windows, Linux Ctrl+K Ctrl+\) openSideBySideDirectionで設定された直交方向にエディターを分割します。 workbench.action.splitEditorOrthogonal
アクティブなエディターグループの開いているエディターを表示します workbench.action.showEditorsInActiveGroup
⌃⌘9 (Windows, Linux Shift+Alt+9) アクティブなエディターを最後のエディターグループに移動します。 workbench.action.moveEditorToLastGroup
⌘K ↑ (Windows, Linux Ctrl+K Up) アクティブなエディターグループを上に移動 workbench.action.moveActiveEditorGroupUp
⌘K ↓ (Windows, Linux Ctrl+K Down) アクティブなエディターグループを下に移動 workbench.action.moveActiveEditorGroupDown
最後のエディターグループにフォーカスする workbench.action.focusLastEditorGroup
最初のエディターグループにフォーカスする workbench.action.firstEditorInGroup
⌘W (Windows Ctrl+F4, Linux Ctrl+W) アクティブなエディターグループを閉じる(開いているエディターは隣接グループにマージされます) workbench.action.closeGroup
すべてのエディターグループを閉じる workbench.action.closeAllEditorGroups
アクティブなエディターグループとそのエディターを閉じる workbench.action.closeEditorsAndGroup
⌘K ⌘\ (Windows, Linux Ctrl+K Ctrl+\) アクティブなエディターを上に分割する workbench.action.splitEditorUp
⌘K ⌘\ (Windows, Linux Ctrl+K Ctrl+\) アクティブなエディターを下に分割 workbench.action.splitEditorDown
⌘K ⌘\ (Windows, Linux Ctrl+K Ctrl+\) アクティブなエディターを左に分割する workbench.action.splitEditorLeft
⌘K ⌘\ (Windows, Linux Ctrl+K Ctrl+\) アクティブなエディターを右に分割する workbench.action.splitEditorRight
すべてのエディターグループのエディターをアクティブなエディターに結合します。 workbench.action.joinAllGroups
⌘4 (Windows, Linux Ctrl+4) 4番目のエディターグループにフォーカス(必要に応じて新しいエディターグループを作成) workbench.action.focusFourthEditorGroup
⌘5 (Windows, Linux Ctrl+5) 5番目のエディターグループにフォーカス (必要に応じて新しいエディターグループを作成します) workbench.action.focusFifthEditorGroup
⌘6 (Windows, Linux Ctrl+6) 6番目のエディターグループにフォーカス (必要に応じて新しいエディターグループを作成します) workbench.action.focusSixthEditorGroup
⌘7 (Windows, Linux Ctrl+7) 7番目のエディターグループにフォーカス (必要に応じて新しいエディターグループを作成します) workbench.action.focusSeventhEditorGroup
⌘8 (Windows, Linux Ctrl+8) 8番目のエディターグループにフォーカス (必要に応じて新しいエディターグループを作成します) workbench.action.focusEighthEditorGroup
アクティブなエディターを左のエディターグループに移動 workbench.action.moveEditorToLeftGroup
アクティブなエディターを右のエディターグループに移動 workbench.action.moveEditorToRightGroup
アクティブなエディターを上のエディターグループに移動 workbench.action.moveEditorToAboveGroup
アクティブなエディターを下のエディターグループに移動 workbench.action.moveEditorToBelowGroup
⌘K ⌘← (Windows, Linux Ctrl+K Ctrl+Left) 左のエディターグループにフォーカスする workbench.action.focusLeftGroup
⌘K ⌘→ (Windows, Linux Ctrl+K Ctrl+Right) 右のエディターグループにフォーカスする workbench.action.focusRightGroup
⌘K ⌘↑ (Windows, Linux Ctrl+K Ctrl+Up) 上のエディターグループにフォーカス workbench.action.focusAboveGroup
⌘K ⌘↓ (Windows, Linux Ctrl+K Ctrl+Down) 下のエディターグループにフォーカス workbench.action.focusBelowGroup
左に新しいエディターグループを作成 workbench.action.newEditorGroupLeft
右に新しいエディターグループを作成 workbench.action.newEditorGroupRight
上に新しいエディターグループを作成 workbench.action.newEditorGroupAbove
下に新しいエディターグループを作成 workbench.action.newEditorGroupBelow
エディターレイアウトを切り替える: シングル workbench.action.editorLayoutSingle
エディターレイアウトを切り替え: 2列 workbench.action.editorLayoutTwoColumns
エディターレイアウトを切り替える: 3列 workbench.action.editorLayoutThreeColumns
エディターレイアウトを切り替え: 2行 workbench.action.editorLayoutTwoRows
エディターレイアウトを切り替える: 3行 workbench.action.editorLayoutThreeRows
エディターレイアウトを切り替え: 2x2 グリッド workbench.action.editorLayoutTwoByTwoGrid
エディターレイアウトに切り替える: 2列 (下) workbench.action.editorLayoutTwoColumnsBottom
エディターレイアウトを切り替える: 2列 (右) workbench.action.editorLayoutTwoColumnsRight
エディターレイアウトを切り替える: 中央揃え workbench.action.editorLayoutCentered

新しいlayoutEditorGroupsコマンド

layoutEditorGroupsコマンドを使用すると、エディターグループのレイアウトを作成し、キーバインディングを割り当てることができます。レイアウトは、初期の(オプションの)方向(0 = 水平、1 = 垂直)と、その中のエディターgroupsの配列を持つオブジェクトとして記述されます。各エディターグループは、sizeと、方向に対して直交するように配置されるエディターgroupsの別の配列を持つことができます。エディターグループのサイズが提供される場合、行または列ごとに適用するために、合計が1である必要があります。例:

{
  "key": "Ctrl+0",
  "command": "layoutEditorGroups",
  "args": {
    "orientation": 1,
    "groups": [{ "size": 0.2 }, { "size": 0.6 }, { "size": 0.2, "groups": [{}, {}] }]
  }
}

これにより、以下のレイアウトが生成されます。

Grid Editor Layout Applied

削除されたコマンド

コマンド ID 代替
workbench.action.showEditorsInFirstGroup 代わりにshowEditorsInActiveGroupを使用してください
workbench.action.showEditorsInSecondGroup 代わりにshowEditorsInActiveGroupを使用してください
workbench.action.showEditorsInThirdGroup 代わりにshowEditorsInActiveGroupを使用してください
workbench.action.moveEditorToSecondGroup 代わりにworkbench.action.moveEditor*コマンドを使用してください
workbench.action.moveEditorToThirdGroup 代わりにworkbench.action.moveEditor*コマンドを使用してください
workbench.action.openLastEditorInGroup 代わりにlastEditorInGroupを使用してください
workbench.action.openFolderAsWorkspaceInNewWindow 代わりにduplicateWorkspaceInNewWindowを使用してください
editor.debug.action.toggleColumnBreakpoint 代わりにtoggleInlineBreakpointを使用してください

履歴ナビゲーションコマンド

コマンド ID 代替
search.history.showPrevious 代わりにhistory.showPreviousを使用してください
search.history.showNext 代わりにhistory.showNextを使用してください
search.replaceHistory.showPrevious 代わりにhistory.showPreviousを使用してください
search.replaceHistory.showNext 代わりにhistory.showNextを使用してください
search.history.showPreviousIncludePattern 代わりにhistory.showPreviousを使用してください
search.history.showNextIncludePattern 代わりにhistory.showNextを使用してください
search.history.showPreviousExcludePattern 代わりにhistory.showPreviousを使用してください
search.history.showNextExcludePattern 代わりにhistory.showNextを使用してください
find.history.showPrevious 代わりにhistory.showPreviousを使用してください
find.history.showNext 代わりにhistory.showNextを使用してください
workbench.action.terminal.findWidget.history.showPrevious 代わりにhistory.showPreviousを使用してください
workbench.action.terminal.findWidget.history.showNext 代わりにhistory.showNextを使用してください
editor.action.extensioneditor.showPreviousFindTerm 代わりにhistory.showPreviousを使用してください
editor.action.extensioneditor.showNextFindTerm 代わりにhistory.showNextを使用してください
editor.action.webvieweditor.showPreviousFindTerm 代わりにhistory.showPreviousを使用してください
editor.action.webvieweditor.showNextFindTerm 代わりにhistory.showNextを使用してください
repl.action.historyPrevious 代わりにhistory.showPreviousを使用してください
repl.action.historyNext 代わりにhistory.showNextを使用してください

新しいドキュメント

新しい Python Flask チュートリアル

VS Code で Python Flask Web アプリケーションを素早く作成、編集、デバッグする方法を示す新しいVisual Studio Code で Flask を使用するチュートリアルが公開されました。

ウェブサイトデプロイチュートリアルを更新しました

Azure Storageを使用して静的ウェブサイトを作成およびデプロイするためのAzure に静的ウェブサイトをデプロイチュートリアルを更新しました。Azure Storage 拡張機能によって提供される新機能により、ウェブサイトのデプロイが簡素化されました。

注目すべき変更

  • 35361: macOS High Sierra でのネイティブウィンドウタブ機能の制限
  • 40158: マルチセッションケースにおけるブレークポイント検証 UI の修正
  • 42726: ファイルを開く: 絶対パスが指定されている場合、名前にスペースを含むファイルを開くことができません
  • 49591: ツールバーにエディターアクションとして「すべて閉じる」ボタンを設ける
  • 51200: Linux のプロセスモニターが誤ったプロセス負荷を表示する
  • 51440: 通知をマウスの中央ボタンで閉じられるようにする

謝辞

最後に、そしてもちろん最も重要なこととして、Visual Studio Codeをさらに良くするために協力してくれた以下の方々に、心からの感謝を申し上げます!

vscodeへの貢献者

vscode-vsceへのコントリビューション

language-server-protocolへの貢献者

vscode-node-debugへの貢献

vscode-chrome-debug-coreへの貢献

vscode-chrome-debugへの貢献

localizationへの貢献

TransifexのVS Codeプロジェクトチームには800人以上のメンバーがおり、毎月約100人のアクティブな貢献者がいます。新しい翻訳の提供、翻訳への投票、プロセス改善の提案など、皆様の貢献に感謝いたします。

このリリースに貢献してくださった方々のスナップショットを以下に示します。貢献者リストを含むプロジェクトの詳細については、プロジェクトサイトhttps://aka.ms/vscodelocをご覧ください。

  • フランス語: Antoine Griffard, Quentin BRETON。
  • イタリア語: Andrea Dottor, Emilie Rollandin, Aldo Donetti, Luigi Bruno, Piero Azi, Marco Dal Pino, Alessandro Alpi, Emanuele Ricci, Lorthirk, Riccardo Cappello。
  • ドイツ語: Ettore Atalan。
  • スペイン語: Alejandro Medina, Alberto Poblacion, José M. Aguilar。
  • 日本語: Shunya Tajima, Satoshi Kajiura, Seiji Momoto, yoshioms, Hiroyuki Mori, Yuki Ueda, Yano Naoki, Yuichi Nukiyama。
  • 中国語 (簡体字): Joel Yang, pluwen, Yurui Zhang, Simon Chan, YF, Vicey Wang。
  • 中国語 (繁体字): Duran Hsieh, Winnie Lin, Alan Liu, Alan Tsai, Will 保哥, Han Lin。
  • 韓国語: Kyunghee Ko。
  • ロシア語: Ivan Kuzmenko。
  • ブルガリア語: Любомир Василев.
  • ハンガリー語: Tar Dániel, Dóczi Dominik。
  • ポルトガル語 (ブラジル): Danilo Dantas, Otacilio Saraiva Maia Neto, Roger Figueiredo, Lucas Miranda, Rafael Oliveira, Yehoshua Oliveira, Bruno Sonnino, Roberto Fonseca。
  • トルコ語: Adem Coşkuner, Burak Karahan, Koray Sarıtaş。
  • オランダ語: RubenJacobse, Gerald Versluis, Maurits Kammer。
  • フィンランド語: Feetu Nyrhinen, Jussi Palo, Petri Niinimäki。
  • ギリシャ語: Nickolaos Platides, Theodore Tsirpanis, George M, Christos Koutsiaris。
  • インドネシア語: Wildan Mubarok, Laurensius Dede Suhardiman, Joseph Aditya P G, G-RiNe Project, Adiyat Mubarak。
  • ラトビア語: kozete。
  • ポーランド語: Patryk Brejdak, Iwona Kubowicz, Sebastian Baran, Lukasz Woznicki, Mateusz Przybyłowicz。
  • スウェーデン語: Eugen Cazacu。
  • ウクライナ語: Fedir Gordiienko, SergZ, Bogdan Surai。
  • ベトナム語: Vuong, Hung Nguyen, Thanh Phu, Brian Nguyen。
  • クロアチア語: Nikša Mihaica, Bruno Vego。
  • 英語 (イギリス): Matthew John Cheetham。
© . This site is unofficial and not affiliated with Microsoft.