Neovimインストール＆セットアップ

最初に教えられたCUIエディタがviでした．そのままvi，vimと移って，モードやコマンドなど色々と覚えたことで私の手に馴染んでいるエディタです．
取っつきにくいかもしれないですが，あらゆるツールで疑似vimキーバインドが作られているように，慣れればキーボードだけで編集効率性は非常に高いと思っています．

vi，Vimと開発が進み，現在では[Neovim](https://neovim.io/)の開発が進められています．
積極的にモダンな機能を取り入れることや開発者人口を増やすことを方針としてvimから切り分けたようですね．VimはBram氏がほとんど一人で管理してきたというのも驚きですが，VSCodeやCursorなどと強力なGUIエディタが犇めき合う中でやはりモダンな機能をvimをエンジンとしたエディタで扱いたいなと思い，数年 Neovim を使い続けています．

ただそのままインストールしても設定が大変なので，今回は簡単にセットアップできる方法を紹介するのと，セットアップまでの作業を記録する目的で記事を残そうと思います．

## 環境
- Ubuntu 24.04.01 LTS
- fish 4.0.2

## Neovim インストール
インストール方法はいくつか用意されていますが，[AppImage ("universal" Linux package)](https://github.com/neovim/neovim/blob/master/INSTALL.md#appimage-universal-linux-package)で進めます．

```shell
curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.appimage
chmod u+x nvim-linux-x86_64.appimage
./nvim-linux-x86_64.appimage
```

特に問題なく以下のように実行できました．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36125/85143d55-b108-4084-a007-9edefa96d01c.png)

> If the ./nvim-linux-x86_64.appimage command fails, try:

実行できない場合の対処方法も用意されているようです．
```shell
./nvim-linux-x86_64.appimage --appimage-extract
./squashfs-root/AppRun --version

# Optional: exposing nvim globally.
sudo mv squashfs-root /
sudo ln -s /squashfs-root/AppRun /usr/bin/nvim
nvim
```

実行ファイルは下記のように共有場所にNeovim用のディレクトリを用意しました．
```shell
mkdir -p /opt/nvim/bin
mv nvim-linux-x86_64.appimage /opt/nvim/bin/nvim
chmod 755 /opt/nvim/bin/nvim
```

私はfishユーザなので以下のように実行ファイルのパスを通しました．
```shell
fish_add_path /opt/nvim/bin/nvim
```

以上でインストール完了です．

## Neovimセットアップ（LazyVim）
Vimのプラグインは大方互換性があり，NodeやPythonで作成されたNeovimプラグインも豊富に存在します．豊富にあることは嬉しいことですが，プラグインを個別に設定するには時間がかかります．開発のためにある程度便利な機能を備えた状態からスタートしたいですよね．

LazyVimはインスタントに必要なプラグインを導入し，基本設定を反映してくれるツールです．もちろんカスタマイズ可能なので，導入後にキーバインドの変更やプラグインの追加などが可能です．

### LazyVim Starter
LaziVimのテンプレートプロジェクトの[LazyVim Starter](https://github.com/LazyVim/starter)を利用して，インストールを進めていきます．

```shell
# NeoVimを利用している場合は必要
mv ~/.config/nvim ~/.config/nvim.bak
mv ~/.local/share/nvim ~/.local/share/nvim.bak

git clone https://github.com/LazyVim/starter ~/.config/nvim
rm -rf ~/.config/nvim/.git
nvim
```

NeoVimを起動するとプラグインのインストールが始まります．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36125/b9d6cad7-0871-4b42-8bfb-e2f6385efeb3.png)

パッケージのインストールが終わるとデフォルトのカラースキーマが適用されて見た目が大きく変更されました．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36125/31269425-2faa-457a-9646-53ac499401cf.png)

起動画面にデカデカとLazyVimと主張してくるのが好まない方はプラグインの導入で変更できたかと思います．

