Open57

Vim から Neovim に移行 && 入門した雑記録

skinnybrianskinnybrian

React + TypeScript を書くようになり初めてから、普段使ってた Vim だと特に LSP の設定とかせずただのデバッガーで確認しながらやってたので、LSP もしっかりしてそうでずっと気になってた Neovim に入門することにした。フロントエンドでも Vim 使ってる人がたくさんいたことによる安心感もある。

いつも使ってた Vim も共存しながら扱っていこうと思うので、ついでに Neovim 向けに 設定ファイルも全部 Lua で書いていくことを目指す💪

skinnybrianskinnybrian

Homaju さんのブログの Vim 記事役に立ちすぎる…ずっと読んでる

skinnybrianskinnybrian

キーマップの設定で学びがあったのでメモ。

どうやら Neovim には現状 2 種類のキーマップの設定があるらしい

結論

vim.keymap.set を使う

Vim の場合

例えば Vim の Insert モードから Normal モードに抜ける時大体 Esc キーをタイプするが、キーボード的に Esc キーは割と遠い位置にあるのでので僕はホームポジションをキープしながら jj とタイプすることでいつも Normal モードから抜けている。その時の Vim における設定は以下のように書く。

.vimrc
inoremap <silent> jj <ESC>

Neovim の場合

これを例にして Neovim で Lua を使って表現する場合、現状 2 パターンの書き方がある。

1. vim.api.nvim_set_keymap を使う

init.lua
vim.api.nvim_set_keymap('i', 'jj', '<ESC>', { noremap = true, silent = true })

https://neovim.io/doc/user/api.html#nvim_set_keymap()

2. vim.keymap.set を使う

init.lua
 vim.keymap.set('i', 'jj', '<ESC>', { noremap = true, silent = true})

https://neovim.io/doc/user/lua.html#vim.keymap.set()

以上の 2 パターンがあるが、直近の commit や Reddit の議論を読むに、vim.api.nvim_set_keymap が v0.5 時代に作られた書き方に対し、vim.keymap.set が比較的新しいキーマップの書き方のよう。個人的にはvim.api.* がかなり冗長してきているのもあるから、キーマップ部分切り離したのではくらいの気持ちで解釈している。なので後者を採用することとする。

参考

https://homaju.hatenablog.com/entry/2022/06/10/081205
https://github.com/neovim/neovim/commit/6d41f65aa45f10a93ad476db01413abaac21f27d
https://www.reddit.com/r/neovim/comments/uuh8xw/noob_vimkeymapset_vs_vimapinvim_set_keymap_key/
https://mitubaex.hatenablog.com/entry/2021/05/06/185019

skinnybrianskinnybrian

Vim のキーバインドに絶対慣れる!!という強い意志で、 .vimrc

.vimrc
" 方向キー無効化
noremap <Up> <Nop>
noremap <Down> <Nop>
noremap <Left> <Nop>
noremap <Right> <Nop>

って書いてたけど、実際本当に使わなくなったのと、なんかの拍子で矢印キーしか使えない状況がある(?)ときに不便なので、これは Neovim の設定ファイルに書かないことにした。

(だけど、読者が入門 Vimmer で未だに矢印キー使っちゃう!って人は、この方向キー無効化の縛りプレイは控えめに言って結構ありですw)

ちなみにこれを Neovim(Lua) で書くなら

-- 方向キー無効化
vim.keymap.set('', '<Up>', '<nop>')
vim.keymap.set('', '<Down>', '<nop>')
vim.keymap.set('', '<Left>', '<nop>')
vim.keymap.set('', '<Right>', '<nop>')

ちなみに map 系のコマンドの違いはまだ微妙に理解してない()

参考
https://yellowring.hatenablog.jp/entry/2015/03/08/152351

skinnybrianskinnybrian

ついに Plugin 系の導入にはいったが、いろいろ設定書いたりするの眺めててもわけわからんってなったのでとりあえず雑に入れることにするw

