站内链接:

安装配置

vim 到 nvim

  1. 创建 init.vim

通过nvim打开编辑终端, 输入命令:help nvim-from-vim开启 vim 到 nvim 的使用文档介绍, 输入下面的命令:

1
2
call mkdir(stdpath('config'), 'p')
exe 'edit '.stdpath('config').'/init.vim'

其中stdpath('config')是 neovim 的内置函数, 用于获取当前用户的配置文件目录, 一般为~/.config/nvim. mkdir用于创建目录, 其中p表示递归创建目录

  1. 在新打开的 init.vim 中添加如下内容:
1
2
3
4
5
set runtimepath^=~/.vim runtimepath+=~/.vim/after
let &packpath = &runtimepath
source ~/.vimrc

; 加载其他lua配置

至此, 一个 neovim 的基本配置就已经完成

plug 包管理

不关注原有的 vim 配置, 通过 neovim 来安装vim-plug:

1
2
sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'

更改init.vim, 变为如下内容, 然后运行PlugInstall进行插件安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
" 1. 原有vim配置
set runtimepath^=~/.vim runtimepath+=~/.vim/after
let &packpath = &runtimepath
source ~/.vimrc


" 2. 包管理工具: vim-plug
call plug#begin()

Plug 'neoclide/coc.nvim', {'branch': 'release'}

call plug#end()


" 3. 引用lua根文件
lua require("bamboo")

问题

  1. vim 打开 coc.vim 异常, 通过 plug 包安装的
1
2
cd ~/.vim/plugged/coc.nvim
git checkout release

配置

  1. 目录结构

功能: nvim 基础配置
目录介绍:

1
2
3
4
5
6
7
8
9
.
├── coc-settings.json
├── init.vim
├── lua
│ ├── bamboo.lua
│ ├── basic.lua
│ ├── keybindings.lua
│ └── plugins.lua
└── readme.md

其中 entrypoint 可以是init.viminit.lua, 一般在该这里导入其他的 lua 文件, 这些 lua 文件默认是放在 lua 文件夹下的:

  • basic.lua: 基础配置
  • keybindings.lua: 配置按键映射
  • lsp.lua: 配置 LSP
  • options.lua: 选项配置, 见下面介绍
  • plugins.lua: 配置插件

config 用于存放各种插件自身的配置, 其中文件名格式一般为nvim-pluginName.lua.

  1. 选项配置

在 nvim 和 vim 中, 选项配置的变量值是不一样的, 下面主要介绍vim.g, vim.opt, vim.cmd在两者之间的不同之处

  • vim.g: 类似 vim 中的 g, vim 中配置let g:foo=bar, 其等价于 nvim 中vim.g.foo=bar配置
  • vim.opt: 类似 vim 中的局部变量, vim 中配置set foo=bar, 其等价于 nvim 中的vim.opt.foo=bar配置
  • vim.mcd: 类似 vim 中的脚本, vim 中的配置some_vim_script, 其等价于 nvim 中的vim.cmd(some_vim_script)配置

下面是 vim 中常见的配置转为 nvim 的例子

1
2
3
4
5
-- tab
vim.opt.tabstop = 4
vim.opt.softtabstop = 4
vim.opt.shiftwidth = 4
vi.opt.expandtab = 4
  1. 按键配置

nvim 中的按键配置也不同于 vim, 在 vim 中使用mode key action来进行键的映射, 而在 nvim 中使用vim.keymap.set(<mode>, <key>, <action>, <opts>)进行快捷键的映射. 下面是 nvim 中的一些快捷键映射

1
2
3
4
5
6
7
8
-- 通用选项
local opts = {
noremap = true,
silent = true,
}

-- 绑定
vim.keymap.set('n', '<C-h>', '<C-w>h', opts)

Plug

在 Vim 中,<Plug> 是一个特殊的占位符,用于定义自定义键映射(keymap)。它是一种用来表示待映射的按键序列,当我们将其用作键映射的左侧时,实际上并不会执行任何操作,而是留待后续定义。

使用 <Plug> 可以方便地定义一系列键映射,并将它们预留在某个插件或配置中,以便稍后根据需要来填充这些映射。这样的设计可以使插件或配置更加灵活和可扩展。例如,我们可以在配置文件中定义一个 <Plug> 映射,如下所示:

1
2
3
" 自定义的键映射
nmap <silent> <Plug>MyCustomMapping1 :echo "This is MyCustomMapping1"<CR>
nmap <silent> <Plug>MyCustomMapping2 :echo "This is MyCustomMapping2"<CR>

在上面的例子中,我们定义了两个 <Plug> 映射:<Plug>MyCustomMapping1<Plug>MyCustomMapping2,分别输出不同的消息。然而,由于我们在 <Plug> 映射的左侧使用了 nmap 命令,这些映射不会直接生效。