### LazyVimの動作確認
LazyVimが正しく動作する状況か確認します．必要なツールがインストールされていない場合はインストールしていきますが，必要なツールは[LazyVimのドキュメントページ](https://www.lazyvim.org/#%EF%B8%8F-requirements)に記載されています．

LazyVimの状態確認を行います（`:LazyHealth`）．
WARNINGやERRORとなっている箇所を解消していきますが，初めてインストールして私と環境が同じであれば下記の通りインストールすると楽かもしれません．

| error/warning | インストール手順 | 参考ページ |
|:-:|:-:|:-:|
| gcc | `sudo apt install gcc` | [LinuxCapable.com](https://linuxcapable.com/how-to-install-gcc-compiler-on-ubuntu-linux/)
| rg | `sudo apt install ripgrep` | [GitHub](https://github.com/BurntSushi/ripgrep?tab=readme-ov-file#installation) |
| lynx  | `sudo apt install lynx` | [Lynx HP](https://lynx.invisible-island.net/) |
| ast-grep  | `npm i @ast-grep/cli -g` | [ast-grep HP](https://ast-grep.github.io/guide/quick-start.html) |
| luarocks | `apt install luarocks` | [GitHub](https://github.com/luarocks/luarocks/blob/main/docs/installation_instructions_for_unix.md) |
| fd-find | `apt install fd-find` | [GitHub](https://github.com/sharkdp/fd?tab=readme-ov-file#installation) |
| lazy-git | [lazygit インストール](https://qiita.com/41ef04241c8168fb960e/#lazygit-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB) | [GitHub](https://github.com/jesseduffield/lazygit?tab=readme-ov-file#debian-and-ubuntu) |
| fzf | `apt install fzf` | [GitHub](https://github.com/junegunn/fzf?tab=readme-ov-file#linux-packages) |
| Go | `apt install golang` | [Go HP](https://go.dev/doc/install) |
| Composer | `apt install composer` | [Composer HP](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos) |
| PHP | `apt install php` | [PHP HP](https://www.php.net/manual/ja/install.unix.debian.php) |
| Cargo | `apt install cargo` | [Cargo Book](https://doc.rust-lang.org/cargo/getting-started/installation.html) |
| Ruby | `apt install ruby` | [Ruby HP](https://www.ruby-lang.org/ja/downloads/) |
| Java | `apt install openjdk-21-jdk` | [OpenJDK HP](https://openjdk.org/index.html) |
| Julia | - | [Julia HP](https://julialang.org/) |
| RubyGems | `apt install ruby` | [RubyGems](https://github.com/rubygems/rubygems?tab=readme-ov-file#installation) |
| tree-sitter | `npm install tree-sitter-cli -g` | [GitHub](https://github.com/tree-sitter/tree-sitter/tree/master/cli) |
| wezterm | [WezTermインストール](https://qiita.com/41ef04241c8168fb960e/edit#wezterm-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB) | [WezTerm HP](https://wezterm.org/install/linux.html#__tabbed_1_3) |
| Imagemagick | [ImageMagickインストール](https://qiita.com/41ef04241c8168fb960e/edit#imagemagick%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB) | [ImageMagick HP](https://imagemagick.org/script/download.php) |
| SQLite3 | `sudo apt install sqlite3` | [SQLite3 HP](https://sqlite.org/download.html) |
| Node.js provider | `npm install neovim -g` | - |
| Python provider | [Python providerの準備](https://qiita.com/41ef04241c8168fb960e/#python-provider%E3%81%AE%E6%BA%96%E5%82%99) | - |


現状必要そうなものを準備しました．その作業をそれぞれ各項目に分けて記録しておきます．

#### lazygit インストール
```shell:lazygit
LAZYGIT_VERSION=$(curl -s "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" | \grep -Po '"tag_name": *"v\K[^"]*')
curl -Lo lazygit.tar.gz "https://github.com/jesseduffield/lazygit/releases/download/v${LAZYGIT_VERSION}/lazygit_${LAZYGIT_VERSION}_Linux_x86_64.tar.gz"
tar xf lazygit.tar.gz lazygit
sudo install lazygit -D -t /usr/local/bin/

fish_add_path /usr/local/bin/
```

#### WezTerm インストール
```shell:WezTerm
curl -fsSL https://apt.fury.io/wez/gpg.key | sudo gpg --yes --dearmor -o /usr/share/keyrings/wezterm-fury.gpg
echo 'deb [signed-by=/usr/share/keyrings/wezterm-fury.gpg] https://apt.fury.io/wez/ * *' | sudo tee /etc/apt/sources.list.d/wezterm.list
sudo chmod 644 /usr/share/keyrings/wezterm-fury.gpg

sudo apt update
sudo apt install wezterm
```

#### ImageMagickインストール
```shell:Imagemagick
sudo apt install libpng-dev libjpeg-dev libtiff-dev
sudo apt install imagemagick
```

#### Python providerの準備
```shell:Python Provider
# pyenv インストール
PYENV_GIT_TAG=v2.5.7 curl -fsSL https://pyenv.run | bash
set -Ux PYENV_ROOT $HOME/.pyenv
fish_add_path $PYENV_ROOT/bin
echo "# pyenv start" >> ~/.config/fish/config.fish
echo "pyenv init - fish | source" >> ~/.config/fish/config.fish
echo "# pyenv end" >> ~/.config/fish/config.fish


# 必要なツールをインストール
sudo apt update; sudo apt install build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl git \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev

# pyenv-virtualenv インストール
git clone https://github.com/pyenv/pyenv-virtualenv.git (pyenv root)/plugins/pyenv-virtualenv


pyenv install 3.13 # *1
pyenv virtualenv 3.13.3 py3nvim
pyenv activate py3nvim
pip install pynvim
pyenv which python # 出力: ~/.pyenv/versions/py3nvim/bin/python

PYTHONPATH=(pyenv which python) echo "vim.g.python3_host_prog = '$PYTHONPATH'" >> ~/.config/nvim/lua/config/options.lua
```
この作業で私は以下のエラーが発生したので以下を参考に対処しました．ツールが足りなかったためでした．
- *1 [ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?](https://github.com/pyenv/pyenv/wiki/Common-build-problems#error-the-python-ssl-extension-was-not-compiled-missing-the-openssl-lib)

#### その他パッケージ
必要なものがあればまた追記します．

### 開発用プラグインの導入（Lazy Extras）
LazyExtraは目的に合わせたプラグインセットをインストールしてくれる優れものです．
各種プラグインの依存関係を考えながら導入するのは本当に大変なので，プリセットが用意されているのは助かります．

起動時の画面であれば "x" を，いずれの画面からでもコマンド ":LazyExtras" でインストーラを呼び出せます．VSCodeにおける"Extensions Marketplace"のようなものです．

最初は以下の三つがインストールされているようです．
- coding.blink
- editor.snacks_explorer
- editor.snacks_picker
これら名称はプリセット名で，右側に一緒にインストールされるプラグイン一覧が列挙されています．プラグイン名で調べてどのような機能を提供してくれるのかGitHubリポジトリを確認するといいと思います．
また，カテゴライズされており，プレフィックス（coding.*, editor.*, etc.）で何関連のプラグインなのか粗方判別がつきます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36125/081528d8-ea0d-4c03-823e-605481175467.png)

基本的に以上を活用すれば自分専用のNeoVimを構成することができます．AI機能を導入する過程を例として挙げたいと思います．

### Copilot & Copilot Chat
NeoVim上でAIに質問しながらコーディングできるように機能追加してみましょう．
AI関連機能は現状，以下が存在するようです．
- ai.codeium
- ai.copilot
- ai.copilot-chat
- ai.supermaven
- ai.tabnine

#### インストール
私はCopilotを利用しているので "ai.copilot" と "ai.copilot-chat" をインストールしますが，無料で使える "ai.codeium" もおすすめです．

LazyExtras で必要なパッケージまでカーソルを移動させ`x`を入力すればインストールが実行されます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36125/2b400c6f-7198-492d-8ef0-5bd3ff620035.png)

LazyExtrasを終了し（`q`），プラグインを利用してみます．Copilotの利用にはライセンスが必要な為，まずは認証作業を実施します．

#### 認証
`:Copilot auth`を実行し，GitHubアカウントと連携します．連携のためURLが表示されるので，Neovim 上に表示されているコードをブラウザに入力すれば完了です！


#### Copilot
ai.copilotは補完候補に Copilot の提案が表示されるようになります．
例えば以下のようなコードで関数を定義しようとすると
```python

if __name__ == "__main__":
    main()
```

以下の画像の通り，main関数の定義が候補に出てきます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36125/ced5ff65-9d29-4e96-aa27-cc83c7db4591.png)

#### Copilot Chat
エディタで開発しながら，ブラウザでChatGPTやGeminiなどに質問して，またエディタに戻ってというような開発をしていると，ウインドウの切り替えや，コードのコピペが面倒だったりしますよね．そういった面倒くささを課題の一つにCursorのようなAI搭載型エディタが登場しましたが，エディタ内でひとまずQAできれば楽ですね．

ai.copilot-chatはウィンドウを分けてチャット用パネルが表示されるようになります．
`:CopilotChat` を入力すると右側のパネルが表示されます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36125/65773a88-b08c-47de-9bd6-3f16487068ea.png)

質問を入力すればその内容に準じたコードを生成してくれますし，左側のソースコードの選択箇所ないしは全体を指して質問やリファクタリングをさせたりすることができます．ただ，直接編集されるわけではないので自分で採用するコードは右パネルからヤンクして該当箇所にペーストする必要があります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36125/acd342f5-164d-41a6-8440-3dde0764913f.png)

また，文頭に'$'を入力すると使用するLLMモデルを切り替えることができますので，内容に応じて切り替えるのも容易です．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36125/148b5813-5762-4cbf-8db5-5752c4b354ce.png)

さらに，'#'を入力するとプロンプトに詰めたい情報を指定することができます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36125/b385d181-0649-4ed8-8ea7-4c7d160ab5cb.png)

Neovim上で表示されている内容は全てバッファに文字列情報が読み込まれているため，コピーせずとも，このようにコンテキストを指定することができます．

## まとめ
新しいPCにインストールする度，セットアップを調べているのでまとめておきました．NeovimやLazyVimのバージョンが更新され，セットアップ方法に変更があれば追記・更新しようと思います．