来源链接:Neovim IDE 搭建系列(01) - 知乎 (zhihu.com)

Neovim IDE 搭建系列(01)

前言

我是一名 Python 开发者,最早的时候使用 Pycharm 进行开发,后来大概使用了一年多的 vscode,由于受不了 vscode 以及 Pycharm 的卡顿,所以在不久前我转到了 neovim 阵营。

得益于 LSP 以及 DAP 的加持,目前 neovim 的编码体验已经不输于 vscode 了,高效的全键盘操作能够让你的思维不会因为寻找鼠标而中断,这也是我热爱 neovim 最重要的一个原因。

鉴于目前这部分中文资料较少,所以在此想对加入 neovim 大家庭而又畏惧繁琐配置的朋友提供一份快速搭建的指南,如果您觉得这个系列对您有帮助,不妨点个关注 ~

预计在未来一周内将会全部更新完毕,感谢阅读。

配置范围

个人平常会使用的语言如下,如果你也使用这些语言,那么是完全可以用 neovim 进行开发的:

  • Python3
  • Golang
  • Lua
  • NodeJs
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • Vue

拟定目录

配置过程大概分为以下几个步骤:

  • 基本配置
  • 美化配置
  • 编辑配置
  • 功能配置
  • LSP 配置
  • DAP 配置
  • 其他配置

刚好 7 天,一天一个板块,目前我的插件数量是 68,没做任何优化,在 16 年的老电脑上启动时间大约 100 毫秒,比 vscode 快了很多倍。

准备工作

在开始之前,需要确保安装以下一些外部依赖:

  • neovim(至少大于 0.5 版本)
  • python3 以及 pip3
  • tar、curl、git、gzip、wget
  • gcc 以及 g++ (用于 nvim-treesitter 的依赖安装)
  • nerd font(正确显示图标)
  • node 以及 npm(用于 LSP 服务,可选)
  • fd 以及 ripgrep (用于 telescope 模糊查找)
  • sed (用于 nvim-spectre 的全局字符串替换)

由于我使用的是 Linux (manjaro),所以安装它们都非常简单,推荐 windows 用户在 WSL 下安装,这样会省掉很多繁琐的步骤。

配置目录

neovim 现在支持 vimscript 和 lua 这 2 种语言书写配置,个人使用纯 lua 语言,它能够更加方便的管理多个插件。

neovim 的配置文件放在 ~/.config/nvim/init.lua 中,可按照下面的目录结构创建相关目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/home/askfiy/.config/nvim
├── init.lua
├── ftplugin/
├── lint/
├── lua/
│ ├── basic/
│ │ ├── config.lua
│ │ ├── keybinds.lua
│ │ ├── plugins.lua
│ │ └── settings.lua
│ ├── conf/
│ ├── dap/
│ └── lsp/
└── snippet/

目录说明:

  • ftplugin:存放不同文件类型的缩进规则文件
  • lint:存放各种语言的代码检查规范配置文件,如 pylint 等
  • basic:存放基本配置项文件
  • conf:存放插件相关配置文件
  • dap:存放 DAP 相关配置文件
  • lsp:存放 LSP 相关配置文件
  • snippet:存放代码片段相关文件

文件说明:

  • init.lua:配置入口文件
  • config.lua:存放用户自定义配置的文件
  • keybinds.lua:存放键位绑定的文件
  • plugins.lua:存放依赖插件的文件
  • settings.lua:存放 neovim 基本配置项的文件

部分功能展示

目录树、重做树、大纲预览、各种终端:

img

语法提示、代码补全、工作区诊断、问题跳转:

img

代码调试:

img

代码快速格式化:

img

自定义代码片段(和 vscode 一样的配置方式,很方便):

img

tabnine 和 git copilot 等 AI 代码补全:

img

快速跳转到词、行、列:

img

项目模糊查找、文件查找、标签查找:

img

各种漂亮的主题:

img

img

Neovim IDE 搭建系列(02)

安装 neovim

为了和大家一样从头开始配置 neovim,我特意准备了一个 Ubuntu 的虚拟机。

首先第一步是安装 neovim,Ubuntu 如果用 apt 安装 neovim 其实版本是非常低的,所以我们从 neovim 官网直接安装最新版本的 neovim。

跳转到 neovim 稳定版本下载页面:点我跳转

img

复制出链接地址,然后使用 wget 下载:

1
2
$ cd ~
$ wget https://github.com/neovim/neovim/releases/download/v0.6.1/nvim-linux64.tar.gz

下载完成后安装:

1
$ sudo tar -xvf ~/nvim-linux64.tar.gz -C /usr/local/

将 neovim 添加至环境变量:

1
$ vi ~/.bashrc

粘贴以下内容:

1
export PATH=/usr/local/nvim-linux64/bin:$PATH

退出 vi,然后刷新配置:

1
$ source ~/.bashrc

输入 nvim,应该可以看见主界面了:

img

创建目录

创建 neovim 配置目录,直接复制粘贴:

