WSL2を使ってみている

個人ではUbuntu Desktopを使っていたのだが、Windows 10 May 2020 Updateがきたので試してみている。Windows Terminalと相まって使い勝手よく試せている。

WSLについて

WSL1と2の違いや仕組みを把握するには以下を参照するとよさそう。

WSLのアーキテクチャ - roy-n-roy メモ

ターミナルアプリケーション

WSL2にふれるのに便利なターミナルアプリケーションがほしかったので、先日正式版になった Windows Terminal を使っている。 Powershell, cmd.exe, WSLとタブを切り替えながら作業できるのがよい。現在の設定は以下。

// To view the default settings, hold "alt" while clicking on the "Settings" button.
// For documentation on these settings, see: https://aka.ms/terminal-documentation

{
  "$schema": "https://aka.ms/terminal-profiles-schema",

  // 自分が使いたいprofileのguidを指定する
  "defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
  "initialCols": 120,
  "initialRows": 50,

  "profiles": {
    "defaults": {
      // Put settings here that you want to apply to all profiles
      "colorScheme": "Dracula",
      "cursorShape": "filledBox",
      "fontFace": "Ricty Diminished",
      "fontSize": 14,
      "hidden": false
    },
    "list": [
      {
        // Make changes here to the powershell.exe profile
        "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
        "name": "Windows PowerShell",
        "commandline": "powershell.exe"
      },
      {
        // Make changes here to the cmd.exe profile
        "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
        "name": "cmd",
        "commandline": "cmd.exe"
      },
      {
        // Make changes here to the wsl.exe profile
        "guid": "{07b52e3e-de2c-5db4-bd2d-ba144ed6c273}",
        "name": "Ubuntu-20.04",
        "source": "Windows.Terminal.Wsl",
        // 起動時にHOMEディレクトリで開くようにする
        "commandline": "wsl.exe ~"
      },
      {
        // Make changes here to the azure profile
        "guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}",
        "name": "Azure Cloud Shell",
        "source": "Windows.Terminal.Azure"
      }
    ]
  },

  // Add custom color schemes to this array
  "schemes": [
    {
      "name": "Dracula",
      "background": "#282A36",
      "black": "#21222C",
      "blue": "#BD93F9",
      "brightBlack": "#6272A4",
      "brightBlue": "#D6ACFF",
      "brightCyan": "#A4FFFF",
      "brightGreen": "#69FF94",
      "brightPurple": "#FF92DF",
      "brightRed": "#FF6E6E",
      "brightWhite": "#FFFFFF",
      "brightYellow": "#FFFFA5",
      "cyan": "#8BE9FD",
      "foreground": "#F8F8F2",
      "green": "#50FA7B",
      "purple": "#FF79C6",
      "red": "#FF5555",
      "white": "#F8F8F2",
      "yellow": "#F1FA8C"
    }
  ],

  // Add any keybinding overrides to this array.
  // To unbind a default keybinding, set the command to "unbound"
  "keybindings": [
    { "command": "copy", "keys": ["ctrl+shift+c"] },
    { "command": "paste", "keys": ["ctrl+shift+v"] }
  ]
}

以下のように日本語の扱いなどでまだ難ありなところはあるが、一旦許容して使っている。 この辺もクリアになるということなしかなー。

  • IMEでインライン補完が効かない

  • 少し古いVimを使っていたら記号や濁点付き文字の表示がおかしくなったりした

  • tmuxの描画が乱れるように感じる

  • tigで縦線が表示されない

WSL2のインストール

まず WSL 2 Linux カーネルの更新 を実施。 次に Windows Subsystem for Linux (WSL) を Windows 10 にインストールする に従って、Microsoft StoreからUbuntu 20.04 LTSをインストールした。 その後普段使うPythonやVim, Git関連のツールをインストール。

$ sudo apt update -y && sudo apt upgrade -y
$ sudo apt install python3-venv python3-dev nodejs npm zip unzip vim-gtk golang xsel hub tig
$ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python3 get-pip.py --user
$ go get github.com/x-motemen/ghq

あとは dotfiles を落として来て、展開すれば準備OK。

クリップボードどうする

VirtualBoxのようなVMを使っているときも悩みのタネだったが、今回はtmuxでclip.exeを使うようにした。 普段からターミナルでのコピペはキーボードで完結させていたので、同じようにしたかった。

