新品のWindows10にWSLを利用した快適な開発環境を整える [備忘録]

初投稿です。
新品のWindows10 PCを購入したので、WSLを利用した (個人的に) 快適な開発環境をセットアップするまでを備忘録がてら残しておきます。なお、ここで言う開発環境とは特定の言語の開発環境を指すのではなく、より全般的な設定などを指しています。
各ツールの詳細な使い方などについては記しませんので、気になったものをそれぞれ調べてみてください。

*2019/11/14追記:* 初稿 (2018/11) から一部の記述を更新しました。

**想定読者**

- Linux (Unix) の多少の経験がある開発者

## フォント

### MacType
[Releases - snowie2000/mactype](https://github.com/snowie2000/mactype/releases)

まず見た目からということでフォントのレンダリングを改善するソフトウェアですが、Windowsの更新などが不安定になるため可能なら入れたくないソフトウェアです。とはいえ、これに慣れてしまうとやっぱりMacTypeありの方が文字がキレイに感じてしまいます。
精細なディスプレイを使ってスケーリングを効かせれば、最近はMacType抜きでもだいぶ文字が見られるようになってきた気はします。**フォントのレンダリングに現状で不満を抱いていないなら入れない方が良いです。**

### Ricty Diminished
[プログラミング用フォント Ricty Diminished](http://www.yusa.lab.uec.ac.jp/~yusa/ricty_diminished.html)

プログラミング用のフォントにはRicty Diminishedを愛用しています。他のフォントに浮気していたこともありますが結局これに戻ってきてしまいます。フォントが配布されており、自分でビルドする必要がないのも楽で良いですね。[Powerlineに対応したもの](https://github.com/mzyy94/RictyDiminished-for-Powerline)もあります。

## ブラウザ

### Firefox
[Firefox](https://www.mozilla.org/ja/firefox/new/)

なぜChromeではなくFirefoxを使っているかというと、単に**MacTypeが効くから**です。現在の私の環境 (MacType v1.2018.10.19-beta4 / Firefox 63) では、`about:config` を開いて

- `gfx.content.azure.backends` を `direct2d1.1,cairo` (`skia`を抜く)
- `gfx.webrender.blob-images` を `false` *(2019/11/14追記, Firefox 70 で確認)*

に変更するだけでMacTypeを適用させることができています。

#### アドオン
- [Bitwarden](https://bitwarden.com/): オープンソースで無料のパスワードマネージャ
- [Nano Adblocker](https://github.com/LiCybora/NanoCoreFirefox/releases) & [Nano Defender](https://github.com/LiCybora/NanoDefenderFirefox/releases): 広告ブロック

## キーボード

### キーの入れ替え
[Windows Server 2003 Resource Kit Tools](https://www.microsoft.com/en-us/download/details.aspx?id=17657)

Resource Kitに含まれている「remapkey.exe」を管理者権限で起動することで、キーを簡単かつ安全に入れ替えることができます。CapsLockをCtrlに割り当てる定番の変更のみであれば、[Ctrl2cap](https://docs.microsoft.com/ja-jp/sysinternals/downloads/ctrl2cap)で十分かもしれません。

### 日本語入力
[Google 日本語入力](https://www.google.co.jp/ime/)

固有名詞などはやはりGoogle日本語入力の方が強いので、こちらをデフォルトにします。個人的には学習機能は要らないのでオフにしています。また無変換キーをIME無効化、変換キーをIME有効化に割り当てて、半角/全角キーを押さなくても済むようにしています。

## Windows Subsystem for Linux (WSL)
ここまで開発環境というよりはWindowsの全般的な設定について記述してしまいましたが、ここからが本題です。

以前まではWindows上の開発環境として[MSYS2](https://www.msys2.org/)を利用していたのですが、Windows Subsystem for Linux (WSL) が随分使えるようになってきたのでこちらに乗り換えました。

- プログラムと機能 → Windowsの機能の有効化または無効化 → Windows Subsystem for Linux のチェックを入れる

### Kali Linux
[Kali Linux を入手 - Microsoft Store](https://www.microsoft.com/ja-jp/p/kali-linux/9pkr34tncv07)

執筆時点でUbuntuやopenSUSE LeapなどのディストリビューションがWSLに対応していますが、その中で**[Kali Linux](https://www.kali.org/)**を選択してみました。私自身これまで聞いたことのなかったディストリビューションなのですが、選択した理由はひとえに**ローリングリリース**を採用しているためです。

ローリングリリースでないものは fixed release や point release と呼ばれますが、これらの多くのディストリビューションはバージョン番号で管理され、バージョンを上げる際には明示的に更新を行わなければなりません (e.g., Ubuntu の `do-release-upgrade`) 。ローリングリリースモデルではそうではなく、頻繁な小さい更新によって常に最新版を保とうとします。

例えばUbuntuはLTSしかWSLでサポートされないと仮定した場合、バージョン18.04の次は20.04まで待たなくてはならないことになります。パッケージマネージャから入れられるソフトウェアのバージョンが古く、結局ソースコードを落としてきて自前でビルドした、なんて経験も皆さんお有りではないでしょうか？　ローリングリリースが採用されているディストリビューションではパッケージも頻繁に更新されるため、そのようなことはほぼ無くなると言えます。Kali LinuxはDebianベースであるため、馴染みのあるaptが使えるのもポイントです。

ただ、Kali Linuxは本来ペネトレーションテストに特化した癖のあるディストリビューションであるため、サーバーを立てたいといった用途には適していません (そもそもWSLがサーバーを立てるのに向いていない気もしますが) 。また、マイナーなディストリビューションであるために情報量が少ない点も気になります。長いものに巻かれていた方が安心という方は、素直にUbuntuを利用した方がいろいろと無難かなと思います。

### パーミッションの設定
Windows上のファイルはWSLからは `/mnt/c/` などから見れますが、デフォルトではファイルのパーミッションが777に見えていて**実に気持ち悪い**です。そこで、`/etc/wsl.conf` を (sudoで) 作成して次のように設定することで、パーミッションが755で見えるようになり多少マシになります。

```:/etc/wsl.conf
[automount]
enable = true
root = /mnt/
options = "metadata,umask=22"
mountFsTab = false
```

とはいえ、これでもただのテキストファイルが644ではなく実行可能な755で見えたりするため気持ち悪さは残りますが、Windowsのファイルシステム上ではこれらを区別することができないため仕方のないところです。デフォルトで実行不能にしてしまう `fmask=111` を追加するのは攻めすぎで、後述するWSLttyが起動しなくなってしまいました。
(その点MSYS2などは面白い実装をしていて、テキストファイルなどは「シェバンがあるかどうか」で実行可能かどうかを判断していました)

また、なぜかデフォルトではディレクトリを新規作成した場合にパーミッションが777になっていたりするので、`umask 022` を `.bash_profile` などにでも追加しておきましょう。

## ターミナル・シェル
### 端末: WSLtty
[Releases - mintty/wsltty](https://github.com/mintty/wsltty/releases)

ターミナル・シェルについても外側から見ていくことにしましょう。まずはターミナルですが、現在はWSLttyを利用しています。以前は[Cmder](http://cmder.net/)を使っていたのですが、aptの進捗がちゃんと表示されなかったりでWSLttyに乗り換えました。

WSLttyの設定はあまりなく、大事なのはフォントをRictyにして、端末のタイプを `xterm-256color` に変更するくらいです。またショートカットキーなどは次のtmux側で設定を行うので、チェックは全て外してしまっています。

~~tmuxやvim上でもカーソルの点滅を行わせるには、[こちら](https://github.com/mintty/mintty/wiki/Tips#blinking-cursor-reset)を参考に以下の内容を設定ファイルに書き込みます。(設定ファイルはWindows側に置く点に注意)~~
*2019/11/14追記:* WSLtty 3.0.1 からこの設定は必要なくなりました。

```:%LOCALAPPDATA%\wsltty\home\%USERNAME%\.minttyrc
SuppressDEC=12
```

### 仮想端末: tmux
WSLttyにはタブ機能が無いため、仮想端末の[tmux](https://github.com/tmux/tmux)を利用することでタブ機能を実現します。aptからtmuxをインストールしたら、WSLttyのショートカットのリンク先の最後の `-~` を `/bin/tmux new -c~` に変更してデフォルトでtmuxを起動するようにします。

tmuxの設定は `~/.tmux.conf` 上で行います。個人的にはローカルのtmuxでは**タブ機能さえ実現できれば良い**ので、プレフィックスは完全に無効化してしまっています。

```sh:~/.tmux.conf
# terminal
set -g default-terminal "screen-256color"

# mouse
setw -g mouse on

# disable prefix
unbind C-b

# key bindings
bind -n C-t new-window -a   # Ctrl+Tで新規タブ
bind -n C-w kill-window     # Ctrl+Wでタブを閉じる
set -s user-keys[0] "\e[1;5I"
set -s user-keys[1] "\e[1;6I"
bind -n User0 next-window       # Ctrl+Tabで次のタブ
bind -n User1 previous-window   # Ctrl+Shift+Tabで前のタブ

# index
set -g base-index 1

# status line
set -g status-position top
set -g status-bg "colour240"
set -g status-fg "colour255"
set -g status-interval 1
set -g status-left ""
set -g status-right "[%Y-%m-%d %H:%M:%S]"
setw -g window-status-current-style bg=colour234,bright
```

#### コピー&ペースト
[Releases - equalsraf/win32yank](https://github.com/equalsraf/win32yank/releases)

[このへん](https://qiita.com/rattcv/items/da6730384111ad8fb70a)を参考に、win32yankを利用してWindows上のクリップボードを介したコピー&ペーストを行えるようにします。(win32yankには適当にパスを通します)

```sh:~/.tmux.conf
# copy and paste
setw -g mode-keys vi
# ドラッグでコピー
bind -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "win32yank.exe -i --crlf"
# Ctrl+Vでペースト
bind -n C-v run "win32yank.exe -o --lf | tmux load-buffer - && tmux paste-buffer"
```

#### スクロール
WSL上のテキストエディタにはnanoを利用しているのですが、デフォルトではマウスのスクロールがtmuxに奪われてしまいます。[このへん](https://github.com/tmux/tmux/issues/1320#issuecomment-381952082)を参考に、nano, manなどいくつかのプログラムではtmux側でスクロールを処理しないように設定します。

```sh:~/.tmux.conf
# scrolling support
tmux_commands_with_legacy_scroll="nano less more man"
bind-key -T root WheelUpPane \
  if-shell -Ft= '#{?mouse_any_flag,1,#{pane_in_mode}}' \
    'send -Mt=' \
    'if-shell -t= "#{?alternate_on,true,false} || echo \"#{tmux_commands_with_legacy_scroll}\" | grep -q \"#{pane_current_command}\"" \
      "send -t= Up Up Up" "copy-mode -et="'
bind-key -T root WheelDownPane \
  if-shell -Ft = '#{?pane_in_mode,1,#{mouse_any_flag}}' \
    'send -Mt=' \
    'if-shell -t= "#{?alternate_on,true,false} || echo \"#{tmux_commands_with_legacy_scroll}\" | grep -q \"#{pane_current_command}\"" \
      "send -t= Down Down Down" "send -Mt="'
```

### シェル: fish
シェルは長らく普通にBashを使っていたのですが、[fish](https://fishshell.com/)を使ってみたところ補完が強力で、コマンドも自動で色がつくなど便利だったためこれを機に乗り換えてみました。

aptからインストールを行ったら、`chsh -s /usr/bin/fish` でデフォルトのシェルをfishに変更してしまいます。またtmuxでもデフォルトシェルを変更するには、以下を `~/.tmux.conf` に書き込みます。

```sh:~/.tmux.conf
# default shell
set -g default-shell /usr/bin/fish
```

fishの設定ファイルは `~/.config/fish/config.fish` に書き込みます。デフォルトで既に良い感じなので、あまり設定は行いません。個人的にはプロンプトはシンプルなのが好きなので以下ではそのように変更していますが、このあたりはお好みでどうぞ。

```sh:~/.config/fish/config.fish
# greeting/prompt
set fish_greeting
function fish_prompt
  set_color brgreen
  printf '%s$ ' (prompt_pwd)
  set_color normal
end

# umask
umask 022
```

なお `function` の使い方を見ると分かるように、fishはBash/zsh等とはスクリプトの文法が異なります。このあたりはやや癖があると言えるかもしれませんが、慣れてくるとこちらの方が好ましく思えてきます (`esac`とか最悪じゃないですか?) 。

このため、例えば `export CC=clang` と書いていたところが `set -x CC clang` のように変わったりします。このあたりは[チュートリアル](https://fishshell.com/docs/current/tutorial.html)に一度目を通しておくと良いかと思います。

また、[Fisher](https://github.com/jorgebucaran/fisher)を導入することでfishにプラグインを入れられるようにもなります。気になる方はこちらについても調べてみてください。

## エディタ
### Visual Studio Code
開発に用いるエディタはそれぞれこだわりのあるところだと思いますが、私は現在 Visual Studio Code (VSCode) を利用しています。さすが後発なだけあって、Gitとの連携などをはじめとして機能が非常に充実している (そのわりに動作も重くない) のが素晴らしいと思います。表示言語は英語でも構わないといえば構わないのですが、日本語化するために拡張機能から「[Japanese Language Pack](https://marketplace.visualstudio.com/items?itemName=MS-CEINTL.vscode-language-pack-ja)」をまず導入しておきましょう。

VSCodeの統合ターミナルでWSLを起動するようにするには、設定に以下を追加します。

```js:settings.json
{
  "terminal.integrated.shell.windows": "C:/Windows/System32/wsl.exe",
  "terminal.integrated.shell.linux": "/usr/bin/fish",
  // カーソルを縦線で点滅させるようにする
  "terminal.integrated.cursorBlinking": true,
  "terminal.integrated.cursorStyle": "line",
}
```

~~VSCodeのためだけにGit for Windowsをインストールするのは個人的には避けたいので、[WSLGit](https://github.com/andy-5/wslgit/releases)を落としてきて次のように設定し、WSL上のGitを利用するようにします (`path/to/`の部分には実際のパスを設定してください) 。~~

```json:settings.json
{
  "git.path": "C:/path/to/wslgit.exe"
}
```

~~本当は開発環境のあるWSL側にVSCodeをインストールしたかったのですが、VcXsrvをインストールして日本語入力のためにfcitx-mozc入れて……、とかいろいろ設定が面倒だった上になんか動作が安定せず辛かったので (WindowsとWSLの両方でVSCodeを起動するとWindows側のフォントがおかしくなったりと挙動が謎) 、当面の間はWindows側でのみVSCodeを使っていこうと思います。~~

*2019/11/14追記:* [Remote - WSL](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl) の登場でこのあたりの問題は現在はすべて解決しています。

### Mery
[Haijin Boys Online - Mery](https://www.haijin-boys.com/software/mery)

VSCodeを起動するほどではない軽い用途のエディタとしては少し前まで[Sublime Text](https://www.sublimetext.com/)を使用していたのですが、

- ちょくちょく購入を促してきて鬱陶しいがライセンスを買うほどではない
- スケーリング環境では日本語のインライン入力がちゃんと行えない (IMESupportプラグイン使用)

といった不満点が気になるようになり、国産エディタのMeryに乗り換えてみました。サクラエディタやNotepad++は設定画面が煩雑なわりに痒いところに手が届かなかったりであまり気に入らなかったのですが、Meryは今のところ快適に使えています。デフォルトでMonokaiなどのテーマが入っていて、日本語のインライン入力にも完全に対応しているのが良いですね。

## その他便利ソフト
この項では、開発とは直接関係ないものの作業を効率化できるソフトをいくつか紹介します。

### QTTabBar
[QuizoApps - QTTabBar](http://qttabbar-ja.wikidot.com/)

Windowsのエクスプローラをタブ化するソフトウェアです。むしろなぜデフォルトでエクスプローラがタブ化できないのかという話です。「Sets」なる機能がWindows10に入るという話もあるので、いずれ不要になるかもしれません。

### Everything
[窓の杜 - Everything](https://forest.watch.impress.co.jp/library/software/everything/)

ファイルの検索が爆速で行えるようになるソフトウェアです。個人的に常駐させるのは嫌なので、その点は設定で変更しています。

### Rapid Environment Editor
[Rapid Environment Editor](https://www.rapidee.com/ja/about)

Windowsの環境変数を簡単に編集できるようにするソフトウェアです。狭い設定画面でセミコロンで区切りながら入力するのはおさらばです。

### Lhaz
[ちとらソフト - Lhaz](https://chitora.com/lhaz.html)

圧縮ファイルの展開を行うソフトウェアです。ダブルクリックでファイルのあるディレクトリに一発で展開を行うように設定しています。例によって4GBを超えるファイルを展開すると尻切れになってしまうようなので、巨大なファイルの展開はtarコマンドなどを利用した方が確実かと思います。