接下来,我们可以在其他地方使用 map 命令或者插件来填充这些 <Plug> 映射,使其生效。例如,可以在插件中这样使用:

1
2
3
" 插件中的键映射
nmap <silent> <Leader>A <Plug>MyCustomMapping1
nmap <silent> <Leader>B <Plug>MyCustomMapping2

在这个例子中,我们在 <Leader>A<Leader>B 的映射中使用了之前定义的 <Plug> 映射,这样就会执行相应的命令并输出消息。使用 <Plug> 映射的好处在于,它可以将自定义的键映射保留在一个统一的地方,方便后续的维护和管理。同时,也能提高配置的可读性和可维护性。

依赖

LSP

LSP 是 Language Server Protocol 的缩写, 它是一种为编辑器和 IDE 提供语言服务的协议. 它的目标是将语言智能与编辑器/IDE 解耦, 使得多种编辑器/IDE 可以共享一些通用的语言服务,从而减少语言实现的重复工作,加速语言实现的迭代速度,为开发者提供更好的开发体验。

目前流行的 lsp 插件有: coc.nvim, vim-lsp, LanguageClient-neovim, 关于coc.nvimvim-lsp的区别, 知乎上有如下说明:

  • 性能上因为 nvim-lsp 不需要远程通讯大概更好一点,不过主要取决于 language server
  • 稳定性上已有功能应该都比较稳定了
  • 使用体验上 coc.nvim 的补全和错误提示是直接提供的,上手相对容易,但是在定制方面因为 coc.nvim 主要基于配置文件只提供了有限的设置,不如 nvim-lsp 那么灵活透明

注释

在 neovim 中我们使用Comment.nvim进行代码的注释,其配置如下:

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
require('Comment').setup({
-- 是否在注释符号和行之间添加空格
padding = true,
-- 注释后光标是否保持在原位置
sticky = true,
-- 在执行注释/取消注释时要忽略的行
ignore = nil,
---在 NORMAL 模式下用于切换注释的键映射
toggler = {
---Line-comment toggle keymap
line = ',cc',
---Block-comment toggle keymap
block = ',bc',
},
-- 在 NORMAL 和 VISUAL 模式下用于操作注释的键映射
opleader = {
---Line-comment keymap
line = ',c',
---Block-comment keymap
block = ',b',
},
-- 用于额外的注释操作的键映射,例如在上面一行、下面一行或行尾添加注释
extra = {
---在上面一行插入一个注释语句
above = ',cO',
---在光标的下面一行插入一个注释语句
below = ',co',
---Add comment at the end of line
eol = ',cA',
},
-- 在注释之前调用的函数
pre_hook = nil,
-- 在注释之后调用的函数
post_hook = nil,
})

但实际使用过程中会碰到如下问题: 对于.vue等文件,在<style>中注释的风格是错误的,这是因为我们没有安装包含语法解析树功能的插件,其使用 filetype 这个最低优先级的注释解析标准。下面是nvim-treesitter的配置和安装流程:

1
2
3
4
5
6
7
# a. 在init.vim中安装该插件并PlugInstall,若碰到TSUpdate命令不存在,先安装在增加后面的update代码
# 重要: 这个配置需要放在coc.nvim的配置后面, 否则不生效,冲突了吗?
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}

# b. 安装vue支持语言
TSInstall vue
TSInstallInfo

至此,整个 neovim 下的注释就没有任何问题了,使用 coc 替代 tags, cscope,使用 comment.nvim 作为全语言的注释,完美。

工具

下面简单的介绍下 python 开发环境中使用到各个工具的用途:

  • flake8: 代码风格检查工具, 注意,这是检查工具
  • pylint: 代码质量检查工具,注意,这是检查工具
  • black: 代码格式化工具, 类似的工具还有: autopep8, yapf, isort

COC

基本说明

coc.nvim 是一个功能强大的 Vim/Neovim 插件,它提供了语言服务器协议(Language Server Protocol,LSP)的支持,使得 Vim/Neovim 编辑器可以实现像 Visual Studio Code 那样的智能代码补全、语法检查、代码导航、重构等功能。coc.nvim 实际上是基于 LSP 开发的一个 Vim/Neovim 客户端。下面是本人借助 coc.nvim 实现的功能:

  • 多语言支持coc.nvim 支持许多不同的编程语言,包括但不限于 Python、JavaScript、TypeScript、Go、Java 等。
  • 代码补全:通过与语言服务器通信,coc.nvim 可以提供智能代码补全功能,根据当前上下文为你推荐可能的代码补全项。
  • 代码导航:你可以跳转到函数或变量的定义处,也可以查找相关的文档和说明。
  • 语法检查:语言服务器可以实时对你的代码进行语法检查,并在编辑器中显示错误和警告。