1
2
3
4
5
6
7
$ mkdir -p ~/.config/nvim/{ftplugin,lint,lua,snippet}
$ mkdir -p ~/.config/nvim/lua/{basic,conf,dap,lsp}
$ touch ~/.config/nvim/init.lua
$ touch ~/.config/nvim/lua/basic/config.lua
$ touch ~/.config/nvim/lua/basic/keybinds.lua
$ touch ~/.config/nvim/lua/basic/plugins.lua
$ touch ~/.config/nvim/lua/basic/settings.lua

最终目录结构如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/home/askfiy/.config/nvim/
├── ftplugin
├── init.lua
├── lint
├── lua
│ ├── basic
│ │ ├── config.lua
│ │ ├── keybinds.lua
│ │ ├── plugins.lua
│ │ └── settings.lua
│ ├── conf
│ ├── dap
│ └── lsp
└── snippet

每个目录、文件的功能及用途可参照本系列第一篇的介绍,这里不再重复说明。

init.lua

在 Lua 中,通过 require 方法,可以导入其它模块。

而 init.lua 是整个配置的入口文件,当 neovim 启动时会自动加载该文件。

所以我们需要在 init.lua 中导入 lua/basic 目录下的 4 个 Lua 文件,复制粘贴以下代码到 init.lua 文件中:

1
2
3
4
5
6
7
$ nvim ~/.config/nvim/init.lua 

-- 加载配置项
require("basic.settings")
require("basic.keybinds")
require("basic.config")
require("basic.plugins")

基础设置

neovim 的基础设置如下,打开 lua/basic/settings.lua 填入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
$ nvim ~/.config/nvim/lua/basic/settings.lua 

-- 设定各种文本的字符编码
vim.o.encoding = "utf-8"
-- 设定在无操作时,交换文件刷写到磁盘的等待毫秒数(默认为 4000)
vim.o.updatetime = 100
-- 设定等待按键时长的毫秒数
vim.o.timeoutlen = 500
-- 是否在屏幕最后一行显示命令
vim.o.showcmd = true
-- 是否允许缓冲区未保存时就切换
vim.o.hidden = true
-- 是否开启 xterm 兼容的终端 24 位色彩支持
vim.o.termguicolors = true
-- 是否高亮当前文本行
vim.o.cursorline = true
-- 是否开启语法高亮
vim.o.syntax = "enable"
-- 是否显示绝对行号
vim.o.number = true
-- 是否显示相对行号
vim.o.relativenumber = true
-- 设定光标上下两侧最少保留的屏幕行数
vim.o.scrolloff = 10
-- 是否支持鼠标操作
vim.o.mouse = "a"
-- 是否启用系统剪切板
vim.o.clipboard = "unnamedplus"
-- 是否开启备份文件
vim.o.backup = false
-- 是否开启交换文件
vim.o.swapfile = false
-- 是否特殊显示空格等字符
vim.o.list = true
-- 是否开启自动缩进
vim.o.autoindent = true
-- 设定自动缩进的策略为 plugin
vim.o.filetype = "plugin"
-- 是否开启高亮搜索
vim.o.hlsearch = true
-- 是否在插入括号时短暂跳转到另一半括号上
vim.o.showmatch = true
-- 是否开启命令行补全
vim.o.wildmenu = true
-- 是否在搜索时忽略大小写
vim.o.ignorecase = true
-- 是否开启在搜索时如果有大写字母,则关闭忽略大小写的选项
vim.o.smartcase = true
-- 是否开启单词拼写检查
vim.o.spell = true
-- 设定单词拼写检查的语言
vim.o.spelllang = "en_us,cjk"
-- 是否开启代码折叠
vim.o.foldenable = true
-- 指定代码折叠的策略是按照缩进进行的
vim.o.foldmethod = "indent"
-- 指定代码折叠的最高层级为 100
vim.o.foldlevel = 100

注意,若想让 neovim 共享系统剪切板,还需要下载一个插件:

1
$ sudo apt install xsel

具体各个配置项的作用可通过 help 命令查询,如 :h hidden:

img

键位设置

个人不太喜欢将默认的键位做太多更改,所以对默认键位只做了非常简单的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
$ nvim ~/.config/nvim/lua/basic/keybinds.lua 

-- leader 键设置为空格
vim.g.mapleader = " "

-- 默认的键位设置函数太长了,所以这里将它们重新引用一下
vim.keybinds = {
gmap = vim.api.nvim_set_keymap,
bmap = vim.api.nvim_buf_set_keymap,
dgmap = vim.api.nvim_del_keymap,
dbmap = vim.api.nvim_buf_del_keymap,
opts = {noremap = true, silent = true}
}

-- 插入模下 jj 退出插入模式
vim.keybinds.gmap("i", "jj", "<Esc>", vim.keybinds.opts)

-- 用 H 和 L 代替 ^ 与 $
vim.keybinds.gmap("n", "H", "^", vim.keybinds.opts)
vim.keybinds.gmap("v", "H", "^", vim.keybinds.opts)
vim.keybinds.gmap("n", "L", "$", vim.keybinds.opts)
vim.keybinds.gmap("v", "L", "$", vim.keybinds.opts)

