NeoVim的基本配置

使用Packer與Nvim-Tree為例子

July 27, 2023, 9:12 p.m.
Vim

Vim一直以來都是我的主要開發工具,上手後最大的優點就是解放滑鼠後的開發效率,習慣以後只能說回不去了。而過去幾年一直耳聞了他重構後的兄弟NeoVim在底層執行上的效率更好,因此這兩週花了一點時間把一直想使用的NeoVim調整完成。

隨手在這邊記錄一下使用的資訊。

NeoVim版本

  • v0.8.3

NeoVim安裝

我是直接使用HomeBrew安裝neovim

brew install neovim

Configure配置的地方

Neovim預設的配置路徑是在家目錄的.config目錄下,這是我當前的目錄結構。
如果相關資料夾不存在的話可以自行建立。

> tree ~/.config/nvim
├── after
│   └── plugin
├── autoload
├── coc-settings.json
├── init.lua
├── lua
│   ├── coc-config.lua
│   ├── plugins.lua
│   └── utils.lua
├── plugin
│   └── packer_compiled.lua
└── pyrightconfig-default.json

稍微簡單描述一下各種資料夾的用途:
- after:用來放置當預設的vim config跑完後,要被載入的腳本們。他可以用來針對不同的檔案型態或插件,複寫一些預設的設定。
- lua:用來放置可以在init.lua中被呼叫的Lua模組們
- plugin:這裡定義了跟plugins, autoloader相關的指令文件

啟動腳本

neovim接受兩種格式的啟動腳本,分別是init.viminit.lua
- init.vim:類似於原本的vim所使用的.vimrc腳本,採用跟.vimrc一樣的VimL語法,風格上看起來會跟老牌的程式語言接近。
- init.lua:LUA格式則是只有neovim可以接受的設定檔,優點是可以將設定檔拆分模組化的動作容易實現,因為有著requirereturn等語法
- 其實原本的.vimrc也可以做到,但風格看起來不如Lua優雅。

這次的設定我採用的是lua格式的設定黨,理由只是想換換口味嚐鮮看看順便學習Lua。我在網路上看其他neovim使用者的討論,其實並沒有說哪一種啟動腳本比較好,後續我在使用的時候,甚至有些模組的安裝可能使用init.vim還會比較方便(例如:模組官方文件只有給出init.vim風格的設定方法)。所以可以依據個人的風格來選定想使用的腳本格式。

一個簡易的init.lua範例:

vim.opt.fileformat = "unix"
vim.opt.encoding = "utf-8"
vim.g.mapleader = " " -- Space key as leader

它等價於原本的.vimrc

set fileformat=unix
set encoding=utf8
let mapleader="\<Space>"

因此,如果原本就已經有在使用的.vimrc腳本,都可以透過NeoVim提供的vim.xxxAPI來做相關的設定。這邊在列一個API相關的例子:

cmd API

cmdAPI我覺得比較像是一種萬用解,他的英文描述是:

All Vim commands and functions are accessible from Lua.
:lua vim.cmd(“{Your Vim Command Here..}”)

也就是說,我們可以原封不動的把.vimrc裡面的指令丟進去vim.cmd裡面就可以跑了。
例如主題設定在vimrc中是:

colorscheme gruvbox

來到Lua會變成:

vim.cmd('colorscheme gruvbox')
  • 但我覺得如果能使用其他對應的API來設定的話,應該還是盡量使用API比較好。不然一整排的vim.cmd在lua啟動腳本內,似乎就失去了使用Lua管理設定檔案的意義了

CheckHealth指令

進入neovim之後,可以使用checkhealth指令來檢查neovim當前的系統狀態是否有問題

:checkhealth

