苦労して構築する Windows10 + WSL2 + Visor ターミナル環境

# はじめに

Windows のターミナル環境は選択肢が多くて、業務だと TeraTerm や PuTTY あたりがよく使われていると思うけれど、他にも多数（ Rlogin, Poderosa, Hyper, mRemoteNG, etc... ）のターミナルエミュレータが存在するし、最近は Microsoft 純正の Windows Terminal というのも出ているよね。

個人用途ではターミナルは PuTTY を使い続けてきて、最近は Mac の iTerm2 の使用感に近付けている。

* ホットキーでターミナルを Visor 表示できる。
* ターミナルを立ち上げると WSL2 環境のシェル ( zsh ) が立ち上がる。
* ウィンドウは透過させて、タブもある。

みたいな感じ。

# Visor とは

Visorと言っているのは、こういう挙動のこと。
![visor-sample](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/7ae948e2-8b7b-be65-518c-e627f39a7da1.gif)
最近は「Quake-style」と呼ぶみたい。

ホットキーを押下するとターミナルの表示/非表示を切り替えられる。これが、頻繁にターミナルと他のアプリケーションを行き来する時（Webで調べながらCUI作業するとか）なんかには、めちゃ便利なわけ。

# 準備するもの

- Windows 10 Pro 64bit
- Ubuntu on WSL2
- ConEmu
- PuTTY
- AutoHotkey

**Visor するだけなら ConEmu だけでいい。**

これに加え、ぼくの場合は

- cmd.exe や PowerShell ではなく WSL2 のシェルを立ち上げるために **WSL2** と **Ubuntu**。
- さらに、普段の使用感（フォントとか）で操作するために **PuTTY**。
- さらに、ConEmu が起動していない時でもホットキーで ConEmu を呼び出すために **AutoHotkey**。

を組み合わせて使っている。

## ConEmu