調べると equalsraf/win32yank が良いという記事があったが、 自分の環境では動かなかったのでOS標準で入ってるのを使うことにしました。 clip.exeはコマンドプロンプトでもPowershellでも使えるので、考えることを減らせていいと思った。 以下のようにファイルを用意してWSL環境のときだけ読み込むように設定。

# ~/.tmux.conf
if-shell 'test "$(uname -a | grep Linux | grep microsoft)" != ""' "source-file ~/.tmux.conf.wsl" ""
# ~/.tmux.conf.wsl
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe "cat | clip.exe"
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'cat | clip.exe'
bind-key -T copy-mode-vi Y send-keys -X copy-pipe 'cat | clip.exe'

ただこれだとVimでヤンクしたときにクリップボード連携ができていないのでvimrcに以下の設定を追加する。 +clipboard なVimである必要があるので、 sudo apt install vim-gtk などして有効にしておくこと。

" ~/.vimrc
if system('uname -a | grep microsoft') != ''
  augroup myYank
    autocmd!
    autocmd TextYankPost * :call system('clip.exe', @")
  augroup END
endif

Docker, docker-composeはどうか

以下の公式ドキュメントを参照しインストール。

sudoなしでdockerコマンドが使えるように以下も設定。

# 現行ユーザをdockerグループに所属させる
sudo gpasswd -a $USER docker

# dockerデーモンを再起動する
sudo service docker restart

# exit後、再ログインして反映
exit

hello-worldは普通にできて、 Docker Desktop WSL 2 backend も問題なく動いたので正直驚いた。しかし WSL2によるホストのメモリ枯渇を防ぐための暫定対処 - Qiita のようにリソース管理から解放されたわけでないので、WSL2のメモリ上限は最低限設定しておいたほうがいいだろう。

Docker Desktop WSL backendは Docker Desktop for Windows をインストールして、WSL2のセットアップが完了してれば使える。

「DockerとWSL 2を使用して最高の開発エクスペリエンスを実現するには、デフォルトのLinuxディストリビューションにコードを含めることをお勧めします。」と公式ドキュメントにあったが、これに沿わない使い方をする場合、WSL2を選択すべきでないのだろう。

エディタやIDE

Vimが使えるので問題ない….のだが、一応かんたんに実行できるかは調べた。

PyCharm

PyCharm 2019.3 時点でWSL2をサポートしている。(Proのみ)

WSLを使用してインタープリターを構成する - 公式ヘルプ | PyCharm にセットアップのしかたが書いてある。

リンク先にもはWSL内でPythonの仮想環境が作成できない問題があるようだが、WSL2内で手動で作成した仮想環境は指定できた。 使うときはWSL2上で環境を作ってからPyCharmにパスを教えてあげればよく、インストールしたPythonパッケージもPyCharmで識別できていたので問題なさそうだ。

Dockerを使用してインタープリターを構成する にあるように、 Expose deamon on ... を有効にした状態でDocker Desktop WSL2 backendを使用したインタープリターの指定もできた。

まだまだデバッガーの指定をしたり、PyCharmで起動したターミナルの指定をWSL2にしたりなど試せることはあるが実行できるなというところだけ確認してここでは終わりにした。こうゆう凝ったことをしようとするとうまく行かないイメージがあったが、意外とあっさり動いてしまった印象。

VSCode

Remote Development拡張を入れるとWSLをインタープリターとして指定できる。ただもりもり開発してるとやはりリソースを喰う傾向にあるようだ。

雑感

凝った使い方をしてないので万人におすすめできるかはわからないが、ひとまずは好印象。Ubuntu DesktopだとAdobe, Kindleが使えないのと、Bluetoothやオーディオ周りで手こずることがあったが、Windowsではそのあたりを気にしなくていいというメリットも得ている。

WSL2に関連するところで感じたのは以下。いいところも気になるところもありつつ、しばらくは付き合ってみようかなと思ってる。

よかった点

  • アプリを立ち上げる感覚でLinux環境が立ち上がるのがよい

  • WSL2内部で限っていえばI/Oが高速

  • Docker for WindowsがWSL2を指定できるので高速

  • 壊れたときの復旧が楽になるように、スナップショットが取れ、別名でテンプレートイメージとしてimportできる

  • bash.exe や git.exe, vim.exe が 3~5 つインストールされなくなったのが良い。(どれ使ってるんだっけ問題)

気になるところ

  • WindowsとWSLで環境の差異は意識する必要がある。

  • WSL2によるホストのメモリ枯渇を防ぐための暫定対処 - Qiita のようにリソース管理から解放されるわけではない。

  • たまにWSL2が落ちてるときがある

  • VirtualBox の使用時に Hyper-V が有効だと不安定

  • WSL2 から Windows 領域のファイルを扱おうとすると WSL1 より重い

  • IPアドレスが起動ごとに変わるので、外部からスクリプトを使って処理するような処理がしにくい

Ubuntu18.04LTSから20.04LTSにアップグレードした

Ubuntu Desktopがアップデートの影響か音が鳴らなくなり、Windowsに切り替えていましたが、GWでUbuntu 20.04LTSにアップグレードしたのでメモ。

Ubuntu20.04LTSとは

2年に一度リリースされる長期サポート版です。サポート期間が5年間提供されます。 それまで使っていたUbuntu18.04LTSのあと、18.10, 19.04, 19.10を一気に飛ばしてのアップグレードでした。 ちょっとドキドキしながらでしたが無事アップグレードできました。

イントール時間

インターネットの回線速度が200Mbpsとかでている朝に実施したので、1時間足らずで完了しました。

アップグレード後実施したこと

ibus-mozcのキーボードが英字配列で認識されていたので、設定ファイルを編集

毎回調べてる 参考URL を見ているので改めてメモ。

  • sudo vim /usr/share/ibus/component/mozc.xml

  • <layout>default</layout><layout>jp</layout> に置換

  • 変更を保存したらログアウトして再ログイン

  • キーボードレイアウトを確認して日本語配列になっていればOK

必要なパッケージのインストール

デフォルトのPythonのバージョンが上がっていたり、nodejsまわりが消えていたので再インストールしました。

  • sudo apt install python3-venv python3-pip nodejs npm

  • deadsnakes から sudo apt install python3.7 python3.7-venv

Ubuntuでどうやってシステム側にpipをいれるかは毎回悩ましいのですが、今回はaptで入れました。

vimの再インストール

自前でビルドしているため、依存関係が変わったあとは再インストールが必要でした。今回はPython3の場所を指定するだけでOKでした。 vimのリポジトリーはgit clone済みなので、 vim/src ディレクトリーに移動して以下のコマンドを実行します。

$ make distclean
$ ./configure \
    --with-features=huge \
    --enable-gui=auto \
    --enable-python3interp \
    --with-python3-config-dir=/usr/lib/python3.8/config-3.8-x86_64-linux-gnu/ \
    --enable-fail-if-missing
$ make
$ sudo make install

ビルド方法については vim-jp » Linuxでのビルド方法 も参考にしてください。

xselの再インストール

ここまでで一応必要なパッケージは揃っていたのですが、以下の現象が再発しました。

Ubuntu18.04LTSのときにインストール済みだったのですが、下記手順でインストールし直したところ改善されました。

$ sudo apt remove xsel
$ sudo apt install xsel

最後に

アップデート自体はすんなり行えました。ひとまずまたUbuntuの民に戻ろうと思います。

ただUbuntu18.04LTS時代はオーディオ関連に悩まされていたので、使っていってどうなるかは気になっています。 有線でイヤホンを使っているときは問題なかったですが、AirPods Proとは接続がなかなかできなくてペアリングし直したりしてました。 さすがにmacOSほど親和性はないと思うので、うまく付き合っていけたらいいなー。

LSPクライアントをcoc.nvimにした話

以前 Pythonの補完環境をjedi-vimからvim-lspに移行した話 — kashew_nuts-blog という記事を書きましたが、現在は neoclide/coc.nvim に完全移行しています。

coc.nvimとは

いろんな記事で説明されてますが、Vim8/Neovim向けのインテリセンスエンジンでLSPのフルサポートを謳ったプラグインです。

移行理由

移行しようと思った理由は以下の3つです。「これなんてVSCode?」となったとかならなかったとか。

  • 自動補完が「ちょうどいい」感じで補完してくれる

  • 拡張が豊富で、LSPに限らずIDEとしての機能を提供してくれる

  • Language Serverの設定でvimrcが膨れない

1. 自動補完が「ちょうどいい」感じで補完してくれる

vim-lspではオムニ補完、 prabirshrestha/asyncomplete.vim も使うと自動補完が使えるようになります。個人的には自動補完はほしい補完ソースを、「期待したタイミングで」動かすのが面倒でした。 LSP導入以前にも自動補完プラグインを使うのに、「連携のための設定」を書くのに苦労していました。

vim-lspを使ってるときはオムニ補完で自分で補完のタイミングをコントロールして書けてよかったのですが、coc.nvimは「これでいいのでは?」というくらい楽に動いたので一気に虜になりました。

2. 拡張が豊富で、LSPに限らずIDEとしての機能を提供してくれる

昨今LSPで各言語ごとに開発環境をインストールするのが楽になってきましたが、インストール自体は手動で行う必要がありました。 よく知らない言語を触るときにLanguage Serverのセットアップで時間を使うのは大変です。

最近では mattn/vim-lsp-settings がでてきたので事情が変わってきましたが、 coc.nvimはcoc.nvim自体がLanguage Serverを含む拡張をインストールできます。 Gitやエクスプローラーなどの拡張もあるので他のVimプラグインを探す時間も省けます。

3. Language Serverの設定でvimrcが膨れない

LSPを活用するにはクライアント側の設定だけでなく、Language Serverの設定も書いたりします。 vimrcにその両方を書いていくとどうしてもvimrcが肥大化していきますが、coc.nvimはLanguage Serverの設定をJSONファイルに書けます。 キーマッピングやcoc.nvimで使う拡張などはvimrcに書く必要がありますが、設定を分離できるのでvimrcが肥大化しにくいです。

インストール要件

現在のインストール要件は以下となっています。

  • Vim >= 8.0.1453

  • node.js >= 8.10.0

  • npm

当初2019年に試したときはVimの場合Python3インターフェイスや neoclide/vim-node-rpc 、yarnに依存していましたが、現在は依存が消えているので使いやすくなりました。(ソースからビルドするときはyarnが必要となります。

Vimの下限のバージョンはUbuntu 18.04LTSとかならデフォルトで満たしていますが、できればpopup-windowを活用するのに、8.2以上だとよりよいでしょう。 node.jsも現在のLTSの下限である10.x系にしたほうがよいと思います。

詳細は Install coc.nvim を参照のこと。

インストール方法

vim-plugを使ってる場合、 vimrcに以下のように記述します。 その後、Vimを再起動しコマンドラインモードで :PlugInstall すればOKです。

Plug 'neoclide/coc.nvim', {'branch': 'release'}

Quick Start の通りですね。

使い方

coc.nvimをインストールしたあとは拡張やLanguage Serverをインストールして使うだけ。 どんな設定ができるかや、Language Serverの設定をすればいいかは以下のWikiやヘルプを参照するとよいです。

まずは自分の使うFileTypeの拡張を入れたり、設定ファイルの記述を便利にするために :CocInstall coc-json はしておくとよいでしょう。

よく使うコマンド

個人的によく使うコマンドは以下です。

  • CocInstall <extension-name>: 拡張のインストール

  • CocUninstall <extension-name>: 拡張のアンインストール

  • CocCommand: インストールした拡張機能の実行

  • CocConfig: Language Serverの設定

  • CocLocalConfig: プロジェクトごとのLanguage Serverの設定

気になるところ

良い点もあれば気になるところもあるということでかんたんに書きます。

  • 設定ファイルがJSONのため、PATHの設定を書くと異なるOS間で共通化しにくい

  • NeoVimでのみサポートとかあるので、coc及び拡張の機能が自分の「Vim」に対応しているか確認する必要がある

  • トラブルシューティングにはJavaScript/TypeScriptまわりの知識が必要になる

現状なにか詰まったりしたときに「そういえばそうだったな」と思うぐらいなので、気に留めておくぐらいでいいかもしれません。

設定ファイル例

設定ファイルは README を参考に自分に必要な記述をすればと思いますが、自分のも一例としてリンクを載せておきます。 こだわりとしてはcoc.nvimを使わないFileTypeでは、キーマッピングなどを上書きしないようにしています。

終わりに

使用感自体は快適です。vim-lspと比べるとnode.jsへの依存が増えていますが、Language Serverによっては関係なく必要なのであまり気にしていません。LSPひとつとっても、Vim界隈はこういった切磋琢磨が目に見えるので使っていても楽しいですね。