Help us understand the problem. What is going on with this article?

Windows10 WSL2にLinux居城を爆誕させる

ひどい……こういうことする気でしょう!
image.png

するとどうなる?

知らんのか

PowerShellすら不要になる

目次

WSLの中身は単純にUbuntu18.04の環境構築としても使えると思うんですけど (名推理)

WSL2とUbuntu18.04LTSを整備する

WSL2とUbuntu18.04LTSのインストール (前提)

既に導入しているものとする。完

cf. Windows10 HomeでLinuxに寄せた開発環境を整える

日本語化する

日本語が表示されるようにする。

これらのコマンドでいけたような気がする。

sudo apt -y install language-pack-ja
sudo update-locale LANG=ja_JP.UTF8
sudo apt -y install manpages-ja manpages-ja-dev

cf. 【WSL入門】第2回 避けては通れないWSLとWindows 10との文字コードの違い

ちなみに、これらを試したのに未だ □□□みたいな表示になっている……という時は、 WSL2ターミナルのフォント設定が悪さをしている可能性もある。

たとえば僕が使っていた DejaVu Sans Monoだとどうもダメで、 MSゴシックとかなら問題なく表示できる。

(DejaVu、Spacemacsでは元気に日本語を表示するのに…どうして)

パッケージ (管理ツール)を最新化しておく

sudo apt update
sudo apt upgrade

aptコマンドの使い方 => aptコマンドチートシート

WSL2のPATHからWindowsパスを抜く

デフォルト設定ではWSL2の PATH環境変数にWindowsのパス (/mnt/c/~みたいなやつとか)が含まれている。

WSL2のタブ補完を重くするほか、SpacemacsがPythonを呼ぶ時に Windows側のコマンドを探し始める (e.g. /mnt/c/msys64/usr/bin/cmd)といった弊害があるため、予め排除したい。

/etc/wsl.confに以下を追記することで排除できる。

/etc/wsl.conf
[interop]
appendWindowsPath = false

cf. https://github.com/microsoft/WSL/issues/4234#issuecomment-505609403

ただし、Dockerでは必要なパスがあったらしいので、そこだけ別途パスを追加する必要がある。

docker-credential-desktop.exeがパスに含まれていないと、 docker login時に以下のエラーが起こる。

Error saving credentials: error storing credentials - err: exec: "docker-credential-desktop.exe": executable file not found in $PATH, out: ``

僕はこうやった (めんどいのでディレクトリごと追加した)

~/.bash_profile
export PATH=$PATH:/mnt/c/Program\ Files/Docker/Docker/resources/bin

cf. WSL2上のdocker-composeで認証エラー

Vimをクリップボードに対応させる

どうもVim操作がクリップボードのコピーを共有しないみたい :innocent:

(一応、Windows側のクリップボード内容はinsert modeで Ctrl + Shift + vによって貼り付けられるが……)

Vimのバージョン表示からクリップボードの情報を確認して、もし -clipboardだったらクリップボード非対応 :innocent:

対応していれば、このように +clipboardと表示される。

$ vim --version | grep clip

+clipboard         +jumplist          +persistent_undo   +virtualedit
-ebcdic            +mouseshape        +statusline        +xterm_clipboard

クリップボード対応の vim-gtkをインストールする。

非対応のVimをアンインストールして入れ直す。

sudo apt purge vim
sudo apt install vim-gtk

cf. Windows Subsystem Linux - Make VIM use the clipboard?

デフォルトのPythonバージョンを3にする

pythonコマンドで使えるPythonはバージョン2 :innocent:

既にpython3が入っていれば、aliasコマンドで乗っ取っておく。

~/.bash_profile
alias python='python3'

※ pipenvやpyenvを使う上では、この措置はいらなさそう

開発用ディレクトリはWSLファイルシステム内にしておく

これは単なる意識の話だが、オススメなので。。。

WSL2でCドライブ下 (いわゆる /mnt/c/)を主戦場にしていると……

ファイルシステムが重い

magit statusがクソみたいに遅い (10秒くらいかかる)

git statusについては、同じ問題が既に報告されている。
cf. git status is slow in WSL2

原因として考えられるのは、 WSL2のファイルシステム外 (/mnt/)にあるファイルを扱っているケース。

/mnt下のファイルシステムが劣悪パフォーマンスという報告がある (つまりCドライブ /mnt/cなどにgitプロジェクトを置いていると激重)

cf. [wsl2] filesystem performance is much slower than wsl1 in /mnt

ひとまずの対処としては、/mntを避けることくらい。

WSL2側に ~/devディレクトリを作って試しにcloneしてみると、あらゆるファイルアクセスがアホみたいに速い :tada:
(元々WindowsビルドのEmacsで遅さに耐えていたためか3秒ラグくらいは許容できる身体になってて、今まで /mnt下へのアクセスがあんなに遅いとは感じていなかった :innocent: )

「WSL2のディレクトリなんて場所がわからん! (わかったとしても遠いしアクセスもできんやんけ!)」という方もいそう。

WLS2のディスクはこのへんに存在するが、中身を見られない :innocent:

C:\Users\v2okimochi\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState

cf. WSLのホームディレクトリの場所@2019