- [ConEmu](https://conemu.github.io/en/)  
( 想定のインストール先：C:\App\ConEmu\ConEmu64.exe )

タブ付きターミナルエミュレータ。`Quake style` として、Visor の機能が搭載されている。
ターミナルエミュレータの中では自由度が高く、かなり細かくカスタマイズができる。

ここまで読んで ConEmu だけでいいや！って人は [Cmder](https://cmder.net/) の方がオススメかも。

## WSL2 + Ubuntu

- [Google: WSL2 インストール](https://www.google.com/search?q=WSL2%20インストール)

WSL2 環境を有効に出来たら Microsoft Store で Ubuntu をインストールする。

## PuTTY

- PuTTY => [iceiv+putty](https://ice.hotmint.com/putty/)  
( 想定のインストール先：C:\App\PuTTY\putty.exe )

昔から好きで使っているのだけれど、不満はある。

- UTF-8 の Emoji がまともに表示できない。
- 端末タイプとキー割り当ての対応がおかしい？

PuTTY で SSH 設定の端末タイプを `xterm-256color` にして `ssh -> zsh -> ( tmux -> ) neovim` とした環境だと Home, End が期待通りに動作しなくて、`screen-256color` にすると期待通りに動作する。
（環境が複雑すぎて原因の切り分けができない…）

という挙動があって、PuTTY 自身はターミナルマルチプレクサでも無いのに今は `screen-256color` を指定して使っている。この状態には違和感があるし、なにより対応する zsh 側の設定が気持ち悪くなる。

この件については今回は無視する。

## AutoHotkey

* [AutoHotkey](https://www.autohotkey.com/) => [ぼくがダウンロードしたのはこれ](https://www.autohotkey.com/download/ahk.zip)  
( 想定のインストール先：C:\App\AutoHotkey\AutoHotkeyU64.exe )

> Powerful. Easy to learn.
> The ultimate automation scripting language for Windows.

こいつがあればキーボードだけで生きていける。

# 各種設定

さあ、ここからが本番だ。

## PuTTY

iceiv 版の PuTTY をダウンロードしたなら、`ja-JP` の中の `*.lng` ファイルを `putty.exe` と同じフォルダにコピーすると日本語になるよ。  
以降の画像は日本語化前の英語表記のものです。

0. `puttygen.exe` を実行。
0. Ubuntu には公開鍵認証方式でSSHログインしたいので、鍵を生成するよ。  
    今回はちょっと意識高く `ECDSA` `521bit` を選んで、「Generate」をクリック。  
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/c8b5e5f2-2475-98c3-2283-02dd85c3dc85.png" width="50%">
0. カーソルをグルグル動かすと生成が進む。  
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/ff1a1bfc-9ce3-8ceb-cff4-fbaad2653809.png" width="50%">
0. 公開鍵を生成する。  
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/f47d85b6-34ad-a816-9e07-21d7e7c2fa14.png" width="50%">
0. ファイル名は「id_ecdsa.pub」とでもしておく。  
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/5931bdcd-671c-69af-fd47-ae0148ea0cc8.png" width="80%">
0. 秘密鍵を生成する。  
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/3a7994b4-0766-4d53-6e36-fc80b1e1140c.png" width="50%">
0. 警告が出るが、「はい」でOK。今回は「パスフレーズ無し」で鍵を作る。  
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/7ccf8968-ac88-1600-84d9-6868f4e01c73.png" width="30%">
0. ファイル名は「id_ecdsa.ppk」とでもしておく。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/6ad46a91-b90c-8718-360f-889e59c3619a.png" width="80%">
0. ウィンドウ右上の「☓」をクリックして閉じる。

次！

0. `putty.exe` を実行。
0. `Connection > SSH > Auth` を開いて、秘密鍵として先ほど生成した `id_ecdsa.ppk` を指定する。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/6c914bb6-432b-c28e-9c35-78c439c31b3e.png" width="50%">
0. `Connection > Data`ユーザ名に Ubuntu をインストールした時に指定したユーザ名を入れる。
    ぼくの場合は諸事情で端末タイプを「screen-256color」というものに変更しているけれど、詳しくはググってくれ！
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/71d7f7a3-9ccf-19b5-3297-ac544a855850.png" width="50%">
0. `Session` で、接続先を `127.0.0.1`、設定名を `wsl` で、保存する。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/ff350372-f21c-4f14-d97b-4cd7023b40b1.png" width="50%">
0. ウィンドウ右上の「☓」をクリックして閉じる。

次！

## ConEmu

**ホットキーは「左Win + 半角/全角」にするよ**

0. `ConEmu64.exe` を実行。

0. 「OK」をクリック。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/41d6004a-120d-140d-4611-0fd3026c64cd.png" width="50%">
0. こんなウィンドウが表示されたら、「Win + Alt + P」で設定画面を出す。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/7406b63c-d922-51b8-30f0-640f46394dc8.png" width="50%">
0. `Startup > Tasks` と進んで、PuTTY用の設定を追加する。（並び順は何でもOK）
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/ed088775-0059-a56c-37f0-7f98fb28aefa.png" width="80%">
0. `Features > Transparency` と進んで、ウィンドウ透過を有効にする。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/aaf9d61e-2ad3-f252-5e47-94f775a7299b.png" width="80%">
0. あとは関係ありそうな設定画面をそのまま貼っていく。（適宜自分好みに変えてください。）
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/0beeaabd-57fd-a502-bb82-759ad5a55de6.png" width="80%">
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/dd5c261e-1ce9-6419-3ff3-97d4bc18fbdf.png" width="80%">
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/3fd0625e-6791-26d9-6e7f-26f3d1cf8ade.png" width="80%">
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/e7b1b1a3-43da-2962-903d-1858c7c29ff6.png" width="80%">
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/b8eec017-3a32-3ddb-95e0-57336733114f.png" width="80%">

0. 「Save settings」をクリックして閉じる。

0. ウィンドウ右上の「☓」をクリックして、一度 ConEmu を終了させる。

0. `C:\App\ConEmu\ConEmu.xml` が生成されているので、サクラエディタか何かで開く。
    
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/5d47c5cb-8e8d-716c-9116-5797c94879d7.png" width="80%">
    45行目辺りにある、    
      - `MinimizeRestore` の値を `00005bf4`
      - `MinimizeRestore2` の値を `00005bf3`
    
    に、それぞれ書き換えて保存する。

次！

## WSL2 + Ubuntu (前半)

0. WSL2 でインストールした Ubuntu を起動する。  
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/3a0dac47-0b78-5936-7c1d-bb5d41d9497f.png" width="50%">

0. 管理者権限に昇格して SSHサーバ（`openssh-server` パッケージ）をインストールする。

    ```
    $ sudo su -
    # apt update && apt install openssh-server
    ```

0. 作業ユーザで sudo する際のパスワード確認を省略するように設定する。

    ```
    # EDITOR=vim visudo
    
    .. (以下を変更。「%sudo」の行に「NOPASSWD: 」を追記して保存する。)
    %sudo>--ALL=(ALL:ALL) ALL
    ↓
    %sudo>--ALL=(ALL:ALL) NOPASSWD: ALL
    ```

0. SSHサーバで公開鍵認証を有効にする。

    ```
    # cd /etc/ssh/
    # ssh-keygen -A
    # vim sshd_config
    
    .. (以下を変更。2箇所のコメントアウトを外して保存する。)
    #PubkeyAuthentication yes
    ↓
    PubkeyAuthentication yes
    ..
    #AuthorizedKeysFile     .ssh/authorized_keys .ssh/authorized_keys2
    ↓
    AuthorizedKeysFile     .ssh/authorized_keys .ssh/authorized_keys2
    ```

0. 設定反映のため、SSHサーバを再起動して、管理者権限を抜ける。

    ```
    # service ssh restart
    # exit
    ```

0. ユーザ権限に戻ったら、PuTTY から公開鍵認証でログインできるようにする。
    前準備として `puttygen.exe` を起動して、`File > Load private key` から先ほど生成した秘密鍵（`id_ecdsa.ppk`）を開いて、画像の赤い囲い部分のテキスト（公開鍵）をコピーする（改行されて見えるけれど、コピーすると1行だよ！）。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/28277023-8b8f-817e-edc4-e08cfcf49688.png" width="50%">
    公開鍵をコピーしたらコマンド入力に戻って、公開鍵をサーバ上に登録する。
    
    ```
    $ cd
    $ mkdir .ssh/
    $ chmod 700 .ssh/
    $ touch .ssh/authorized_keys
    $ chmod 600 .ssh/authorized_keys
    $ vim .ssh/authorized_keys
    .. (コピーしためちゃ長い公開鍵1行分を追記して保存する。)
    ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1M...== ecdsa-key-20200912

    ```

0. 一旦サーバから抜ける。

    ```
    $ exit
    ```

サーバ上の作業終わり！
次！

## WSL2 + Ubuntu (後半)

ここまでの設定では WSL の仕様で Windows を再起動しても sshd が自動で立ち上がらない。
なので、以下の手順で Windows 起動時に Ubuntu の sshd を起動するように設定する。

0. 以下の内容で `C:\App\startup_for_wsl.ps1` を作成。

    ```powershell:startup_for_wsl.ps1
    $wsl_is_available = $FALSE
    
    while( ! $wsl_is_available )
    {
        ubuntu.exe run sudo service ssh restart
        $wsl_is_available = $?
        if( $wsl_is_available ) {
            break
        }
        else {
            Start-Sleep -Seconds 5
        }
    }
    ```

    `ubuntu.exe` に関しては Microsoft Store で  
    - Ubuntu をインストールした人は `ubuntu.exe` のまま。
    - Ubuntu 18.04 をインストールした人は `ubuntu1804.exe` 。
    - Ubuntu 20.04 をインストールした人は `ubuntu2004.exe` 。
    
    に適宜読み替えてください。
    
0. Winキー + Rキー でファイル名を指定して実行で「shell:startup」を開く。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/f6207138-4ce9-9690-1c65-ef345f20084f.png)

0. 何もないところを右クリック -> 新規作成 -> ショートカット、「項目の場所」として  

    ```
    %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy RemoteSigned -File C:\App\startup_for_wsl.ps1
    ```

    を指定して「次へ」、適当に名前を付けて「完了」。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/fd996de7-b770-c38b-9344-c200cbfababa.png)

**※ 改めて調べていたら WSL2 からはこんなことしなくても、systemd を PID 1 で動かすハックが存在するみたい**

## AutoHotkey

ホットキーは「左Win + 半角/全角」とする。
AutoHotkey上では

- `LWin` が「左Windowsキー」
- `vkf4` が「半角/全角キー」

を意味する。
 
0. 以下の内容で `C:\App\AutoHotkey\MyHotkey.ahk` を新規作成。
    
    ```:MyHotkey.ahk
    #WinActivateForce
    #HotkeyInterval 2000
    #HotkeyModifierTimeout 100
    #MaxHotkeysPerInterval 100
    #InstallKeybdHook
    #UseHook
    
    ; ConEmu
    LWin & vkf4::
    Process, Exist, ConEmu64.exe
    if ErrorLevel <> 0
    {
        IfWinActive, ahk_class VirtualConsoleClass
        {
            Send, #{vkf4}
        }
        else
        {
            IfWinExist, ahk_class VirtualConsoleClass
            {
                WinActivate, ahk_class VirtualConsoleClass
            }
            else
            {
                Send, #{vkf4}
                WinActivate, ahk_exe ConEmu64.exe
            }
        }
    }
    else
    {
        run, C:\App\ConEmu\ConEmu64.exe, C:\App\ConEmu
    }
    return
    
    ```

0. AutoHotkey 自体にスタートアップで起動する機能は無いので、タスクスケジューラで設定する。
    スタートメニューから「タスクスケジューラ」を起動する。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/dbda0baa-2e9f-b897-7e40-23fc26e72702.png" width="50%">
0. 左ペインの「タスクスケジューラ ライブラリ」を右クリックして「新しいフォルダー(N)」で
    「App」とか適当に作成して、右ペインの「タスクの作成」をクリック。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/b8e8e795-067f-c0eb-b2ce-64754b471f67.png" width="70%">
0. 名前に「AutoHotkey」、お好みで「最上位の特権で実行する」にチェック。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/5a5050e7-994a-17ea-5728-a8514aabdb4b.png" width="60%">
0. トリガータブに移って、「新規」をクリック。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/463a6410-0b4d-12ac-40a5-45df9fc244a7.png" width="60%">
0. 上部のプルダウンを「ログイン時」に変更して、「OK」をクリック。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/da7b0a96-a4c7-b85c-faf8-09b7b69274b1.png" width="60%">
0. 操作タブに移って、「新規」をクリック。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/b2c27249-25e2-ef1a-ba1b-b1150911c132.png" width="60%">
0. それぞれ以下のように入力して、「OK」 をクリック。  
    - プログラム/スクリプト(P)：`C:\App\AutoHotkey\AutoHotkeyU64.exe`
    - 引数の追加 オプション(A)：`C:\App\AutoHotkey\MyHotkey.ahk`
    - 開始 (オプション)(T)： `C:\App\AutoHotkey`
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/a9672029-4a37-5c84-465e-7dc05add81de.png" width="60%">
0. 条件タブに移って、「AC電源で使用している場合のみ」のチェックを外す。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/ae931457-3bf4-c095-879c-b896fb09a9b0.png" width="60%">
0. 設定タブに移って、「タスクを停止するまでの時間」のチェックを外して、OKをクリック。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/5db8a337-0d8e-7e47-e90a-75b2838e3bd7.png" width="60%">
0. あとちょっとだ！
    AutoHotkeyのタスクが保存されていることを確認して、右ペインの「実行」をクリック！
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87322/2c40486b-f64a-d5c0-9851-6604fe80ac4e.png" width="60%">

# 動作確認

長かった！
ここまで正しく設定されていれば、「左Winキー + 半角/全角キー」をホットキーとして ConEmu のターミナルが現れたり消えたりするはずだ！
しかも、PuTTY を通じて WSL2環境の Ubuntu のシェルが表示されているはずだ！
それに、Windows を再起動しても何もしなくてもホットキーは動作するはずだ！
ヤッター！

# さいごに

スクリーンショットに写っている秘密鍵/公開鍵に関しては、破棄しており実際には使用していないのでご心配なく。