NeoVim會新開一個Buffer顯示類似下面的畫面:

  nvim: health#nvim#check
  ========================================================================
  ## Configuration
    - OK: no issues found

  ## Performance
    - OK: Build type: Release

  ## Remote Plugins
    - OK: Up to date

  ## terminal
    - INFO: key_backspace (kbs) terminfo entry: key_backspace=^H
    - INFO: key_dc (kdch1) terminfo entry: key_dc=\E[3~
    - INFO: $TERM_PROGRAM='iTerm.app'
    - INFO: $COLORTERM='truecolor'

  nvim-treesitter: require("nvim-treesitter.health").check()
  ========================================================================
  ## Installation
    - OK: `tree-sitter` found 0.20.7 (parser generator, only needed for :TSInstallFromGrammar)
    - OK: `node` found v20.3.1 (only needed for :TSInstallFromGrammar)
    - OK: `git` executable found.
    - OK: `cc` executable found. Selected from { vim.NIL, "cc", "gcc", "clang", "cl", "zig" }
      Version: Apple clang version 14.0.3 (clang-1403.0.22.14.1)
    - OK: Neovim was compiled with tree-sitter runtime ABI version 14 (required >=13). Parsers must be compatible with runtime ABI.

  ## OS Info:
  {
    machine = "arm64",
    release = "22.5.0",
    sysname = "Darwin",
    version = "Darwin Kernel Version 22.5.0: Thu Jun  8 22:22:20 PDT 2023; root:xnu-8796.121.3~7/RELEASE_ARM64_T6000"
  }

可以看到Neovim不只檢查了Config是否有問題,也會一併檢查模組(這裡用nvim-treesitter這個模組當範例)是否有問題。

Provider的安裝

Provider是為了讓NeoVim能夠執行使用其他程式語言開發的模組,像是Python或是ruby…等等。可以透過上述的checkhealth指令查看相關的訊息。NeoVim會提示你這些可選擇的Provider目前的安裝狀況

  provider: health#provider#check
  ========================================================================
  ## Clipboard (optional)
    - OK: Clipboard tool found: pbcopy

  ## Python 3 provider (optional)
    - INFO: pyenv: Path: /opt/homebrew/Cellar/pyenv/2.3.21/libexec/pyenv
    - INFO: pyenv: $PYENV_ROOT is not set. Infer from `pyenv root`.
    - INFO: pyenv: Root: /Users/peter/.pyenv
    - INFO: Using: g:python3_host_prog = "/Users/peter/.pyenv/versions/neovim3/bin/python"
    - INFO: Executable: /Users/peter/.pyenv/versions/neovim3/bin/python
    - INFO: Python version: 3.9.10
    - INFO: pynvim version: 0.4.3
    - OK: Latest pynvim is installed.

  ## Python virtualenv
    - OK: no $VIRTUAL_ENV

不同程式語言的Provider的安裝方式都不一樣,我們可以透過help指令查看他們的安裝方法

:help provider-python
  • 我們可以把provider後面的語言換成想要的

模組管理器Packer

NeoVim有很多不同的模組管理器可以使用,這裡我使用的是Packer。
首先我們把Packer的Repo下載到:
~/.local/share/nvim/site/pack/packer/start/packer.nvim

git clone --depth 1 https://github.com/wbthomason/packer.nvim\

 ~/.local/share/nvim/site/pack/packer/start/packer.nvim

然後回到~/.config/nvim內在我們的plugins.lua添加Packer的引用指令

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

  -- 之後想要使用的模組都可以丟在這之後
  ...
end)

然後我們就可以使用指令PackerSync看看Packer的安裝狀況

:PackerSync
  • 如果PackerSync沒有出現在NeoVim的指令中的話,可以試試看cd到plugins.lua所在的位置再次下達指令看看。

模組安裝(以nvim-tree為例)

我們把想要安裝的模組,接在上述plugins.luapakcer模組之後。這裡使用nvim-tree當作範例:

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

  -- Nvim Tree
  use {
      'nvim-tree/nvim-tree.lua',
      requires = {
          'nvim-tree/nvim-web-devicons', -- optional
      },

  }
end)

然後使用:PackerSync來安裝他。(PackerSync會自動從Github把最新版本的套件拉下來)

nvim-tree是一個檔案總管類型的套件,類似的功能我之前使用vim的時候所使用的是nerdtree這個模組。能夠以側邊欄的形式來管理當前目錄下的檔案。

接下來我們回到init.lua設定,加入下面的指令來啟動他:

  -- Nvim Tree Settings
require("nvim-tree").setup({
  -- Nvim-Tree Settings for Project Manager
  sync_root_with_cwd = true,
  respect_buf_cwd = true,
  update_focused_file = {
      enable = true,
      update_root = true
  },
})

vim.api.nvim_set_keymap('n', '<C-n>', ':NvimTreeToggle<CR>', {})
  • 重新啟動NeoVim之後,就可以用:NvimTreeToggle指令測試看看nvim-tree
  • 因為我習慣使用Ctrl + n來開關,所以這裡有做了快捷鍵的設定

後續目標

到目前為止一個基本的NeoVim設定已經完成。然而之後還有非常多可以玩的項目,光是使用lua將腳本模組化就不知道可以玩多少東西,還別說零零總總的模組有著一海票的設定可以客製化自己的編輯器。後續有空我再陸續把一些好用的模組的使用方式分享上來。

Tags:

vim