😎

Neovim & tmux に入門してElixirの開発環境を整えた

2022/03/12に公開

経緯

普段はVSCodeを利用しているのですが、最近業務で

  • 作業用のサーバーにsshで入る
  • backendの実装
  • frontendのコードの確認
  • 別プロジェクトのコードを眺める

などなど、プロジェクトを跨いだ作業が増えてきて、次のような課題感がありました。

  • VSCodeのwindowが大量に増える
    • workspaceの機能なり使えばマシになるのだろうけど、個人的には各リポジトリのrootでエディタを開きたい
  • 統合terminalとiTerm2で迷子になる
    • 適当にやると「どこで iex -S mix phx.server してたっけ」となる

そこで色々と調べていくうちに、vimmerになっていました(急)

この記事では試行錯誤した流れを残しておきたいと思います。

書くこと

  • neovim, tmuxをキャッチアップした流れ
  • 現在使っているプラグイン
  • 感想

書かないこと

  • tmuxやNeovimの詳細な説明
  • 各プラグインの設定方法の詳細

感想

先にvimに対する印象のbefore/afterをまとめてみます。

before

  • 設定大変そう
  • 玄人
  • キー操作で全部操作はしんどそう
  • VSCodeのクオリティまでは流石に厳しいか
  • Chrome拡張のVimiumは良い

