VSCode+Vim(.vimrc)からVSCode+NeoVim(lua)に移行してみた+プラグイン色々紹介
はじめに
zenn初投稿になります。
ある時ふとVimのを使いこなせるようになったら効率上がりそうだなと思い、一旦VScodeにVimの拡張機能を入れました。
しかしVim の拡張機能とは違い、NeoVimの拡張機能の方が実際に内部でNeoVimを動かすと書かれている記事を見かけ、なんか良さそうだと思って移行してみることにしました(?)。
自分と同じような考えに至った方の参考になれば幸いです。
ターゲット
- VSCodeでVimを使っていて
.vimrc
の蓄えがあり、NeoVimに移行するついでにluaにしたい人 - 初めてNeoVimのカスタマイズをしたくてコピペでもある程度使えるものを探してる人
- 良さげなプラグインを探してる人
ターゲットじゃないかもしれない人
- 記述されている設定やキーマップの意味を知りたい人
今回やったこと
- NeoVimのインストール
- VSCodeのNeoVim拡張機能のインストール
-
.vimrc
(init.vim
)をinit.lua
に書き換え - プラグインマネージャ(
wbthomason/packer.nvim
)の導入 - プラグインの導入
動作環境
M1 MacBook Air
MacOS Ventura 13.5.2
NeoVim 0.9.1
NeoVimのインストール
MacなのでHomebrewでインストールしました。他のOSを使用されている方はそれぞれ対応している方法でインストールしてください。
brew install neovim
VSCodeのNeoVim拡張機能のインストール
拡張機能のマーケットプレイスで「neovim」と調べて最上に出てくるであろう「VSCode Neovim」をインストールしました。
その後 VSCode に対して NeoVimPATH の設定をしました。
まずwhich nvim
で NeoVim のパスを調べ、NeoVim 拡張機能の設定に移り、"Executable Path"に先ほど調べたパスをコピペしました。
Darwin(MacOS)、Windows、Linuxとそれぞれ欄があると思うので自分のOSの欄にコピペしてください。
次に"NeoVim Init Vim Paths"にVimのInitファイルのパスを指定します。ここについては後述するので後でいいです。
.vimrc
(init.vim
)をinit.lua
に書き換え
最終的には以下のようなディレクトリ構造にしました。
init.vim.disabled
は以降元のinit.vim
ファイルで、読み込まれるのを防ぐ目的且つ、分かりやすくするために拡張子を.disabled
としました。特に意味はないです。自分がわかりやすければいいと思います。
coc-settings.json
とplugin/
はプラグイン導入の過程で勝手に出来上がるもので、こちらで作成するのはinit.lua
とlua/xxx.lua
のみになります。
nvim
├── coc-settings.json
├── init.lua
├── init.vim.disabled
├── lua
│ ├── keymaps.lua
│ ├── option.lua
│ ├── plugins.lua
└── plugin
└── packer_compiled.lua
まず~/.config/
にnvim
ディレクトリがあるかを確認します。自分の場合はなかったので作りました。
cd ~/.config
mkdir nvim && cd nvim
touch init.lua && mkdir lua
また違うディレクトリに.vimrc
がある場合は移動させるか標準出力で書き写しましょう。
移行する際にタブ分割で見ながらのほうが効率がおそらく良く、同ディレクトリ直下にあることで開きやすくなるためです。
自分の場合は当初luaに移行するのをめんどくさがっていたのでinit.vim
で標準出力をしました。
mv .vimrc ~/.config/nvim/
// or
cat .vimrc >> ~/.config/nvim/init.vim
次に、以下のサイトを参考にしながらinit.vim
の内容をluaに書き換えていきます。
そこで、今までは.vimrc(init.vim)
に全ての設定をぶちこんでいましたが、管理しやすくするためにファイルを分けることにします。それが先のxxx.lua
です。
まず大元となるinit.lua
を作成します。
touch init.lua
そして分けたファイルを読み込んでもらうために、以下のように記述します。
require ("plugins") -- プラグイン管理
require ("option") -- シンタックスハイライトやインデントなどの各種設定
require ("keymaps") -- キーマップ(キーバインド)の設定
init.vim
の該当部分とxxx.lua
との比較で示しますが、それぞれ以下のように書き換えました。
option
set title
set number
syntax on
set ruler
set smartcase
set cursorline
set shiftwidth=2
set tabstop=2
set hls
set clipboard=unnamed
set showmatch
set encoding=utf-8
set fileencodings=iso-2022-jp,euc-jp,sjis,utf-8
set fileformats=unix,dos,mac
local set = vim.opt
set.swapfile = false
set.helplang = "ja"
set.syntax = "on"
set.encoding = "utf-8"
set.title = true
set.number = true
set.ruler = true
set.smartcase = true
set.cursorline = true
set.shiftwidth = 2
set.tabstop = 2
set.hls = true
set.clipboard = "unnamed"
set.showmatch = true
set.fileencodings = "utf-8"
set.updatetime = 300
set.laststatus = 2
set.expandtab = true
set.autoindent = true
set.smartindent = true
keymaps
let mapleader = "\<Space>"
inoremap <silent> jj <Esc>
inoremap <silent> っj <Esc>
inoremap <C-j> <Down>
inoremap <C-k> <Up>
inoremap <C-h> <Left>
inoremap <C-l> <Right>
nnoremap あ a
nnoremap い i
nnoremap う u
nnoremap え e
nnoremap お o
nnoremap っd dd
nnoremap っy yy
noremap ;; $
inoremap { {}<LEFT>
inoremap [ []<LEFT>
inoremap ( ()<LEFT>
inoremap " ""<LEFT>
inoremap ' ''<LEFT>
noremap <S-h> 0
noremap <S-l> $
nnoremap <Leader>s :w<CR>
map <C-n> :NeoTreeShowToggle<CR>
nnoremap Y y$
vim.g.mapleader = "<Space>"
vim.keymap.set('i', 'jj', "<Esc>", { silent = true, noremap = true})
vim.keymap.set('i', 'っj', "<Esc>", { silent = true, noremap = true})
vim.keymap.set('i', '<C-j>', "<Down>", {noremap = true})
vim.keymap.set('i', '<C-k>', "<Up>", {noremap = true})
vim.keymap.set('i', '<C-h>', "<Left>", {noremap = true})
vim.keymap.set('i', '<C-l>', "<Right>", {noremap = true})
vim.keymap.set('n', 'あ', "a", {noremap = true})
vim.keymap.set('n', 'い', "i", {noremap = true})
vim.keymap.set('n', 'う', "u", {noremap = true})
vim.keymap.set('n', 'え', "e", {noremap = true})
vim.keymap.set('n', 'っy', "yy", {noremap = true})
vim.keymap.set('n', 'っd', "dd", {noremap = true})
vim.keymap.set('', ';;', "$", {noremap = true})
vim.keymap.set('i', '{', '{}<Left>', {noremap = true})
vim.keymap.set('i', '[', '[]<Left>', {noremap = true})
vim.keymap.set('i', '(', '()<Left>', {noremap = true})
vim.keymap.set('i', '\"', '\"\"<Left>', {noremap = true})
vim.keymap.set("i", "\'", "\'\'<Left>", {noremap = true})
vim.keymap.set('', '<S-h>', '0', {noremap = true})
vim.keymap.set('', '<S-l>', '$', {noremap = true})
vim.keymap.set('n', '<leader>s', ':w<CR>', {noremap = true})
vim.keymap.set('n', 'Y', 'y$')
vim.keymap.set("n", "<C-n>", ":NeoTreeShowToggle<Return>", {noremap = true, silent = true})
vim.keymap.set("n", "<C-j>", ":bnext<CR>", { silent = true, noremap = true })
vim.keymap.set("n", "<C-k>", ":bprev<CR>", { silent = true, noremap = true })
新たに追加した部分もありますが、このように書き換えられます。plugins.lua
はパッケージマネージャーの導入に伴い新たに作成したものですので移行するものはありません。
また、.vimrc
にはじめから関数が書かれている場合があるかと思います(自分の記憶では気づいた頃には勝手に書かれてました)。
それも移行しようかと考えたのですが、しなくても問題なく動いてそうだったのでしておりません。
ここまで設定したらこちらの"NeoVim Init Vim Paths"にinit.lua
のPATHを通しましょう。
VSCodeでのキーバインドの追加
VSCode上では一部動作しないキーバインドがあります。特にインサートモード中に使用するコマンド(<Esc>
→jj
など)は動作しません。そのためVSCode上でキーバインドの設定をする必要があります。
また、VSCodeのエクスプローラをNeoVimのファイラープラグインのように使いたい場合も一部こちらで設定する必要があります。
まず<Shift>+⌘+P
もしくは<Shift>+<Ctrl>+P
と押してコマンドパレットを開きます。
そこで「ショートカット」と検索して[基本設定: キーボードショートカットを開く(JSON)]を選択すると、キーバインドを設定するjsonファイルが開きます。ここで自身の好きなようにキーバインドの設定ができます。
自分は以下のように設定しています。
// 既定値を上書きするには、このファイル内にキーバインドを挿入します
[
// インサートモード中に"jj"でノーマルモードに抜ける
{
"command": "vscode-neovim.compositeEscape1",
"key": "j",
"when": "neovim.mode == insert && editorTextFocus",
"args": "j"
},
// インサートモード中にCtrl+hjklでノーマルモードと同じようにカーソル移動
{
"key": "ctrl+l",
"command": "cursorRight",
"when": "neovim.mode == insert && editorTextFocus"
},
{
"key": "ctrl+h",
"command": "cursorLeft",
"when": "neovim.mode == insert && editorTextFocus"
},
{
"key": "ctrl+j",
"command": "cursorDown",
"when": "neovim.mode == insert && editorTextFocus"
},
{
"key": "ctrl+k",
"command": "cursorUp",
"when": "neovim.mode == insert && editorTextFocus"
},
// エクスプローラ(左欄のファイル見れるやつ)から編集中ファイルにフォーカスを合わせる
{
"key": "ctrl+w l",
"command": "workbench.action.focusFirstEditorGroup",
"when": "listFocus && !inputFocus"
},
// ノーマルモード時行頭へ("0"と同じ)
{
"key": "shift+h",
"command": "cursorHome",
"when": "neovim.mode == normal && editorTextFocus"
},
// ノーマルモード時行末へ("$と同じ")
{
"key": "shift+l",
"command": "cursorEnd",
"when": "neovim.mode == normal && editorTextFocus"
},
// エクスプローラでファイル名変更
{
"key": "m r",
"command": "renameFile",
"when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
},
// フォーカスをエクスプローラ←→ファイル間で行き来
{
"key": "ctrl+n",
"command": "workbench.explorer.fileView.focus",
"when": "!filesExplorerFocus"
},
{
"key": "ctrl+n",
"command": "workbench.action.toggleSidebarVisibility",
"when": "filesExplorerFocus"
},
// エクスプローラでファイルコピー
{
"key": "m c",
"command": "filesExplorer.copy",
"when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
},
// エクスプローラでファイルペースト
{
"key": "m p",
"command": "filesExplorer.paste",
"when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
},
// エクスプローラでファイル新規作成
{
"key": "m a",
"command": "explorer.newFile",
"when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
},
// エクスプローラでファイル削除
{
"key": "m d",
"command": "deleteFile",
"when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
},
// エクスプローラでフォルダ新規作成
{
"key": "m f",
"command": "explorer.newFolder",
"when": "explorerViewletVisible && filesExplorerFocus && !inputFocus"
}
]
パッケージマネージャの導入
(Neo)Vimの有名なパッケージマネージャにはdein.vim
やpacker.nvim
などがありますが、今回はpacker.nvim
を採用しました。
リンク先のREADMEに記載がありますが、一応インストールコマンドを示しておくと、
git clone --depth 1 https://github.com/wbthomason/packer.nvim\
~/.local/share/nvim/site/pack/packer/start/packer.nvim
となります。plugins.lua
の雛形の記述を行いました。
vim.cmd.packadd "packer.nvim"
require("packer").startup(function()
-- Write plugins you wanna add below.
-- use "hoge/hoge-plugin"
use 'wbthomason/packer.nvim'
end)
こちらに導入したいパッケージのリポジトリ名を構文とともに載せてNeoVim内で:PackerInstall
とコマンドを打てば自動でインストールしてくれます。すごく楽で便利です。
尚、こいつはこのファイル内に記述がない導入済のプラグインは削除するかを問う旨のポップアップを出してきます、自爆を防ぐためにもuse 'wbthomason/packer.nvim'
と記述しましょう。自分はこのポップアップによくわからずY
と押してしまい再インスコする羽目になりました......。
おすすめプラグイン
kylechui/nvim-surround
kylechui/nvim-surround
は""
''
[]
{}
()
やHTMLタグ(<p>
)などの単語を囲む記号の編集をするコマンドを追加することができるプラグインです。
以下は上記のリンクから参照できるコマンド例を引用したものです。*
がカーソル位置になります。
Old text Command New text
-----------------------------------------------------------------------------
surr*ound_words ysiw) (surround_words)
*make strings ys$" "make strings"
[delete ar*ound me!] ds] delete around me!
remove <b>HTML t*ags</b> dst remove HTML tags
'change quot*es' cs'" "change quotes"
<b>or tag* types</b> csth1<CR> <h1>or tag types</h1>
delete(functi*on calls) dsf function calls
導入するためには以下の記述を追加します。
use({
"kylechui/nvim-surround",
tag = "*", features
config = function()
require("nvim-surround").setup({
})
end
})
おわりに
はい、以上になります。
「え?これだけ?」と思うかもしれませんが、VSCode上で使うだけであればこれだけで十分です。
このほかにもNeoVimにはカラースキームやファイラー、シンタックスハイライトを扱うプラグインが多数存在しますが、それらはVSCode上では意味を成さない上に、わざわざ導入せずともVSCodeにそのような機能はある程度あるためです。
一応そのようなプラグインもある程度導入してはいますが、自己満足でしかなくほとんど役には立っていません。
念の為、plugins.lua
の内容と、プラグイン探しの際に参考にしたサイトを次節に記しておきますので、興味がある方がいましたらどうぞ。
細かな解説ができませんで恐縮ですが、これからNeoVimに移行する・NeoVimに触れてみるという人の参考になれば幸いです。
かくいう自分もまだVimに目覚めてから日は浅く、使いこなせているかというと微妙なところです。Vimの成長曲線は急だと良く聞きますので、精進して参ります。
おまけ
vim.cmd.packadd "packer.nvim"
require("packer").startup(function()
-- Write plugins you wanna add below.
-- use "hoge/hoge-plugin"
use 'wbthomason/packer.nvim'
use "Shougo/ddc-around"
use 'Shougo/ddc.vim'
use 'vim-denops/denops.vim'
use "folke/tokyonight.nvim"
use "kdheepak/tabline.nvim"
use "tpope/vim-commentary"
use "dinhhuy258/git.nvim"
use {
"neoclide/coc.nvim",
branch = "release"
}
use({
"nvim-treesitter/nvim-treesitter",
run = ":TSUpdate",
})
use {
"nvim-lualine/lualine.nvim",
requires = { "nvim-tree/nvim-web-devicons", opt = true }
}
use {'kyazdani42/nvim-web-devicons'}
-- use("nvim-tree/nvim-web-devicons")
use {
"nvim-neo-tree/neo-tree.nvim",
branch = "v2.x",
requires = {
"nvim-lua/plenary.nvim",
"nvim-tree/nvim-web-devicons", -- not strictly required, but recommended
"MunifTanjim/nui.nvim",
}
}
use({
"kylechui/nvim-surround",
tag = "*", -- Use for stability; omit to use `main` branch for the latest features
config = function()
require("nvim-surround").setup({
-- Configuration here, or leave empty to use defaults
})
end
})
end)
Discussion