-- 将 C-u 和 C-d 调整为上下滑动 10 行而不是半页
vim.keybinds.gmap("n", "<C-u>", "10k", vim.keybinds.opts)
vim.keybinds.gmap("n", "<C-d>", "10j", vim.keybinds.opts)

-- 插入模式下的上下左右移动
vim.keybinds.gmap("i", "<A-k>", "<up>", vim.keybinds.opts)
vim.keybinds.gmap("i", "<A-j>", "<down>", vim.keybinds.opts)
vim.keybinds.gmap("i", "<A-h>", "<left>", vim.keybinds.opts)
vim.keybinds.gmap("i", "<A-l>", "<right>", vim.keybinds.opts)

-- 修改分屏大小
vim.keybinds.gmap("n", "<C-up>", "<cmd>res +1<CR>", vim.keybinds.opts)
vim.keybinds.gmap("n", "<C-down>", "<cmd>res -1<CR>", vim.keybinds.opts)
vim.keybinds.gmap("n", "<C-left>", "<cmd>vertical resize-1<CR>", vim.keybinds.opts)
vim.keybinds.gmap("n", "<C-right>", "<cmd>vertical resize+1<CR>", vim.keybinds.opts)

-- 正常模式下按 ESC 取消高亮显示
vim.keybinds.gmap("n", "<ESC>", ":nohlsearch<CR>", vim.keybinds.opts)

-- 通过 leader cs 切换拼写检查
vim.keybinds.gmap("n", "<leader>cs", "<cmd>set spell!<CR>", vim.keybinds.opts)

输入法设置

个人使用的是 Fcitx 框架,所以直接可以自己写一个函数让 neovim 在退出插入模式时切换到英文输入法。

打开 lua/basic/config.lua,填入以下内容

1
2
3
4
5
6
7
8
9
10
11
$ nvim ~/.config/nvim/lua/basic/config.lua 

-- 自动切换输入法(Fcitx 框架)
vim.g.FcitxToggleInput = function()
local input_status = tonumber(vim.fn.system("fcitx-remote"))
if input_status == 2 then
vim.fn.system("fcitx-remote -c")
end
end

vim.cmd("autocmd InsertLeave * call FcitxToggleInput()")

如果是 Windows 或者 Mac 平台,可以搜索 im-select 并安装,而后自行寻找其它教程配置,这里不再举例。

ftplugin 配置

不同类型的文件有不同的缩进规则,比如在 Python 中缩进是 4 个空格,而在 Golang 中是 1 个 tab。

基础设置时,我们在 lua/basic/settings.lua 中配置了这样的一个选项:

1
2
-- 自动缩进的策略为 plugin
vim.o.filetype = "plugin"

接下来需要在 ~/.config/nvim/ftplugin 目录中新建不同语言的缩进规则文件,如图所示:

img

然后根据语言的缩进规则来书写不同的内容,以 go.lua 为例:

1
2
3
4
5
6
7
8
-- 是否将 tab 替换为 space
vim.bo.expandtab = false
-- 换行或 >> << 缩进时的 space 数量
vim.bo.shiftwidth = 4
-- 一个 tab 占用几个 space
vim.bo.tabstop = 4
-- tab 和 space 的混合,和上面 2 个设置成相同即可
vim.bo.softtabstop = 4

同理,在 Lua 中的缩进规则是 4 个空格,那么 lua.lua 文件的内容就是下面这样:

1
2
3
4
5
6
vim.bo.expandtab = true                     
vim.bo.shiftwidth = 4
vim.bo.tabstop = 4
vim.bo.softtabstop = 4
-- 取消自动注释,当前行是 -- 注释时,按下 CR 或者 o 默认会自动注释下一行,所以这里取消了
vim.opt_local.formatoptions = vim.opt_local.formatoptions - {"c", "r", "o"}

除此之外,我们也可以为不同语言设置不同的空格以及回车样式,但是要确保 lua/basic/settings.lua 中的 list 配置项是打开的:

1
2
-- 是否特殊显示空格等字符
vim.o.list = true

比如我想让 Golang 中的空格表现为 ⋅,回车表现为 ↴,那么就可以在 go.lua 中加入下面 2 行代码:

1
2
vim.opt.listchars:append("space:⋅")
vim.opt.listchars:append("eol:↴")

在编辑 Golang 文件时,你会发现它们生效了:

img

本章节的话

如果你之前使用过 vimscript 但对 Lua 并不熟悉的话,可以参照 在 neovim 中使用 Lua 这份教程。

今后的配置不会很繁琐,能用 Lua 写的代码就会尽量用 Lua 来写,不会涉及太多深层次的东西。

ok,那么基础配置已经搞定了,后面会做一些美化让 neovim 看起来更酷一些。

如果您觉得对你有所帮助,烦请动动发财的小手,点波喜欢吧~