WSL2内を一発で見に行く方法は ファイルエクスプローラのURL欄に \\wsl$を入力してジャンプ

cf. https://github.com/microsoft/WSL/issues/4328#issuecomment-513691337

はええ。。。普通にアクセスできている。。。

npmなどのホットリロードが効かない

npm run serveなど、「関連ファイルを変更・上書き保存すると自動で再ビルドされる」ホットリロード機能が 効かなくなる

npm単独で起こるのではなく、ホットリロード機能について起こるようだ (?)

やはり /mnt/下で開発していると発生するようで、 /home/ (WSL2のファイルシステム)下で開発していれば問題ない模様。 Windows本体のファイルシステムは恨みでも買っているのか

cf. https://github.com/microsoft/WSL/issues/4417#issuecomment-628697567

WSL2が使えるメモリ量を制限する

初期設定だと、WSL2で大量のメモリを消費した時にWindows本体がメモリ不足で詰む。

cf. WSL 2 consumes massive amounts of RAM and doesn't return it

Windows側の ~/.wslconfigを作って、以下の設定をする。
たとえばメモリを7GBまで、スワップを8GBまでにする。

~/.wslconfig
[wsl2]
memory=7GB
swap=8GB

cf. https://github.com/microsoft/WSL/issues/4166#issuecomment-622318211

もちろん必要な時には多くのメモリを使わせたい (極端に制限すればWSL2が低スペと化す :innocent: )ので、ホストマシンが耐えられるギリギリを模索していくことになりそう。

IPv6を無効化する

ClojureのnReplサーバやAPIサーバがIPv6で立ち始めるので。。。

/etc/sysctl.confに以下を追記する。

/etc/sysctl.conf
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

ターミナルから反映する。

sudo sysctl -p

cf. Disable IPv6 on Ubuntu Linux and Windows 10

Windows側からWSL2内のサーバに localhostで接続できるようにする

初期設定ではできない。

.wslconfigでホストフォワーディングする

楽に設定できる。

まず、Windows側の ~/.wslconfig (つまりWSL2側から見た /mnt/c/Users/v2okimochi(ユーザ名)/.wslconfig)に localhostForwardingを加える。

~/.wslconfig
[wsl2]
localhostForwarding=true

cf. WSL2内で立ち上げたサーバにWindows側からlocalhostで接続する

デフォルトでtrueになってるらしいけど効かなかった疑惑が強いので明示的に設定するのが良さそう。

次に、WSL2側で立ち上げるサーバのホストIPは 0.0.0.0を指定する ( localhost127.0.0.1ではダメみたい :innocent: )

For example, you may need to bind your application to 0.0.0.0 instead of 127.0.0.1. In the example of a Python app using Flask, this can be done with the command: app.run(host='0.0.0.0').

cf. Comparing WSL 2 and WSL 1 - Connecting via remote IP addresses

サーバのホストIPをイーサネットに合わせる

.wslconfigを設定せずにやる場合 (設定したほうが楽なのでたぶん非推奨。最初に載せた方法がコレなので残しているだけ)

WSL2側にWeb, APIサーバを立てていて、以下のようにAPIサーバ側のローカルアドレスが localhost (or 127.0.0.1)になっていると、Windows側から接続できない。Webサーバからも接続できない。

$ sudo netstat -tulpn | grep LISTEN

tcp        0      0 127.0.0.1:8080          0.0.0.0:*   <- 接続できない (API)
tcp        0      0 0.0.0.0:3000            0.0.0.0:*   <- 接続できる (Web)

Webサーバがあたかも大丈夫っぽい見え方だが、Windows側からはWSL側のイーサネット eth0アドレスを使わないと接続できなかった :innocent:

多分同じ理由で、 .wslconfigを使わないならAPIサーバを単に 0.0.0.0にしてもダメ。

サーバのホストIPは、WSL側の eth0アドレスと合わせる (172.29.29.80みたいなやつ)
※ Windows側から見えているWSLアドレスではない

すると、WSL2内の別サーバやWindows側から eth0アドレスで接続できる。

不要かもだが、もしeth0アドレスが変わっても機械的に取得するには、こういうコマンドを使う?

$ ip address show eth0 | grep inet | awk '{print substr($2, 0, index($2, "/") - 1)}'

※ eth0のアドレス情報からIP (172.29.29.80/20みたいなやつ)だけを抜き出し、さらにサブネットマスク (/20とか)を抜いて表示する

WSL2内のサーバにlocalhostで接続できない問題が起きたら

WSL2のホストフォワーディングを有効にしてWSL2内サーバ側ホストIPを 0.0.0.0にしたのにWindows側から接続できない (拒否される)というパターンがある。

