Neovim設定記録
正月だし Neovim の設定を Lua で書き直そうと思ったので、せっかくなので zenn のスクラップも試してみることに。
移行元の vimrc
昔は2000行近くあったvimrcも、何度か整理しているうちに500行を切っていたし、しかも使ってない設定も多い。
dotfiles に nvim ディレクトリを作って ~/.config/nvim
にシンボリックリンクを作った。
nvim/init.lua
を作りつつ、今までのvimrcは削除。
まずはキーマップを移植した。
vim.keymap.set
を使うといいらしい。
vim.g.mapleader = ","
-- ; : の入れ替え
vim.keymap.set('n', ';', ':')
vim.keymap.set('n', ':', ';')
-- <C-l> を ESC に
vim.keymap.set({'v', 'i', 'c'}, '<C-l>', '<ESC>')
vim.keymap.set('n', '<C-l>', ':nohlsearch<CR>')
-- 移動
vim.keymap.set({'n', 'v'}, 'J', '10j')
vim.keymap.set({'n', 'v'}, 'K', '10k')
vim.keymap.set({'n', 'v'}, 'H', '10h')
vim.keymap.set({'n', 'v'}, 'L', '10l')
-- 保存
vim.keymap.set('n', '<SPACE>w', ':write<CR>')
-- Qキーをマクロに
vim.keymap.set('n', 'q', '<NOP>')
vim.keymap.set('n', 'Q', 'q')
-- s を 画面移動系のprefixに
vim.keymap.set('n', 's', '<NOP>')
vim.keymap.set('n', 'sq', ':quit<CR>')
-- 分割
vim.keymap.set('n', 'ss', ':sp<CR>')
vim.keymap.set('n', 'sv', ':vs<CR>')
-- 分割移動
vim.keymap.set('n', 'sj', '<C-w>j')
vim.keymap.set('n', 'sk', '<C-w>k')
vim.keymap.set('n', 'sh', '<C-w>h')
vim.keymap.set('n', 'sl', '<C-w>l')
vim.keymap.set('n', 'sJ', '<C-w>J')
vim.keymap.set('n', 'sK', '<C-w>K')
vim.keymap.set('n', 'sH', '<C-w>H')
vim.keymap.set('n', 'sL', '<C-w>L')
-- タブページ
vim.keymap.set('n', 'st', ':tabnew<CR>')
vim.keymap.set('n', 'sn', 'gt')
vim.keymap.set('n', 'sp', 'gT')
vim.keymap.set('n', 'sN', ':tabmove +1<CR>')
vim.keymap.set('n', 'sP', ':tabmove -1<CR>')
-- 編集支援系
vim.keymap.set('n', '<CR>', 'o<ESC>')
vim.keymap.set('n', '<SPACE>d', 'cc<ESC>')
- Leader は
,
- 主にプラグイン関連のマッピングのプレフィックスにしてる
- 英字キーボードなので
:
;
を入れ替えてる -
<C-l>
を Esc の代わりに使う - JKHL で多めに移動できるように。
- shift押して強化するイメージで、結局高速移動系のプラグインを入れてもこれあるから使わなくなりがち
- 分割・タブ系を
s
を prefix にしたしたマッピングに
もっと色々設定してた気もするけど、プラグイン系を除くとこれくらいだった。
コマンドを読んでいる系のマッピングに {silent = true}
を足した。
オプション系
-- カーソルを真ん中に
vim.o.scrolloff = 999
-- 行番号表示
vim.o.number = true
vim.o.relativenumber = true
-- 現在行・列を強調
vim.o.cursorline = true
vim.o.cursorcolumn = true
-- 各種ファイルを生成しない
vim.o.autoread = true
vim.o.backup = false
vim.o.writebackup = false
vim.o.swapfile = false
vim.o.undofile = false
-- 改行文字表示
vim.o.list = true
vim.o.listchars = 'tab:¦ ,eol:↴,trail:-,nbsp:%,extends:>,precedes:<'
-- 検索
vim.o.ignorecase = true
vim.o.smartcase = true
vim.o.wrapscan = true
vim.o.incsearch = true
-- 新しいウィンドウを下に開く
vim.o.splitbelow = true
-- クリップボード
vim.o.clipboard='unnamedplus'
-- タブ関連
vim.o.expandtab = true
vim.o.tabstop = 2
vim.o.shiftwidth = 2
vim.o.softtabstop = 2
vim.o.autoindent = true
vim.o.smartindent = true
relativenumber を on にしたり、cursorline だけじゃなく cursorcolumn も有効にしてるのはちょっと変わってるかもしれない。
プラグイン管理は packer.nvim
を採用した
推奨通り plugin 関連の設定は nvim/lua/plugins.lua
にまとめるようにして plugin.lua の更新時に :PackerCompile
を実行するような設定を追加した。
単なるコピペになるので割愛。
テーマはとりあえず元々使ってた iceberg
を採用。
vim-hybrid とか Solarized とかを使ってたことを思い出した。
比較的単機能なプラグインの内、今も使っているなというものをとりあえず引き続き使うことに。
use 'mattn/vim-findroot'
use 'jiangmiao/auto-pairs'
use 'mhinz/vim-signify'
use 'cohama/vim-insert-linenr'
use {
'tpope/vim-commentary',
setup = function()
vim.keymap.set('n', 'CC', 'gcl', {remap = true})
vim.keymap.set('', 'C', 'gc', {remap = true})
end,
}
-- textobj系
use 'kana/vim-textobj-user'
use 'kana/vim-textobj-entire'
use 'kana/vim-textobj-indent'
use 'kana/vim-textobj-line'
-- operator系
use 'kana/vim-operator-user'
use {
'kana/vim-operator-replace',
setup = function()
vim.keymap.set('v', 'p', '<Plug>(operator-replace)')
vim.keymap.set('', 'R', '<Plug>(operator-replace)')
end,
}
use {
'tyru/operator-camelize.vim',
setup = function()
vim.keymap.set('', '<leader>c', '<Plug>(operator-camelize)')
vim.keymap.set('', '<leader>C', '<Plug>(operator-decamelize)')
end,
}
プラグインに関する設定も一緒に書くように。
この時点までプラグインの設定以外はすべて init.lua
に書いていたがファイルを分けることに。
そのために、とりあえず fuzzy-finder 系のプラグインを入れてファイルを分けてもサクッと開けるように。
telescope を採用してみた。
設定は次の通り。
use {
'nvim-telescope/telescope.nvim', tag = '0.1.0',
requires = { {'nvim-lua/plenary.nvim'} },
config = function()
local builtin = require('telescope.builtin')
vim.keymap.set('n', '<leader>uf', builtin.find_files)
vim.keymap.set('n', '<leader>ub', builtin.buffers)
vim.keymap.set('n', '<leader>uh', builtin.help_tags)
vim.keymap.set('n', '<leader>ug', builtin.live_grep)
require('telescope').setup{
defaults = {
mappings = {
i = {
["<C-l>"] = "close"
}
}
}
}
end,
}
<leader>
をプラグイン系マッピングのプレフィックスにしている。
<leader>u
にしているのは、最初にこれ系で使ったのが Unite.vim で、その名残で u
キーを当てている。
<C-l>
を Esc
の代わりにしているので telescope も同じように閉じれるように。
とりあえずで入れたが、動作も軽快で良さそう。
ハイライト関連として
を入れた。
どっちかだけで良い……? あとで他の人の導入してるプラグイン例とかを見てみる。
とりあえず元々入れてたので導入。
status line 変更系プラグインとして lualine.nvim` を入れた
ほとんどデフォルトの設定だけど、アイコンは使わない設定にした。
use {
'nvim-lualine/lualine.nvim',
config = function()
require('lualine').setup {
options = {
icons_enabled = false,
theme = 'auto',
component_separators = { left = '', right = ''},
section_separators = { left = '', right = ''},
always_divide_middle = true,
globalstatus = false,
},
sections = {
lualine_a = {},
lualine_b = {'branch', 'diff', 'diagnostics'},
lualine_c = {{'filename', path = 1}},
lualine_x = {'filetype'},
lualine_y = {},
lualine_z = {'location'}
},
inactive_sections = {
lualine_a = {'diff'},
lualine_b = {{'filename', path = 1}},
lualine_c = {},
lualine_x = {},
lualine_y = {},
lualine_z = {'location'},
},
}
end,
}
……と、ここまでは振り返りつつ書いてみた。
何やったかメモるか→どうせメモるならあとでブログにしてみようか→zennのスクラップあったからそれでいいや
みたいな理由。
公開してもいいような作業工程を残すのに良いなと思ったので、飽きなければ続けます。
導入。最近開いたファイルを開く。 file_mru 的な。
一時メモ用のコマンドを追加。
vim.api.nvim_create_user_command
でユーザーコマンドを定義できた。
vim.api.nvim_create_user_command('Inbox', 'edit ~/.inbox.md', {})
vim.api.nvim_create_user_command('Temp', 'edit ~/.vim_tmp/tmp.<args>', {nargs = 1})
:Inbox
でメモファイルを開く。一時的な作業領域的な扱い。
:Temp <拡張子>
で言語別のメモファイル。
最近使ってなかったものの、設定作業とかしてると欲しくなるので再度設定した。
昔は Dropbox 管理化に置いて複数PC間で見れるようにしていたけど、今まともに vim を使っているPCが一台だしそもそも Dropbox をほとんど使っていないのでなしで。
ユーザーコマンドを定義した流れで vim-ambicmd
を導入。
use {
'thinca/vim-ambicmd',
setup = function()
vim.keymap.set('c', '<space>', [[ambicmd#expand("\<Space>")]], {expr = true})
vim.keymap.set('c', '<CR>', [[ambicmd#expand("\<CR>")]], {expr = true})
end,
}
すっかり手に馴染んでてデフォルトの挙動だと思っていた。
require がキャッシュするので再読み込み時にキャッシュをクリアするようにした。
init.lua
setting_files = {
'core',
'keymap',
'commands',
'plugins',
}
for _, value in ipairs(setting_files) do
require(value)
end
keymap.lua (一部)
vim.keymap.set('n', '<SPACE>.r', function()
for _, value in ipairs(setting_files) do
package.loaded[value] = nil
end
vim.cmd(':source ' .. init_path)
end)
マッピングを消したりしたときは素直に再起動で。
Packer の autocmd の設定を vim.api.nvim_create_autocmd
を使うように書き換え。
ついでに PackerInstall, PackerClean を実行するようにした。
vim.api.nvim_create_augroup('packer_user_config', {})
vim.api.nvim_create_autocmd('BufWritePost', {
group = 'packer_user_config',
pattern = {"plugins.lua"},
callback = function()
vim.cmd('source ' .. vim.fn.expand("%"))
vim.cmd('PackerCompile')
vim.cmd('PackerInstall')
vim.cmd('PackerClean')
end,
})
git の差分表示を gitsigns.nvim に乗り換えた
ついでに signcolumn を常に表示するように設定
vim.o.signcolumn = 'yes'
↑をベースにしつつ最低限 LanguageServer を使って補完できるようにした。
use {
'neovim/nvim-lspconfig',
config = function()
vim.keymap.set('n', 'gk', '<cmd>lua vim.lsp.buf.hover()<CR>')
vim.keymap.set('n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>')
vim.keymap.set('n', 'gt', '<cmd>lua vim.lsp.buf.type_definition()<CR>')
end,
}
use {
'williamboman/mason.nvim',
config = function()
require('mason').setup()
end,
}
use {
'williamboman/mason-lspconfig.nvim',
config = function()
local lspconfig = require('lspconfig')
require("mason-lspconfig").setup({
ensure_installed = { "sumneko_lua" }
})
require('mason-lspconfig').setup_handlers({
function(server)
lspconfig[server].setup({})
end,
["sumneko_lua"] = function ()
lspconfig.sumneko_lua.setup {
settings = {
Lua = {
diagnostics = {
globals = { "vim" }
}
}
}
}
end,
})
end,
}
use {
"hrsh7th/nvim-cmp",
requires = {
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-buffer",
"hrsh7th/cmp-path",
},
config = function()
local cmp = require("cmp")
cmp.setup({
sources = {
{ name = "nvim_lsp" },
{ name = "buffer" },
{ name = "path" },
},
mapping = cmp.mapping.preset.insert({
["<C-p>"] = cmp.mapping.select_prev_item(),
["<C-n>"] = cmp.mapping.select_next_item(),
['<C-c>'] = cmp.mapping.abort(),
["<CR>"] = cmp.mapping.confirm { select = true },
}),
experimental = {
ghost_text = true,
},
})
end,
}
まだ導入するのは lua のみ。
マッピングも使うものだけ。
メモしたURLをブラウザで開けるようにするため open-browser を導入。
use {
'tyru/open-browser.vim',
config = function()
vim.keymap.set('n', '<leader>o', '<Plug>(openbrowser-open)')
end,
}
カラースキームを変更
duskfox
にした
Luaのコードフォーマッタの Stylua を有効に。
まず cargo 経由でコマンドをインストールした。
次に null-ls を導入。
use({
"jose-elias-alvarez/null-ls.nvim",
config = function()
vim.api.nvim_create_augroup("lsp_format", {})
vim.api.nvim_create_autocmd("BufWritePre", {
group = "lsp_format",
callback = function()
vim.lsp.buf.format()
end,
})
local null_ls = require("null-ls")
null_ls.setup({
sources = {
null_ls.builtins.formatting.stylua,
},
})
end,
})
保存時にフォーマットを実行するようにした。
LSPの進捗を表示する fidget.nvim を入れた
カッコよくて好き。
……というのもあるけど、LSPが有効になるまでどうしても時間がかかるので、進捗が表示されると嬉しい。
ファイラには telescope-file-browser.nvim
を採用した。
telescopeはとりあえず入れただけだが結構気に入ってきたので、このままファイラも telescope に乗っかるものを採用することに。
use({
"nvim-telescope/telescope-file-browser.nvim",
config = function()
require("telescope").load_extension("file_browser")
vim.keymap.set("n", "<leader>uF", ":Telescope file_browser<CR>", { noremap = true })
end,
})
,uf
でファイルを開くようにしているので、その強化版ということで ,uF
でファイラを開く感じに。
ファイラのときだけノーマルモードで起動したい気もする。
vim-quickrunを導入。
use({
"thinca/vim-quickrun",
requires = { { "lambdalisue/vim-quickrun-neovim-job" } },
setup = function()
vim.g.quickrun_config = {
["_"] = {
["runner"] = "neovim_job",
["outputter/buffer/opener"] = "new",
["outputter/buffer/close_on_empty"] = 1,
},
["rust"] = {
["exec"] = "cargo run",
},
}
vim.keymap.set("n", "<leader>r", "<Nop>")
vim.keymap.set("n", "<leader>rr", ":QuickRun<CR>", { silent = true })
end,
})
とりあえず rust の設定だけ
特定のプロジェクトだけ設定を変えたい、ということがあるので nvim-config-local を入れた。
use({
"klen/nvim-config-local",
config = function()
require("config-local").setup({
config_files = { "local.init.lua" },
})
end,
})
quickrunの挙動を変えるのが目的。
設定済みの vim のグローバル変数の辞書の一部を変更しようとしてハマっていた。
quickrun の代わりに :teminal
を使いたいと思い始めた。
プラグインの設定を外しつつ terminal mode から抜ける設定を追加。
vim.keymap.set("t", "<C-l>", "<C-\\><C-n>")
vim.keymap.set("t", "<ESC>", "<C-\\><C-n>")
分割しつつterminalを起動
vim.keymap.set("n", "sT", ":sp<CR>:terminal<CR>i", { silent = true })
コマンドの呼び出しはとりあえず
vim.keymap.set("n", "<leader>r", function()
vim.cmd("split")
vim.cmd("cd パス")
vim.cmd("terminal コマンド")
end)
こんな感じで。あとでもうちょっと考えたい。