Visual Studio 2022 をEmacsキーバインドで使う

# 概要

普段VSCodeにEmacsキーバインドの拡張機能を入れてコーディングを行っているのですが、VS2022を使う機会が増えてきたので、VSでも同じようなキーバインドを使いたいと思いいろいろ設定したので、メモとして残します。

# 拡張機能

なにはともあれ、Emacsキーバインドを使用できるようにする拡張機能を入れます。

## Marketplace の Emacs Emulation

まずVisual Studio Marketplace に公開されている [Emacs Emulation](https://marketplace.visualstudio.com/items?itemName=JustinClareburtMSFT.EmacsEmulation2)を入れたのですが、こちらではset-markで選択した範囲を一括で削除することができませんでした。

## Fork版 Emacs Emulation

いろいろ探してみたところ、以下の記事を見つけました。
[Visual StudioのEmacs Emulationで選択範囲を一気に消せるぞ！ - プログラムdeタマゴ](https://nodamushi.hatenablog.com/entry/2020/10/06/030830)
現在MarketplaceにアップされているソースをForkして、選択範囲削除をできるように変更されている方がいらっしゃるようです。（ありがたい）
記事に紹介されているリポジトリの[delete-selection-modeブランチ](https://github.com/TTimo/EmacsKeys/tree/delete-selection-mode)をビルドして、インストールするとうまく動作してくれました。
※ ちゃんと会話内容を追い切れていないようですが、この変更はmainブランチへとはマージされていないようです。（従来と挙動が変わるため設定などでユーザーが切り替えを行えるようにする必要があるというのが理由？）

# その他キー割り当て

その他、使用しているVSCodeのEmacs拡張機能（[Awesome Emacs Keymap](https://marketplace.visualstudio.com/items?itemName=tuttieee.emacs-mcx)）と自分のVSCodeの環境と似たような使い心地になるようにキー割り当てを行いました。
- `Ctrl + H`でBackspaceできるようにする
    - 「編集.後退削除」に`Ctrl + H`を割り当て
- `Ctrl + A`での移動先を行の先頭ではなく、インデントの先頭に変更する（デフォルトの行頭移動になるので、set-markが切れてしまう）
    - 「編集.Emacsの行頭に移動」のキー割り当てを削除
    - 「編集.行頭に移動」に`Ctrl + A`を割り当て
- ~~`Ctrl + P`/`Ctrl + N`でインテリセンスの補完や入力候補を上下選択できるようにする~~<br>⇒下移動(`Ctrl+N`)と行頭移動(`Ctrl+A`)を連続して入力すると、`Ctrl`を拾いきれず、'e'が入力されてしまうことが分かったので、設定を削除
    - 「編集.Emacsの1行上へ」/「編集.Emacsの1行下へ」を削除
    - 「編集.1行上へ」/「編集.1行下へ」に`Ctrl + P`/`Ctrl + N`を割り当て
- ~~`Ctrl + G`でEscape と同じ挙動にする（入力候補の取り消しがEmacs Emulationの拡張ではできなかった）~~<br>⇒`Ctrl + P`/`Ctrl + N`の連続入力問題と同様に削除
    - ~~[Microsoft PowerToys (MS Storeリンク)](https://apps.microsoft.com/store/detail/XP89DCGQ3K6VLD)をインストールし、 Keyboard Manager で Visual Sutdio (devenv)を使用中は`Ctrl + G`をEscに割り当て~~<br>⇒`CtrlL + G`に`ESC`と同じコマンドを割り当てることで、入力候補の非表示が可能だったので、それらを割り当て
        - 「ウィンドウ.ドキュメントウィンドウをアクティブにする」(全体)
        - 「編集.選択範囲の取り消し」(テキストエディター)
        - 「編集.選択範囲の取り消し」(マネージドリソースエディター)
        - 「編集.選択範囲の取り消し」(設定デザイナー)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2430330/f3c3ce14-41bf-be40-b473-dd86c753779b.png)

# 課題

現状の設定でコーディングすることに関してはかなりいいところまで来ているのですが、いくつか課題があります。

## Ctrlキーによる入力候補の半透明化

VSにはCtrlキーを押し続けると、インテリセンスの補完候補を半透明にしてくれるという機能があるのですが、これがCtrlを多用するEmacsキーバインド使いには候補の見え方が変わってしまい、見づらいです…。
よい拡張機能、設定などあれば知りたい…。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2430330/e6f97875-a347-533a-2ec9-a87c63bf9475.png)

公式のDeveloper Communityでも投稿がありましたが、まだまだ進展はないようです…。

https://developercommunity.visualstudio.com/t/cannot-disable-transparency-on-hold-ctrl/1466213

## `tab + tab`でスニペットを挿入できない

Visual Studioではスニペットを挿入するのに`tab + tab`を使用するのですが、どうもEmacs Emulationsがtabキーを何か上書きしているようで、スニペットの挿入をうまくできません。
スニペットの挿入自体はほかのコマンドが用意されているので、そちらを使えばよいですが、`tab + tab`のようにコーディングしながら流れるように使えないので、少し不便です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2430330/3c0704fc-160d-9937-8c44-487fc97d911e.png)

同様に`tab`で保管するGitHub Copilotもうまく動作させることができません…。

## XAMLファイルの空行でtabインデントを行うと例外が発生する

:::note info
修正プルリクエストがマージされ、問題が解決されたv6.1が公開されました！
:::

https://github.com/justcla/EmacsKeys/pull/5

XAMLファイルで以下の赤枠で囲ったような空白行でtabキーを押すと、例外が発生してVSごと落ちてしまいます。
これが地味にストレスで、手癖でtabキーを押してしまうとVSを再起動しなくてはいけません。
※ [こちら](https://qiita.com/nobushi95/questions/b8202be05555d0f85d22)でも質問にあげていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2430330/3dc3699d-4e47-391f-173a-cacfcbb44931.png)

### 解決策1（設定で回避）

設定などで回避できないかといろいろ試したところ、XAMLのインデントを"ブロック"に設定していると、この問題は起こらなさそうだったのですが、インデントが個人的にきれいにされないと感じたので断念しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2430330/75916fa3-e316-a76d-9ae9-c64b7b6c31e9.png)

### 解決策2（拡張機能を修正する）

~~拡張機能のソースをクローンして、落ちる部分を無理やり直しました。~~
以下のコミットを元にした修正プルリクエストがマージされました。

https://github.com/nobushi95/EmacsKeys/commit/09d5069dab572f2c95247d6b2de2c785ccae1dc7

# まとめ

VSでEmacsキーバインドを設定するのにいろいろとやったことをまとめてみました。
VSCodeは情報があふれているのですが、VSは情報を入手するのにかなり苦戦してしまいました。
ほかにもよい設定などあれば、いろいろな設定を試してみようと思います。