skinnybrianskinnybrian

fzf テンション上がる!!!!!

こんな感じで使うやつ一旦割り当ててみた

init.lua
vim.g.mapleader = " "
vim.keymap.set('n', '<leader>F', "<cmd>lua require('fzf-lua').files()<CR>")
vim.keymap.set('n', '<leader>b', "<cmd>lua require('fzf-lua').buffers()<CR>")
vim.keymap.set('n', '<leader>f', "<cmd>lua require('fzf-lua').git_files()<CR>")
vim.keymap.set('n', '<leader>g', "<cmd>lua require('fzf-lua').live_grep()<CR>")

mapleader まともに使ってなかったけど、スペースでやるのめっちゃいいな

skinnybrianskinnybrian

coc-nvim を導入しようと思ってるけど、これを導入するのに lazy.nvim で導入してる人がぜんぜん見つからない。もしやみんな別のパッケージマネージャーつかってるのかな

skinnybrianskinnybrian

普通にいけた。雑だけどひとまず

init.lua
require("lazy").setup({
  {
    'neoclide/coc.nvim'
  }
})

でうまくいった

skinnybrianskinnybrian

Neovim の表示言語を英語にしたくてそれ用の Neovim コマンドあるかなって思ったけど探せなかった()なので無難にこれは vim.cmd()

init.lua
vim.cmd('language C')

でうまくいった

skinnybrianskinnybrian

なに!? latn1 って文字コード初めて知ったんだけど!?これが原因かあああ

skinnybrianskinnybrian

.tsx ファイルのコメントアウトが便利になる nvim-ts-content-commentstring を入れた時にハマったメモ
https://github.com/JoosepAlviste/nvim-ts-context-commentstring

前提として、コメントアウトを行う Plugin として Comment.nvim を採用している。
https://github.com/numToStr/Comment.nvim
※一応こちらの README.md にも手順が追加されているのでそちらもご参考まで。


まず nvim-treesitter と依存関係にあるので、必ず入れる
https://github.com/nvim-treesitter/nvim-treesitter

その後、 nvim-treesitter の設定で tsx をインストールするように ensure_installed に追記しておく。
以下は lazy.nvim での書き方の場合。

init.lua
require("lazy").setup({
  {
    'nvim-treesitter/nvim-treesitter',
    event = {'BufNewFile', 'BufRead'},
    build = ":TSUpdate",
    config = function()
      local configs = require("nvim-treesitter.configs")
      configs.setup({
        ensure_installed = { "c", "lua", "vim", "vimdoc", "query", "elixir", "heex", "typescript", "javascript", "tsx", "html", "markdown" },
        sync_install = false,
        highlight = { enable = true },
        indent = { enable = true },
      })
    end
  }
})

これで tsx の構文解析ができるようになる。 nvim-treesitter の説明はここでは割愛。こちらの記事がとても参考になった。
https://zenn.dev/duglaser/articles/c02d6a937a48df

これを踏まえて、 nvim-ts-content-commentstring の Wiki に書かれてある手順に沿って更に設定を追記する。

init.lua
require('ts_context_commentstring').setup {
  enable_autocmd = false,
}
require('Comment').setup {
  pre_hook = require('ts_context_commentstring.integrations.comment_nvim').create_pre_hook(),
}

これで無事に tsx ファイルで JS 部分と HTML 部分でそれぞれコメントアウトが効くようになった💯

skinnybrianskinnybrian

そーろそろ init.lua がまったく init なファイルじゃなくなってきてるのでリファクタするか〜

skinnybrianskinnybrian

nvim-lspconfig っていつ使うんやろって思ったけど、多分 coc-nvim つかってるうちはそっちで大丈夫?って解釈でええんかな?🤔

skinnybrianskinnybrian

この方の Lua ファイルのファイル構造めちゃくちゃ参考になるメモ
https://github.com/catgoose/nvim/tree/main