未应用但是 coc.nvim 自带的其他功能,官网的简易配置中有给出下面功能的一些映射:

  • 重命名:通过与语言服务器通信,你可以安全地重命名变量、函数等,确保代码一致性。
  • 重构coc.nvim 支持一些代码重构操作,如提取函数、变量重命名等。
  • 快速修复:在出现错误或警告时,coc.nvim 可以为你提供快速修复建议。
  • 自定义设置:你可以根据自己的需要定制 coc.nvim 的功能和行为。

注意 coc 本身并不提供具体语言的补全功能,更多的只是提供了一个基于 LSP 服务协议的平台,在安装完成后,我们需要安装具体的语言服务以支持对应的补全功能。 总的来说,coc.nvim 是一个非常强大且灵活的插件,它提供了许多有用的功能,可以极大地提高 Vim/Neovim 编辑器的开发效率和舒适度。下面是一些常见的命令或配置:

  1. 查看配置和键映射
1
2
3
4
5
6
7
8
# 查看当前的配置, 实际上就是查看coc-settings.json内容
CocConfig

# 查看当前所有生效的快捷键,避免冲突, 其中tab为键盘上的键
:verbose imap <tab>
# 查看某个快捷键的详细信息
:verbose imap ,date
:verbose map ,date
  1. 安装和管理
1
2
3
4
5
" 注意: coc-tsserver同时支持javascript和typescript, 插件安装到`~/.config/coc/extensions/node_modules/coc-json`目录下
CocInstall coc-json coc-html coc-css coc-tsserver

" 通过命令查看所有安装的插件
CocList extensions

其中 CocList 命令的输出中,每一个插件前面的字符说明如下:

  • ?表示无效扩展名
  • *表示扩展已激活
  • +表示扩展已加载
  • -表示扩展被禁用
  1. 配置文件

coc.nvim 使用jsonc作为配置文件格式,这是与 VSCode 相同格式的配置,为了看到更好的 JSON 高亮显示,可以安装vim-jsonc或者进行简单的配置(NeoVim0.6.0+版本不需要安装):

1
2
3
4
5
# a. 安装jsonc, 通过:PlugInstall安装
Plug 'kevinoid/vim-jsonc'

# b. 简单配置
autocmd FileType json syntax match Comment +\/\/.\+$+

注意,为了智能感知coc-settings.json,需要提前安装coc-json以便更好的进行配置:CocInstall coc-json,并且在该 json 文件中配置新的变量项的时候会有提示信息。

插件基础

  1. 基本命令
  • CocInstall: 安装某些扩展,如果需要安装某个插件扩展,可以到 npm 上搜索coc.nvim来获取某个语言支持的扩展
  • CocUpdateCocUpdateSync: 更新所有的未锁定的扩展
  • CocUninstall: 卸载某个扩展
  • CocList services: 打开服务列表,可以看到每个服务的 id,state,filetypes,如果服务 id 以 开头languageserver,则它来自languageservercoc-settings.json 中的配置,如果不是,则来自 coc.nvim 的扩展。

例如:

1
2
languageserver.golang [starting] go
json [running] json,jsonc

<buffer>的文件类型不匹配后面的服务 filetypes 时,该项服务不会启动,我们可以通过CocCommand document.echoFiletype查看当前缓冲区的文件类型。当然,如果在<buffer>存在开始,每打开一个不同类型的文件都会启动相应的扩展并且不会自动关闭,这是需要注意的。

  1. 调试创建

如果扩展抛出未捕获的错误,您可以通过以下方式获取错误消息::messages,这相当于调试输出,例如我们编辑完coc-settings.json并保存就会产生如下几条消息:

1
2
3
4
Neoformat: prettier formatted buffer
"~/.config/nvim/coc-settings.json" 19L, 714B 已写入
Neoformat: prettier formatted buffer
"~/.config/nvim/coc-settings.json" 30L, 964B 已写入

插件分类

每一个扩展或插件都是为了支持某个语言而产生的, 下面就简单的介绍下各个基础的 coc 插件:

  1. coc-html

coc-html 利用 LSP 支持为 HTML 开发提供智能补全、代码导航、错误提示等特性,在安装完coc-html插件之后,你还需要在coc-settings.json中完成相关的配置:

1
2
3
4
5
6
7
8
9
10
11
{
"languageserver": {
"html": {
"command": "html-languageserver",
"filetypes": ["html", "htmldjango"],
"rootPatterns": ["*.html", "templates/**.html", "views/**.html"],
"initializationOptions": {},
"settings": {}
}
}
}

示例

django 环境

首先,在进入一个新的 python 虚拟环境之后需要安装如下几个包:

1
2
3
4
5
6
7
8
# LSP服务
pip install jedi-language-server

# 代码格式化
pip install "black[jupyter]"

# 最后安装pylint, 因为ale会使用
pip install pylint-django

参考