技術

Neovim2 (ファイラや補完周りなど)

Neovimを使い始めました。

Neovimは使っている時もそうですが、セットアップするのが面白いです。まだ完全に使いこなせているわけではありませんので、がっつりと作業するときはJetbrainsやVSCodeを使っていますが、徐々にNeovim率を上げていきたいと思います。

前回はインストールとパッケージインストールを試してみるところまでやりました。その続きとして、今回は重要度の高いパッケージを入れて行きます。

Vim Option追加と外出し

前回は初期セットアップということもあり、vimのオプションの設定をinit.luaに直接書いてったのですが、これを外出しします。

lua/options.luaを作成して、init.luaに書いていた内容をここに記載します。

ついでに、初期設定時に入れた設定が少なすぎたので、少し足しておきます。

yankのクリップボードへのcopy、マウス有効化、ignorecaseを追加しておきます。

lua/options.lua

vim.opt.fileencoding = "utf-8"                  -- the encoding written to a file
vim.opt.clipboard = "unnamedplus"               -- allows neovim to access the system clipboard
vim.opt.cursorline = true                       -- highlight the current line
vim.opt.number = true                           -- set numbered lines
vim.opt.mouse = "a"                             -- allow the mouse to be used in neovim
vim.opt.ignorecase = true                       -- ignore case in search patterns

そしてこのファイルを読み込めるように、init.luaを修正します。

require("options")

Telescope

https://github.com/nvim-telescope/telescope.nvim

TelescopeはFuzzy Finder(ファジーファインダー)と言われている部類のパッケージになります。

Vimを使う人のほとんどが入れているようです。作業の起点になるので、これがないとどうしようもないという人もいます。

まずは必須依存ではありませんが、ripgrepが推奨依存となっているので、入れてない場合は入れておきます。

brew install ripgrep

続いてパッケージを追加していきます。

plugins.luaに以下を追加します。

    use { "nvim-lua/plenary.nvim" } -- Useful lua functions used by lots of plugins
    use("williamboman/nvim-lsp-installer")

nvim-lua/plenary.nvimは、色々なパッケージの依存として使われるようなので、公式にある依存の記述でなく、外出しで別に記述しておきます。https://github.com/LunarVim/nvim-basic-ideを参考にしました。

PackerSyncを実施後、:Telescope でファジーファインダーが起動します。続いて、find_filesとやればREADMEにあるような動作ができるようになります。

このパッケージは色々と機能があるようですが、今の所、find_filesしか使っていないです。

Neotree

https://github.com/nvim-neo-tree/neo-tree.nvim

NeovimにはエディタやIDEには必須のファイルウィンドウ(プロジェクトウィンドウ)が標準ではありません。

Neovimではファイラと呼ばれるタイプのパッケージになります。Neotreeというパッケージを使用することにします。

公式のREADMEにあるものを、そのままplugins.luaに貼り付けます。

    -- filer
    -- Unless you are still migrating, remove the deprecated commands from v1.x
vim.cmd([[ let g:neo_tree_remove_legacy_commands = 1 ]])

use {
  "nvim-neo-tree/neo-tree.nvim",
    branch = "v2.x",
    requires = { 
      "kyazdani42/nvim-web-devicons", -- not strictly required, but recommended
      "MunifTanjim/nui.nvim",
    }
  }

PackerSync実施後、:Neotreeでサイドバーにファイラーが表示されるようになります。?を入力すると使い方がポップアップされます。

この状態ではファイルアイコンなどが表示されませんが、あとで考えることにします。とりあえず最低限のことができるようになったで、今はこれで良しとします。

null-ls

https://github.com/jose-elias-alvarez/null-ls.nvim

ファイルへのアクセス周りはとりあえず良しとして、肝心の編集機能が全然そろっていません。

とりあえずNeovimの設定言語である、Luaをフォーマットできるようにします。

フォーマッター、リンターはnull-lsというのがメジャーらしいです。こちらを導入していきます。

lua/plugins.luaに以下を追加

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

use({ "jose-elias-alvarez/null-ls.nvim" }) -- formatter

LSPの2つのパッケージの関連がよくわかっていないです。null-lsの動作に必要なのかどうかわかりませんが、今後必要になるVimでは必須パッケージなので入れておきます。

init.luaに以下を追加

require("null-ls").setup({
    sources = {
        require("null-ls").builtins.formatting.stylua,
    },
})

これも後で別ファイルに外出ししますが、とりあえず今は動くこと優先で、init.luaに直接書いていきます。

null-lsは各言語ごとに、フォーマッターやリンターを設定していきます。今回はLuaのフォーマットだけしておきます。

: checkhealth null-ls 

で設定確認できます。

styluaコマンドがないというエラーが出たので、brewでインストールします。

brew install stylua

これでnull-lsが動くようになりました。luaファイルを開いているときに、

lua: vim.lsp.buf.formatting()

を実行すると整形されるようになりました。毎回このコマンドを叩くのは実用的ではありませんが、それは後で考えることにします。

cmp

https://github.com/hrsh7th/nvim-cmp

補完機能を追加していきます。cmpというのがGitHubでスターが多かったのでこちらを利用します。

こちらは別途スニペットが必要らしいです。vsnipやluasnipが有名どこらしいです。luasnipの方がスターが多いですし新しそうなので、こちらを使うことにします。

lua/pluginsに以下を追加します。

    -- cmp plugins
    use({ "hrsh7th/nvim-cmp" })
    use { "hrsh7th/cmp-buffer"}
    use { "hrsh7th/cmp-path"}
    use({ "hrsh7th/cmp-nvim-lsp" })
    use { "hrsh7th/cmp-nvim-lua"}
    use { "saadparwaiz1/cmp_luasnip"}  -- luasnip
    use { "L3MON4D3/LuaSnip"}  -- luasnip

init.luaに以下を追加します。

require("cmp").setup({
    snippet = {
        expand = function(args)
            require("luasnip").lsp_expand(args.body)
        end,
    },
    window = {
        -- completion = cmp.config.window.bordered(),
        -- documentation = cmp.config.window.bordered(),
    },
    mapping = require("cmp").mapping.preset.insert({
        ["<C-b>"] = require("cmp").mapping.scroll_docs(-4),
        ["<C-f>"] = require("cmp").mapping.scroll_docs(4),
        ["<C-Space>"] = require("cmp").mapping.complete(),
        ["<C-e>"] = require("cmp").mapping.abort(),
        ["<CR>"] = require("cmp").mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
    }),
    sources = require("cmp").config.sources({
        { name = "nvim_lsp" },
        { name = "nvim_lua" },
        { name = "luasnip" },
    }, {
        { name = "buffer" },
    }),
})

-- The nvim-cmp almost supports LSP's capabilities so You should advertise it to LSP servers..
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities = require("cmp_nvim_lsp").update_capabilities(capabilities)

-- The following example advertise capabilities to `clangd`.
require("lspconfig").clangd.setup({
    capabilities = capabilities,
})

最後の方の設定はまだよくわかっていませんが、カスタムなどは後でやるとして、とりあえず動く所まで持っていきます。

PackerSyncを実行して、nvimを起動しなおすとluaファイルで補完が効くようになります。

まとめ

今回は以上になります。ファイラ系とフォーマット、補完周りの整備を追加していきました。これで最低限の編集作業はできるようになったと思います。

次はGit周りの設定、リッチな見た目関連(ステータスバーやアイコン、アウトラインなど)、Vimのキーバインドのカスタムなどをやっていくつもりです。それが終わったら言語別の設定でしょうか。markdownやPython辺りからやっていくことになると思います。