WSL2上でRust開発環境を整える（2日目）

[1日目](https://qiita.com/doshiyo/items/1b3baceb831268714495)の続き。

## win32yank.exeのシンボリックリンクを作る

```zsh
# c:\wsl-tools\bin\win32yank.exe に保存した場合はこんな感じ
ln -s /mnt/c/wsl-tools/bin/win32yank.exe /usr/local/bin/win32yank.exe
```

PATH変数に突っ込んでもよい
```zsh
echo 'export PATH="/mnt/c/wsl-tools/bin:$PATH"' >> ~/.zshrc
```

## tmuxの設定を追加

zshでマウスを使わずスクロールやコピペをする方法を知らないのでtmuxを使う。
ホームポジションから動かないので、腱鞘炎持ちには優しい。
あと、なんとなくステレオタイプ的なハッカーっぽい感じで操作できるのが良い。

```conf:~/.tmux.conf
# vim キーバインド
setw -g mode-keys vi

# C-b q で切り替えるときの猶予時間を5秒に
set -g display-panes-time 5000

# Vim使いはEscapeにディレイがあるとストレスフルなので最短にする
# set -sg escape-time 0 にするとセッション作成時に謎の文字列が表示されるので、1にしておく
set -sg escape-time 1

# マウス設定
set -g mouse on
bind -T edit-mode-vi WheelUpPane send-keys -X scroll-up
bind -T edit-mode-vi WheelDownPane send-keys -X scroll-down

# ペインの移動をVimライクに
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

# vキーで選択開始
bind -T copy-mode-vi v send -X begin-selection
# Ctrl-vで矩形選択
bind -T copy-mode-vi C-v send-keys -X begin-selection \; send-keys -X rectangle-on
# Escape時に矩形選択モードも解除
bind -T copy-mode-vi Escape send-keys -X clear-selection \; send-keys -X rectangle-off

# クリップボードにコピー
bind -T copy-mode-vi y 	   send-keys -X copy-pipe-and-cancel 'win32yank.exe -i --crlf'
bind -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel 'win32yank.exe -i --crlf'
# クリップボードから貼り付け
bind p run 'tmux set-buffer -- "$(win32yank.exe -o --lf)"; tmux paste-buffer'
```

参考記事

https://qiita.com/gatapon/items/c7cf549ebffe86599be9

https://qiita.com/tMinamiii/items/f2d7adcb244719f987a6

## Neovimをインストール

aptでインストールすると0.7系が入っちゃうので、snapでインストールする。
systemdを有効にする必要があったので、参考記事の通りsystemdを有効にする。

[公式ドキュメント](https://github.com/neovim/neovim/wiki/Installing-Neovim#snap)にsnapでのインストール方法が書かれているのでその通りインストールする。

```zsh
sudo snap install --beta nvim --classic
# snapインストールディレクトリにパスを通す
echo 'export PATH=/snap/bin:$PATH"' >> .zshrc
# vimコマンドでnvimを起動させる
echo 'alias vim="nvim"'
```

参考記事

https://qiita.com/lx-sasabo/items/123b95ada9a3a4813899

## Neovimを設定する

ここが一番大変なんじゃないかと思う。
IDEとして使うための [LunerVim](https://www.lunarvim.org/) とかあるけれども、Vimを使いこなしているわけでもないのでキーバインドを覚えられなさそうだし、VSCode-Neovimも使いたいので自分で設定を書かないとプラグインの切り分けが大変そうということでスモールスタートする。

パッケージマネージャーはなんとなく [lazy.nvim](https://github.com/folke/lazy.nvim) にする。

### まずはコピペできるようにする

コピペできないと面倒なので、一時的にコピペする設定を入れておく。

```zsh
mkdir -p ~/.config/nvim/lua
touch ~/.config/nvim/init.lua
touch ~/.config/nvim/lua/temp.lua
```

```lua:~/.config/nvim/lua/temp.lua
vim.opt.shortmess:append("c")
vim.opt.clipboard:append("unnamedplus")

vim.g.clipboard = {
  name = "WslClipboard",
  copy = {
     ["+"] = "win32yank.exe -i --crlf",
     ["*"] = "win32yank.exe -i --crlf",
   },
  paste = {
     ["+"] = "win32yank.exe -o --lf",
     ["*"] = "win32yank.exe -o --lf",
  },
  cache_enabled = 1,
}

-- ついでにタブはスペース2つに
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.softtabstop = 2
vim.opt.expandtab = true
```

```lua:~/.config/nvim/init.lua
require("temp")
```

### lazy.nvimの導入

インストールは[公式](https://github.com/folke/lazy.nvim)に書いてある通りに進める。

```lua:~/.config/nvim/lua/plugin.lua
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    "git",
    "clone",
    "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git",
    "--branch=stable", -- latest stable release
    lazypath,
  })
end
vim.opt.rtp:prepend(lazypath)
```

```lua:~/.config/nvim/init.lua
require("temp")
require("plugin")
```

ここまで設定してnvimを再起動すればlazy.nvimがインストールされるはず。
`~/.local/share/nvim/lazy/lazy.nvim` が出来上がってればOK

### テキストオブジェクトとオペレーターを追加

まずはテキストオブジェクトから追加していく。
最初からキレイに書こうとしても、慣れてきた頃には書き直したくなるハズなので最初はとりあえず動かすことを目標とする。

```lua:~/.config/nvim/lua/plugin.lua
-- ファイルの末尾に追記
require("lazy").setup({
  -- テキストオブジェクト
  'kana/vim-textobj-user',
  {'kana/vim-textobj-entire', dependencies = {'kana/vim-textobj-user'}},
  {'kana/vim-textobj-line', dependencies = {'kana/vim-textobj-user'}},
  {'kana/vim-textobj-function', dependencies = {'kana/vim-textobj-user'}},
  {'kana/vim-textobj-jabraces', dependencies = {'kana/vim-textobj-user'}},
  {'kana/vim-textobj-indent', dependencies = {'kana/vim-textobj-user'}},
  {'mattn/vim-textobj-url', dependencies = {'kana/vim-textobj-user'}},
  {'thinca/vim-textobj-between', dependencies = {'kana/vim-textobj-user'}},
  {'anyakichi/vim-textobj-xbrackets', dependencies = {'kana/vim-textobj-user'}},
  {'RyanMcG/vim-textobj-dash', dependencies = {'kana/vim-textobj-user'}},
  {'sgur/vim-textobj-parameter', dependencies = {'kana/vim-textobj-user'}},

  -- オペレーター
  'kana/vim-operator-user',
  {'kana/vim-operator-replace', dependencies = {'kana/vim-operator-user'}},
  -- vim-surroundよりこっちの方が好き
  {'rhysd/vim-operator-surround', dependencies = {'kana/vim-operator-user'}},
})
```

dependenciesが無いとエラーになった。
これ、依存しているプラグインはすべて書かないといけないのだろうか？
ちょっと面倒なんだが...


```lua:~/.config/nvim/lua/keymap.lua
-- キーマップはここに集める
-- Leaderキーの設定
vim.g.mapleader = " "
vim.g.maplocalleader = " "

local keymap = vim.api.nvim_set_keymap
local opts = { noremap = true, silent = true }
local sopts = { silent = true }

keymap('n', "R", '<Plug>(operator-replace)', { noremap = true })
keymap('', "<Leader>sa", '<Plug>(operator-surround-append)', sopts)
keymap('', "<Leader>sr", '<Plug>(operator-surround-replace)', sopts)
keymap('', "<Leader>sd", '<Plug>(operator-surround-delete)', sopts)
keymap('n', "<Leader>srw", '<Plug>(operator-surround-replace)<Plug>(textobj-between-a)', sopts)
keymap('n', "<Leader>sdw", '<Plug>(operator-surround-delete)<Plug>(textobj-between-a)', sopts)

keymap("i", "jj", "<Esc>", opts)
```

キーマップは好きに設定したらよいと思う。
surround系はLeaderで開始しているが、いらん気がしている。
正直、sキーは使ってないので `viwsa"` とか `va"sr'` みたいに使えた方が楽じゃないかと思っている。
`s`も`c`も使ってないが、似たような機能だし`c`さえ生きていればきっと大丈夫。

最後にinit.luaにkeymapの読み込みを追加してnvimを再起動すればOKなはず。

```lua:~/.config/nvim/init.lua
require("temp")
require("plugin")
require("keymap")  -- 追加
```


### nvim-tree

これはサクッと導入できた。
試してないけど、dependenciesはきっと必須。

```lua:~/.config/nvim/lua/plugin.lua
require("lazy").setup({
  ...
  -- setupの最後に追加
  -- nvim-tree
  'nvim-tree/nvim-web-devicons',
  {
    'nvim-tree/nvim-tree.lua',
    dependencies = { 'nvim-tree/nvim-web-devicons' },
    config = function ()
      require('nvim-tree').setup()
      vim.api.nvim_create_user_command('Ex', function () vim.cmd.NvimTreeToggle() end, {})
    end
  },
})
```

### nvim-treesitter

TelescopeでOptional Dependenciesだったので入れる。

```lua:~/.config/nvim/lua/plugin.lua
require("lazy").setup({
  ...
  -- setupの最後に追加
  {
    'nvim-treesitter/nvim-treesitter',
    build = ":TSUpdate",
    config = function ()
      local configs = require("nvim-treesitter.configs")

      configs.setup({
        ensure_installed = {"c", "lua", "vim", "vimdoc", "javascript", "typescript"},
        sync_install = false,
        highlight = { enable = true },
        indent = { enable = true },
      })
    end,
  },
})
```
再起動時にluaファイルとかを開くとエラーが発生するが、languageのインストールが完了したら大丈夫なので、もう一度再起動する。

### coc.nvim

主流はBuiltIn-LSPのようだけど、めんどくさそうなのでCOCにする。

Node.jsが必要なので、[asdf-nodejs](https://github.com/asdf-vm/asdf-nodejs) で入れる。
[asdf](https://github.com/asdf-vm/asdf) のインストールは[公式ドキュメント](https://asdf-vm.com/guide/getting-started.html)の通り。

```zsh
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.13.1
echo '. "$HOME/.asdf/asdf.sh"' >> ~/.zshrc
source ~/.zshrc
asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
# 2023/12/08時点での最新Stableを入れる
asdf install nodejs 20.10.0
asdf global nodejs 20.10.0
# ついでにneovimパッケージも入れておく
npm i -g neovim
```

```lua:~/.config/nvim/lua/plugin.lua
require("lazy").setup({
  ...
  -- setupの最後に追加
  { 'neoclide/coc.nvim', branch = 'release' },
})
```
今すぐ使うわけではないので、エラーが出なければOK

---
Telescopeのインストールまで書こうと思ったけど力尽きたのでまた明日。