WSL2の気分によって時折そうなる…と思ったらなんとPCを起動する度に発生する (cf. https://github.com/microsoft/WSL/issues/4636#issuecomment-634817484 (ビルド 19041.264で観測))。

全般的な (?)issueも立っていた
cf. Local sites running in WSL2 not accessible in browser

解決策としては、
- Windowsの高速スタートアップ設定を止める
- PCを再起動する
- WSL2を再起動する

高速スタートアップ設定を止める

Windows10にはPC起動を高速化する設定があり、これがWSL2に影響しているという説がある。

To everyone subscribed on this thread: Turn off Fast Startup.
Until the bug is fixed turning off Fast Startup seems best solution for now on build 19041.

cf. https://github.com/microsoft/WSL/issues/4636#issuecomment-637821622
cf. WSL2 localhost forwarding randomly stop working

Windows設定から高速スタートアップを止める方法:
cf. Windows10 - 高速スタートアップを有効/無効にする方法

PCを再起動する

解決するらしいが、しんどい
(毎日PCをシャットダウンしているので、毎日PC起動後に再起動せねばなるまい)

WSL2を再起動する

色々と不具合があるときも、WSL2を再起動して解決することがある

PCを再起動せず、WSL2だけを狙って再起動するにはこうする。停止させれば、自動で再起動する。

wsl --shutdown

cf. Rebooting Ubuntu on Windows without rebooting Windows?

wsl -t Ubuntu18.04みたいな使い方もあって気になっていたけど、うまく動かなくて断念。

WSL2でDockerを使う

Docker Desktop for Windows v2.2.2.0以降をインストールする。

Dockerの設定から、 Enable integration with my default WSL distro or `Enable integration with additional distros (お好みのディストリビューション)にチェックを入れる。

cf. https://qiita.com/v2okimochi/items/c9da7df8d4f03283121b#docker-desktop-for-windows-v2220%E4%BB%A5%E9%99%8D

WSL2でツール円舞する

Homebrew for WSLでパッケージインストールを楽にする

ようこそ https://docs.brew.sh/Homebrew-on-Linux

ターミナルでコレを実行するらしい。

test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)
test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.bash_profile
echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile

Macのように、パッケージを楽にインストールできるようになった :tada:

brewの使い方 => 今さらだけどHomebrewのコマンドをちゃんと理解して使おう

Gitを最新化する

Ubuntu18.04LTSに入っているGitは2.17.1-1ubuntu0.7だった。これ以上バージョンが上がらない :innocent:

Gitに脆弱性が見つかったというニュースがホットなので、かなり気になる。

cf. Gitに深刻な脆弱性、認証情報など取得されるおそれ

aptのGitはアンインストールしてしまって、Homebrew for WSLでGitをインストールするのが良さそう。

sudo apt purge git

brew install git

direnvでプロジェクトごとに環境変数を管理する

ようこそ https://github.com/direnv/direnv

Homebrewを入れたな?brewを打て

brew install direnv

~/.bashrcに設定を追記する。vimを使うならこう

~/.bashrc
export EDITOR=vim
eval "$(direnv hook bash)"

使い方 => direnvを使おう

jenvでJDKをバージョン管理する

ようこそ https://github.com/jenv/jenv

しかしHomebrewのjenvはうまく動かない :innocent:

jenv公式に従い、Linux版の手動インストールをする。

Bashの場合はこれらのコマンドでいけそう。

git clone https://github.com/jenv/jenv.git ~/.jenv

echo 'export PATH="$HOME/.jenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(jenv init -)"' >> ~/.bash_profile

https://jdk.java.net/archive/ からopenjdk11や12を手動ダウンロードして、jenvに加える。

たとえばopenjdk13を使う場合は、これらのコマンドでいけそう。
手動ダウンロードしたJDKは ~/jdks/に集める想定。

mkdir ~/jdks
cd ~/jdks
wget https://download.java.net/java/GA/jdk13.0.2/d4173c853231432d94f001e99d882ca7/8/GPL/openjdk-13.0.2_linux-x64_bin.tar.gz
tar xvfz openjdk-13.0.2_linux-x64_bin.tar.gz

jenv add ~/jdks/jdk-13.0.2

うまく入れば、JDKバージョンの候補に表示される。

$ jenv versions

  system
  13
  13.0
  13.0.2
  openjdk64-13.0.2

利用するJDKとして指定する。グローバルに使いたい場合は、たとえばこう。

jenv global 13.0.2

成功すれば、Javaコマンドのバージョン表示が変わる。

$ java --version

openjdk 13.0.2 2020-01-14
OpenJDK Runtime Environment (build 13.0.2+8)
OpenJDK 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)

JDKをバージョン管理できるようになった :tada:

pipenvでPython仮想環境を管理する

ようこそ https://github.com/pypa/pipenv

pipenvの用意

Homebrewを入れたな?brewを打て

brew install pipenv

pyenvの用意

どうも pyenv (Pythonのバージョン管理)が入ってこないみたい。

必要なライブラリを準備した上で、pyenvをインストールする。

sudo apt install zlib1g-dev
brew install pyenv

cf. 【pyenv】ubuntu16.04でのpython環境の構築

Pythonの仮想環境を使えるようになった :tada:

tfenvでterraformをバージョン管理する

ようこそ https://github.com/tfutils/tfenv

Homebrewを入れたな?brewを打て

brew install tfenv

terraformをバージョン管理できるようになった :tada:

nvmでNodeをバージョン管理する

ようこそ https://github.com/nvm-sh/nvm

Homebrewがサポートされていない :innocent: :innocent: :innocent:

Homebrew installation is not supported. If you have issues with homebrew-installed nvm, please brew uninstall it, and install it using the instructions below, before filing an issue.

断腸の思いで手動インストールする。
公式に従い、以下のコマンドでいけそう。

export NVM_DIR="$HOME/.nvm" && (
  git clone https://github.com/nvm-sh/nvm.git "$NVM_DIR"
  cd "$NVM_DIR"
  git checkout `git describe --abbrev=0 --tags --match "v[0-9]*" $(git rev-list --tags --max-count=1)`
) && \. "$NVM_DIR/nvm.sh"

~/.bashrcに環境変数を追加する。

~/.bashrc
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

cf. https://github.com/nvm-sh/nvm#manual-install

Nodeをバージョン管理できるようになった :tada:

余談だが、WSL2では npm run serveのホットリロードが機能しない :innocent:

cf. https://github.com/microsoft/WSL/issues/4417

avnでnvmによるバージョン切り替えを自動化する

まずはnvmで適当なNodeバージョンを使うんだ (v12.18.0とか)

nvmによるNodeバージョン切り替えは、そのままだと手動で行う必要がある :innocent: :innocent:
jenvがJavaバージョンを勝手に使い分けるみたいに、nvmもよしなにやってほしい。。。

自動化するため avnをインストールする

$ npm install -g avn avn-nvm avn-n
$ avn setup

avn: profile already set up (~/.bash_profile)
avn: configuration unchanged (~/.avnrc)
avn-n: installation complete

cf. ディレクトリごとに異なるバージョンのnodeを使いたいのでavnを使った話

nodeのバージョンによっては、setup時に error cb.apply is not a functionエラーが起こる。

v14.11.0やv14.12.0ではダメだった。v12.18.0ではsetupできた。

cf. https://github.com/nodejs/help/issues/2874#issuecomment-693368991

あとは任意のディレクトリに .node-versionを用意すれば、そのディレクトリに入った時自動でNodeバージョンが切り替わる。

地味に面倒なので echo "v14.12.0" > .node-versionみたいにスッと作ってしまう。

.node-version
v14.12.0

avnを入れたのはv12.18.0のはずだが、他のバージョンを使っている時でもちゃんとバージョン切り替えが発動する。なぜだ。。。

LeiningenでClojureをいい感じに使う

ようこそ https://leiningen.org/

残念ながら手動操作が多い :innocent:

  1. Download the lein script (or on Windows lein.bat)
  2. Place it on your $PATH where your shell can find it (eg. ~/bin)
  3. Set it to be executable (chmod a+x ~/bin/lein)
  4. Run it (lein) and it will download the self-install package

以下のコマンドでいけそう。

wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein
mkdir ~/bin
sudo mv ~/lein ~/bin/
sudo chmod a+x ~/bin/lein
echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc
lein

成功すれば、leiningenのバージョンを確認できる。

$ lein --version

Leiningen 2.9.3 on Java 12.0.2 OpenJDK 64-Bit Server VM

ClojureのビルドツールLeiningenを使えるようになった :tada:

sbtでScalaをがんばる

ようこそ https://www.scala-sbt.org/1.x/docs/ja/Hello.html

Homebrewを入れたな?brewを打て

brew install sbt

Scalaのビルドツールsbtを使えるようになった :tada:

tmuxで1ターミナルをうまく使う

ようこそ https://github.com/tmux/tmux

tmuxをインストール

Homebrewを入れたな?brewを打て

brew install tmux

ターミナルの1画面を分割して使えるようになった :tada:

マウス操作やクリップボード共有を設定する

マウスで画面を切り替えたり、クリップボードを共有したりしたい。

まずクリップボード共有の前準備として、Windows側のクリップボードを使うために win32yankを使う1

wget https://github.com/equalsraf/win32yank/releases/download/v0.0.4/win32yank-x64.zip
unzip win32yank-x64.zip

win32yank.exeが出てくる。
一緒に解凍される LICENSEREADME.mdは削除しても良い。

今回は ~/bin/に置いてパスを通すことを想定する。
予め実行権限もつけておく。

chmod +x win32yank.exe
mkdir ~/bin
mv ~/win32yank.exe ~/bin/
echo "export PATH=$HOME/bin:$PATH" >> ~/.bash_profile

source ~/.bash_profile

最後に、 ~/.tmux.confに以下を記述する。

~/.tmux.conf
# マウス有効化
set -g mouse on

# マウススクロール
bind -n WheelUpPane   select-pane -t= \; copy-mode -e \; send-keys -M
bind -n WheelDownPane select-pane -t= \;                 send-keys -M

# ドラッグでコピー
bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "win32yank.exe -i"

# copy-modeのコピー&ペーストをviキーバインドにする
set-window-option -g mode-keys vi
setw -g mode-keys vi
bind-key -T copy-mode-vi v send -X begin-selection
bind-key -T copy-mode-vi y send -X copy-pipe-and-cancel "win32yank.exe -i"
unbind -T copy-mode-vi Enter
bind-key -T copy-mode-vi Enter send -X copy-pipe-and-cancel "win32yank.exe -i"

cf. tmux 2.1 以降でもマウスを有効にする方法
cf. tmuxのおすすめconf設定@2019

さらに、tmuxではコピー&ペーストの挙動がまるで違うため、ひとまずtmux

tmuxinatorでtmuxのレイアウトを自動起動する

ようこそ https://github.com/tmuxinator/tmuxinator

Homebrewを入れたな?brewを打て

brew install tmuxinator

開発環境でいつも使っているようなレイアウト・いつも使っている移動コマンドなどを登録して、コマンド1発で自動起動できる。

先に環境変数 EDITORを追加しておく。tmuxinatorで使うエディタ。

~/.bash_profile
export EDITOR='vim'

たとえば devという名前で、自動起動の設定を作る。

$ tmuxinator new dev

先ほど登録したエディタが立ち上がるので、Yamlで設定を書く。たとえばこう。

~/.config/tmuxinator/dev.yml
name: dev
root: ~/

windows:
  - editor:
      layout: 8c65,205x39,0,0{102x39,0,0,0,102x39,103,0[102x19,103,0,1,102x19,103,20,2]}
      panes:
        - root-dir:
          - cd ~/dev/v2okimochi-apps
          - pwd
        - frontend:
          - cd ~/dev/v2okimochi-apps/frontend
          - npm run serve
        - spacemacs:
          - emacs

上記の設定では、こういうことをしている。

  • 1ウィンドウを3分割している (左右2分割し、右側をさらに上下2分割)
    • レイアウトは用意されたものを使うこともできるし、自力で書くこともできる
      > The layout setting gets handed down to tmux directly, so you can choose from one of the five standard layouts or specify your own.
    • 自力で書く場合は、tmuxで好みのレイアウトを作った状態で別のシェルから tmux list-windowsすれば、レイアウト情報が表示される。
  • 3分割したペインで、それぞれ別のコマンドを実行している
    • 1番目のペイン root-dirでは cdpwd
    • 2番目のペイン frontendでは cdnpm run serve
    • 3番目のペイン spacemacsでは emacs

作成済みの設定 devを実行する場合はこう。

$ tmuxinator start dev

さらに aliasを張って、WSL2の開始とともに一言でレイアウト起動することもできる。

~/.bash_profile
alias devstart='tmuxinator start dev'

いつものレイアウトでディレクトリ移動したりサーバを立ち上げたりする作業が自動化された :tada:

WSL2上で動かすSpacemacsのために便利な設定をする

Spacemacsをインストールする前にやっておくと、無駄なエラーが出なくて良さそう。

Source Code Proフォントをインストールする

Spacemacsで推奨されているフォント Source Code ProをUbuntuにインストールする。

以下の7コマンドをターミナルで打ち込む。完

mkdir /tmp/adodefont
cd /tmp/adodefont
wget https://github.com/adobe-fonts/source-code-pro/archive/2.010R-ro/1.030R-it.zip
unzip 1.030R-it.zip
mkdir -p ~/.fonts
cp source-code-pro-2.010R-ro-1.030R-it/OTF/*.otf ~/.fonts/
fc-cache -f -v

cf. https://kurenaif.hatenablog.com/entry/2016/10/28/193238
(元はコレ? https://askubuntu.com/a/576263)

ispellでSpacemacsのスペルチェックをする

言語を ja_JPにしていると、デフォルト設定では ja_JPに対するispellのスペルチェックがうまく働かない。

(エラー: No word lists can be found for the language "ja_JP".)

ispellの言語設定を en_USにする。なんと aspell.confで良いらしい。

echo “lang en_US” > ~/.aspell.conf

cf. ispellで No word lists can be found for the language “ja_JP”

Clojureの掃除屋clj-kondoを雇う

ようこそ https://github.com/borkdude/clj-kondo

Homebrewを入れたな?brewを打て

brew install borkdude/brew/clj-kondo

掃除屋を雇えた :tada:

jokerでClojureのlinterを充実させる

ようこそ https://github.com/candid82/joker

Homebrewを入れたな?brewを打て

brew install candid82/brew/joker

linterが増えた :tada:

MetalsでScalaの定義ジャンプを効かせる

Spacemacsの本体はEmacsなので、EmacsでMetalsを扱うためのドキュメントを参考にする。

手動インストール :innocent: :innocent: :innocent:

これらのコマンドでいける模様 (最後のコマンドは sudoが必要)

curl -L -o coursier https://git.io/coursier-cli
chmod +x coursier
sudo ./coursier bootstrap \
  --java-opt -Xss4m \
  --java-opt -Xms100m \
  --java-opt -Dmetals.client=emacs \
  org.scalameta:metals_2.12:0.9.1 \
  -r bintray:scalacenter/releases \
  -r sonatype:snapshots \
  -o /usr/local/bin/metals-emacs -f

cf. https://scalameta.org/metals/docs/editors/emacs.html

Spacemacsで使う場合は、 Space Spaceから手動で lsp-metals-build-importを実行する必要があるかも。

(でないと no build targetだの Skipping build import for unsupported sbt version <unknown>だのとエラーが出て定義ジャンプしてくれない)

ScalastyleでScalaを自動フォーマットする

cf. https://github.com/syl20bnr/spacemacs/tree/develop/layers/%2Blang/scala#scalastyle

Homebrewを入れたな?brewを打て

brew install scalastyle

しかしこれだけでは機能しない :innocent:

フォーマット設定のため、以下のようなxmlファイルを作る。たとえば ~/scalastyle_config/default.xmlという名前で置く場合はこう。

~/scalastyle_config/default.xml
<scalastyle commentFilter="enabled">
 <name>Scalastyle standard configuration</name>
 <check level="warning" class="org.scalastyle.file.FileTabChecker" enabled="true" />
 <check level="warning" class="org.scalastyle.file.FileLengthChecker" enabled="true">
  <parameters>
   <parameter name="maxFileLength">800</parameter>
  </parameters>
 </check>
</scalastyle>

cf. http://www.scalastyle.org/configuration.html

次にSpacemacs側の設定を加える。 user-config()にxmlの場所を絶対パスで追記する (フォーマットはFlycheckで行う)

ホームディレクトリが /home/v2okimochiならこう。

(defun dotspacemacs/user-config ()
  ;;; Scala

  ;; format style
  (setq-default flycheck-scalastylerc "/home/v2okimochi/scalastyle_conf/default.xml")
)

自動フォーマットされるようになった :tada:

WSL2上でSpacemacsを動かしてGUI表示する

Xサーバを利用してWSL2の描画をWindows側へ引っ張る。

VcXsrvインストール

cf. WSL上にXサーバをインストールしてGUIを実現する(VcXsrv編)

※ VcXsrvのインストールだけ参考にする。WSL2側の設定は色々カスタムすることになる。

WSL2にデスクトップ環境をインストールする

インストールするデスクトップ環境は、わりと何でも良いかもしれない。

僕は xfce4をインストールした。軽量で有名みたい。

sudo apt install xfce4

cf. 初心者のためのWSL( 2 ) ~GUI設定,デスクトップ環境設定編~

キー反応速度を上げる

xfce4のデスクトップ環境上でキー反応速度を上げておくと、デスクトップ環境で起動したSpacemacs上のカーソル移動が捗る。

キーボード設定から キー入力の設定を変える。僕のオススメはこれ。

- リピートするまでの時間: 150 (ms)
- リピート速度: 30

WSL2からVcXsrvに接続するための設定をする

WSL2に DISPLAY環境変数を設定する

以下のように ~/.bashrcに追記して、 source ~/.bashrcなどで反映する。

~/.bashrc
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0

cf. https://github.com/microsoft/WSL/issues/4106#issuecomment-501885675

こんな記述をする理由は、WSL2のバグ (?)2や仕様 (?)3があるから。

デスクトップ環境が xfce4の場合は、DISPLAYに加えてこっちも必要かも。

~/.bashrc
export LIBGL_ALWAYS_INDIRECT=1

cf. 初心者のためのWSL( 2 ) ~GUI設定,デスクトップ環境設定編~

VcXsrvをグローバルアクセス可能にする

VcXsrvの XLaunch起動時に行うデフォルト設定で、手を加える。

まず Extra settingsDisable access controlにチェックを入れる。
(全てのクライアントからアクセス可能にする)

cf. https://github.com/microsoft/WSL/issues/4106#issuecomment-502920377

同じく Extra settingsAdditional parameters for VcXsrv欄に -acを入力する。
(パブリックアクセス可能にする)

※ 僕はなくてもいけた

cf. https://github.com/microsoft/WSL/issues/4106#issuecomment-502989345

設定ファイル config.xlaunchを保存し、それをWindowsスタートアップに登録すれば、Windows起動時に同じ設定で XLaunchが立ち上がってくれる。

cf. WSL2におけるVcXsrvの設定

WindowsファイアウォールでVcXsrvのパブリックアクセスを許可する

cf. https://github.com/microsoft/WSL/issues/4106#issuecomment-502996546

VcXsrvインストール時に、ファイアウォールのパブリックアクセスを許可していれば設定不要。

もし許可していなければ、改めて設定から許可する。

コントロールパネル > システムとセキュリティ > Windowsファイアウォールによるアプリケーションの許可

描画されることの確認は、WSL2で xeyesなどGUIのコマンドを打つ。

Spacemacsをインストールする

ようこそ https://github.com/syl20bnr/spacemacs/tree/develop

git clone -b develop https://github.com/syl20bnr/spacemacs ~/.emacs.d

設定やトラブルシュートのあれこれはこっち cf. Spacemacsメモとトラブルシューティング

GNU Emacs26をインストールする

Homebrew for WSLでインストール可能な emacs25は相性が悪いようなので、GNU Emacsを使う。

(MacのHomebrewだと emacs-plusを使えるが、Ubuntuなのでまあ仕方ない)

27をインストールしてみる

$ sudo apt update
$ sudo apt install emacs27

apt-get使ってた頃はEmacsが候補に無かったのでリポジトリ追加とかしてた。
もしaptで同じ現象があれば以下で追加する

$ sudo add-apt-repository ppa:kelleyk/emacs

cf. Emacsで快適な研究環境を整えよう~導入編

Emacs26から27にするぞ、をやる場合はパッケージ競合で昇天するので既存Emacsをアンインストールしてから新たなEmacsをインストールする必要がある。

うっかり既存Emacsを残すと依存関係エラーが出てinstallもuninstallもできなくなる

dpkg: アーカイブ /var/cache/apt/archives/emacs27-common_27.1~1.git86d8d76aa3-kk2+18.04_all.deb の処理中にエラーが発生しました (--unpack):
 '/usr/include/emacs-module.h' を上書きしようとしています。これはパッケージ emacs26-common 26.3~1.git96dd019-kk1+18.04 にも存在します
dpkg-deb: エラー: ペースト subprocess was killed by signal (Broken pipe)
処理中にエラーが発生しました:
 /var/cache/apt/archives/emacs27-common_27.1~1.git86d8d76aa3-kk2+18.04_all.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

やらかした場合は dpkg--force-overwriteオプションでひとまず強制修復 (?)してから再インストールする手がありそう

こんな感じ
$ sudo dpkg -i --force-overwrite /var/cache/apt/archives/emacs27-common_27.1~1.git86d8d76aa3-kk2+18.04_all.deb

cf. CUDAの依存関係でエラーが出た話

Spacemacsでまともな日本語入力をする

どうもデフォルト状態だと、日本語の変換機能が貧弱 ( 日本語という変換すらできない :innocent: :innocent: :innocent: )

Google日本語入力で有名な mozcを導入する。

必要な機能のインストール

emacs-mozc-binがあれば良いらしい。
emacs-mozcをごっそり入れるとEmacsまでついてきてしまうらしいので、 emacs-mozc-binを狙い撃つ。

sudo apt install emacs-mozc-bin

Spacemacsの設定でも mozcパッケージをインストールする。こんな感じで追加する。

.spacemacs
   dotspacemacs-additional-packages '(mozc
                                      mozc-popup)

IMEとキーバインドを設定

mozcをデフォルトの入力ソースに設定するついでに、キーバインドもつけておく。

.spacemacs
(defun dotspacemacs/user-config ()

  ;;; 入力中のIME切り替え

  (setq default-input-method "japanese-mozc")
  (if (require 'mozc-popup nil t)
      ;; 'overlay: 入力直下にオーバーレイ表示, 'echo-area: Powerlineに表示, 'popup: 軽量なoverlay
      (setq mozc-candidate-style 'popup)
    (setq mozc-candidate-style 'echo-area))
  (defun start-mozc()
    "入力ソースがnilなら、日本語入力に切り替えるコマンド"
    (interactive)
    (if (equal current-input-method nil)
        (progn (toggle-input-method)
               (message "IMEを有効化しました"))))
  (defun end-mozc()
    "入力ソースがあれば、IME無しに切り替えるコマンド"
    (interactive)
    (if (not (equal current-input-method nil))
        (progn (toggle-input-method)
               (message "IMEを無効化しました"))))
  ;; insert stateでIME切り替え
  (define-key evil-insert-state-map (kbd "<henkan>") 'start-mozc)
  (define-key evil-insert-state-map (kbd "<muhenkan>") 'end-mozc)
  ;; command line (ex-completion)入力時にIME切り替え
  (define-key evil-ex-completion-map (kbd "<henkan>") 'start-mozc)
  (define-key evil-ex-completion-map (kbd "<muhenkan>") 'end-mozc)
  ;; `/`検索 (ex-search)入力時にIME切り替え
  (define-key evil-ex-search-keymap (kbd "<henkan>") 'start-mozc)
  (define-key evil-ex-search-keymap (kbd "<muhenkan>") 'end-mozc)
  ;; insert stateになったらIME無効化
  (add-hook 'evil-insert-state-entry-hook 'end-mozc)

  ;;; Helm

  (with-eval-after-load 'helm
    (bind-keys :map helm-map
               ;; IME切り替え
               ("<henkan>" . start-mozc)
               ("<muhenkan>" . end-mozc)))

)

cf. spacemacsでmozcを用いた日本語入力
cf. この春オススメしたい第三のエディタ

壮大な設定を書かざるを得なかった :innocent: :innocent: :innocent: :innocent: :innocent:

current-input-methodを使った判定が うまくいかなかった うまくいったので、それを利用している。

普段は 変換キーと 無変換キーでIMEを切り替えているため、キーバインドも合わせねばならない。

しかもnormal stateにキーバインドを設定するとさらなる不具合に見舞われる4ため、insert stateとcommand-line state (なぜかex-completionが該当するらしい)とhelm find mode (ファイル検索するときのアレ)を狙い撃つように設定した。

また、日本語変換のポップアップ表示のためmozc-popupを使っている5

cf. Spacemacs Emacs 25.2(日本語入力) on Ubuntu 16.04 on VMware 8.5 on macOS Sierra

Ubuntu側のキー設定を無効化

Ubuntu側にもmozcのキー設定があって、デフォルト設定だと 変換キーと無変換キーが衝突するかもしれない
見たところSpacemacs内ではキーバインドが独立しているような気がするので、大丈夫かも。

一応、無効化するためには、デスクトップ環境からmozcのキー設定を削る。

xfce4なら、ターミナル上で以下のコマンドを使えばデスクトップ環境が立ち上がる。

$ startxfce4

mozc設定.png

キー設定.png

henkan.png

Henkan, Muhenkanがそれぞれ3パターンほど存在する。
選択して 編集ボタンから削除する。

完了

良い感じに変換してくれるようになった :tada:
image.png

変換候補ウィンドウの背景色が目に悪いのが気になるが……

プログラミングと相性の良いフォント Source Han Code JPを使う

プログラミングに役立つフォントは、チラっと見ただけでも結構ある。
たとえば日本語対応フォント。

Source Han Code JP
Cica
Myrica
Ricty Diminished
VLゴシック
Migu 1M

cf. 【2019年版】プログラミングが捗るコーディングに適したフォント集

Spacemacsが激推しなのはSource Code Pro
Ubuntuにもインストールできる。

一時期は 会社など旧字体のような表示があり6、だいぶしんどかったのでフォントを Source Han Code JPに変えた。
(Cicaはうまくインストールできなかったので断念した)

基本的にはこちらの通りにインストール。だいぶアレンジしてしまったので、その手順も残しておく。

cf. Source Han Code JPをUbuntuにインストールしてデフォルトフォントに設定する

AFDKOとSource Han Code JPをcloneするのは同じ。今回は面倒なので、個別に仮想環境を作らず、pyenvで既に持っていたPython3.8に関連ライブラリを直接インストールしてしまった。記憶は曖昧

sudo apt install gcc-multilib g++-multilib
pip install fonttools

mkdir ~/fonts-download
cd ~/fonts-download
git clone https://github.com/adobe-type-tools/afdko/
git clone https://github.com/adobe-fonts/source-han-code-jp
cd afdko
python setup.py

addSVGtableに関する部分はやはりエラーが出るため、参考の通りにコメントアウトした。
このあたり。38-54行だった。

source-han-code-jp/commands.sh
    if addSVGtable.py -s $svg ${nf} ; then :
    else
        echo Error
        exit
    fi

    if addSVGtable.py -s $svg ${inf} ; then :
    else
        echo Error
        exit
    fi

    if otf2otc -t 'CFF '=0 -o ${ttc} ${nf} ${inf} ; then :
    else
        echo Error
        exit
    fi

最後にOTFファイルを作成する。

cd ~/fonts-download
./commands.sh

だんだん考えるのがつらくなってきたので、フォントのインストールは ~/.fontsを使った。

OTFファイルを置いておけば、コマンド1発でインストールできる。
~/.fonts内にフォント以外の変なファイルを置いたりすると表示がバグるので注意 (フォント関連のclone先を分けたのはそういう意図もある)

mkdir ~/.fonts
cp ~/fonts-donwload/source-han-code-jp/Medium/SourceHanCodeJP-Medium.otf ~/.fonts/
fc-cache -fv

cf. フォントのインストール

最後にSpacemacs側でフォント設定を変える。Spacemacsを再起動すればフォントが変わっているはず。

   dotspacemacs-default-font '("Source Han Code JP"
                               :size 16
                               :weight normal
                               :width normal
                               :powerline-scale 1.1)

ヨシ!

image.png


  1. /mnt/c/Windows/System32/clip.exeでもできるのかもしれないが、Windows側のパスは予め除外済みなので改めて加えるのが億劫だった。記事によっては既存コマンドに不足があってwin32yankを推すものもあったので、今回採択した。 

  2. VcXsrvに関する諸記事では DISPLAY=:0.0DISPLAY=:0など やたら省略できる方法が紹介されているが、WSL2ではどうやら 通用しない
    cf. WSL2の導入とGUI環境の構築とsshfsしたものもgnome-openしたい!!
    localhost表記すら通じないらしく、 DISPLAY=127.0.0.1:0.0のようにIPアドレスを明示する必要がある。 

  3. WSL2のIPアドレスは起動の度に変わる :innocent: :innocent: :innocent: Windowsを起動する度にHyper-VスイッチのIPが変わるから、らしい。
    cf. https://github.com/microsoft/WSL/issues/4210#issuecomment-511105147
    cf. https://github.com/MicrosoftDocs/WSL/issues/418#issuecomment-511104330 

  4. 理由はわからないが、insert stateとnormal stateで IME設定が分離しているかのような挙動をする。
    たとえばnormal stateでIMEを無効化したつもりが、insert stateに入ってみると変化していない。
    仕方ないので、 (add-hook)を使って insert stateに入った時にIMEを無効化することにしている (日本語入力は必要な時しか使わないので、普段はできるだけ無効化しておきたい) 

  5. mozcをただ使うだけなら 'mozc-overlayでポップアップ表示される。
    しかし重くてラグがひどかったので、 mozc-popupをインストールして 'popupのほうを使っている (動作が軽い) 

  6. 原因は別のところにあったようで、今ではSource Code Proに戻しても不具合はない。まあ明示的に日本語対応しているSource Han Code JPを引き続き使っている 

v2okimochi
_人人人人人人人人_           >         <           > お き も ち <           >         <            ̄Y^Y^Y^Y^Y^Y^Y^ ̄           
opt
"INNOVATION AGENCY" を標榜するインターネット広告代理店。エンジニア組織 "Opt Techonologies" を中心にアドテクetc...に取り組んでいます。
https://opt-technologies.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away