after

  • 設定は確かに大変
    • ググると、lua言語を使った方法とvimscriptを使った方法がバラバラと出てくる。何も分からない
    • 大量のプラグインがあり、取捨選択がなかなか大変(awesome-neovim参照
    • ただ、自分に最適化されたエディタが出来上がっていく感じがとても楽しい
    • カスタマイズが好きではない人には厳しそう
  • キー操作だけじゃなくてマウスやカーソルでも操作可能なため意外と大丈夫
    • ちょっとこなれてきて、単語単位での削除などはパッと無意識に使えるようになってきた
  • tmuxとの組み合わせでVSCodeよりvimの方が良いというところまで来た
    • VSCodeで行いたい作業もまだある
  • vimそのものが本当に多機能
    • tab, window, quickfix, autocmd ... 知らない機能、用語がたくさん

参考にしたリソース

キャッチアップしていくにあたって参考にしたリソースをまとめます。

packer.nvim で Neovim + Lua のビッグウェーブに乗る

Neovimの導入〜plugin managementのpacker.nvimの導入を行いました。

プラグインを入れては動かし、採用/不採用のサイクルをまずは回せるようになったので良かったです。

https://qiita.com/delphinus/items/8160d884d415d7425fcc

Neovim IDE from Scratch

ほとんどこれでベースが整いました。英語ですがコード自体はリポジトリに上がっているため、英語が苦手でもコードを見ながら進める分には支障ないと思います。

などなどを導入し、リッチなエディタがどんどん出来ていきます。

YouTubeのvideoIDが不正ですhttps://www.youtube.com/playlist?list=PLhoH5vyxr6Qq41NFL4GvhFp-WLd5xzIzZ

lspconfigの導入動画では「言語ごとの設定は公式のserver_configurations.mdを見たら良い」という紹介があり、こちらにelixirlsの説明も載っています。

https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#elixirls

Vim as an Elixir IDE

ベースができたらElixir固有の設定を追加していきました。この記事が良かったです。

前述の動画では導入していないプラグイン(neoclide/coc.nvim)を導入しているため、適宜読み替えました。

https://subvisual.com/blog/posts/vim-elixir-ide

この記事で次のことが学べました。

  • ale を導入して保存時のformat, credoによるエラー表示
  • quickfix-reflector.vimを導入してプロジェクト内での全置換ができるように
    • Elixir固有の設定ではないが参考になりました

grep.app

記事や動画ではないのですが、grep.appをひたすら叩きまくっています。

冒頭の感想にて書いた通り、lua言語での設定方法とvimscriptでの設定方法が混在しており、何をどう設定したらよいかピンとこないことが多いです。

例えばelixirls をlua言語指定で検索するとdotfilesなどを公開している方のコードが参照できます。このように、プラグイン名等で検索しまくっています。

https://grep.app/search?q=elixirls&filter[lang][0]=Lua

tmuxを必要最低限で入門して使う

neovimの環境構築と並行して、tmuxも学習していきました。まずはこちらの記事で全体感を掴めました。

https://qiita.com/shin-ch13/items/9d207a70ccc8467f7bab

あとは「tmux 自動化」などでググると作業画面を一発で構築する方法がいくつか出てくるため、複数プロジェクトをセッション単位で自動起動するスクリプトを自作していっています。

https://dev.classmethod.jp/articles/tmux_create_devenv_display/

ide とコマンドを叩くと

  • zennの記事作業用のセッション作成
  • 上下にペイン分割
  • 各ペインで作業ディレクトリに移動
  • 上ペインでnvim起動
  • 下ペインで npx zenn preview 起動

といったのを作ってみました。

Image from Gyazo

ideという大層なaliasをつけていますが、以下の設定ファイルを tmux source しているだけです。今後育てていきたいと思います。

tmux.private.conf
# zenn
new-window -n zenn
split-window -v -p 20

send-keys -t zenn.0 'cd $(ghq root)/github.com/koga1020/zenn-articles; v .' C-m
send-keys -t zenn.1 'cd $(ghq root)/github.com/koga1020/zenn-articles; npx zenn preview' C-m

導入しているプラグイン

2022/03/12時点で導入したプラグインを貼っておきます。どれも便利で大変ありがたいです。
今も試行錯誤中ですのでまた入れ替わっていくと思います。

plugins.lua
vim.cmd([[packadd packer.nvim]])

-- Autocommand that reloads neovim whenever you save the plugins.lua file
vim.cmd([[
  augroup packaer_user_config
    autocmd!
    autocmd BufWritePost plugins.lua source <afile> | PackerSync
  augroup end
]])

return require("packer").startup(function(use)
	-- Packer can manage itself
	use("wbthomason/packer.nvim")

	-- Keybindings
	use("folke/which-key.nvim")

	-- Colorscheme
	use({ "projekt0n/github-nvim-theme" })

	-- Language
	use("elixir-editors/vim-elixir")

	-- Format & Linter
	use({ "ckipp01/stylua-nvim" })
	use("dense-analysis/ale")
	use("lukas-reineke/lsp-format.nvim")

	-- Fuzzy Finder
	use({ "junegunn/fzf" })
	use({
		"nvim-telescope/telescope.nvim",
		requires = { { "nvim-lua/plenary.nvim" } },
	})
	-- Completion & Snippet
	use("L3MON4D3/LuaSnip")
	use("hrsh7th/cmp-buffer")
	use("hrsh7th/cmp-cmdline")
	use("hrsh7th/cmp-path")
	use("hrsh7th/cmp-vsnip")
	use("hrsh7th/nvim-cmp")
	use("hrsh7th/vim-vsnip")
	use("hrsh7th/vim-vsnip-integ")
	use("rafamadriz/friendly-snippets")
	use("saadparwaiz1/cmp_luasnip")
	use("hrsh7th/cmp-nvim-lsp")

	-- LSP
	use("neovim/nvim-lspconfig")
	use("williamboman/nvim-lsp-installer")
	use("onsails/lspkind-nvim")

	-- Syntax
	use("nvim-treesitter/nvim-treesitter")
	use({
		"kyazdani42/nvim-tree.lua",
		requires = {
			"kyazdani42/nvim-web-devicons", -- optional, for file icon
		},
		config = function()
			require("nvim-tree").setup({})
		end,
	})

	-- Git
	use({
		"lewis6991/gitsigns.nvim",
		requires = { "nvim-lua/plenary.nvim" },
	})

	use({
		"tanvirtin/vgit.nvim",
		requires = {
			"nvim-lua/plenary.nvim",
		},
	})
	use("lambdalisue/gina.vim")
	use("ap/vim-buftabline")
	use({ "tyru/open-browser-github.vim", requires = { "tyru/open-browser.vim" } })

	-- Testing
	use("vim-test/vim-test")

	-- Projection
	use("tpope/vim-projectionist")

	-- Quickfix
	use("stefandtw/quickfix-reflector.vim")

	-- Terminal
	use({ "akinsho/toggleterm.nvim" })

	-- Comment
	use("terrortylor/nvim-comment")

	-- Statusline
	use("feline-nvim/feline.nvim")
end

今後格闘予定のネタ

かなり整ってきたため、今後格闘予定の細かいネタをリストアップしておきます。

elixir開発環境の強化

  • pipeの入力用のkeymap設定
  • snippetの整理

などなど、Elixirの開発しやすい環境を整えていきます。

snippetに関しては hrsh7th/vim-vsnip を導入し、VSCodeのsnippetを移植できます。自作した分や公開されているものなどを導入して便利にしていこうと思います。

https://github.com/hrsh7th/vim-vsnip

ファイルのdiff

翻訳活動をしていて、翻訳元のファイルと翻訳先のファイルのdiffをパッとみたい時にVSCodeの File: Compare Active File With... はとても便利です。これをvimでやるにはどうするかが検討ついていません。

https://atmarkit.itmedia.co.jp/ait/articles/1806/08/news028.html

PlantUML

VSCodeでのPlantUMLのプレビューは便利なので、これは代替案を検討したいです。この辺入れたらいいのかなと思いつつ、まだ試していません。

https://github.com/weirongxu/plantuml-previewer.vim

Statuslineの拡張

Statuslineを全然使いこなせていないです。
↑↑のプラグイン一覧に入っているfeline.nvimでbranch名の表示などそれっぽくなったのですが、拡張性があるとのことなので色々と試してみたいと思います。

まとめ

思い立ってからおよそ1週間、仕事終わりの時間をほぼnvimの学習(+マリオカート)に当てて一気に導入ができました。

VSCodeに戻ってしまうのか、はたまたひたすら育っていくのか、Elixirの開発環境として使ってみた状況を改めて別記事にしていきたいと思います。

Discussion