Neovim介绍
当在终端中进行大量工作,尤其是当你在使用无图形界面的时候,很自然的会想到有没有一种可以在终端中直接进行编程的工具,这就是我们的Vim。当然你可能会说,我为什么不用VSCode?这是个好问题,的确有许多人用的是VSCode作为编辑器,但对于我来说VSCode依然过于重了,很多时候我并不是正规的以项目为单位进行开发,而是东一个文件,西一个文件。我希望能有一个编辑器既能作为项目开发的主力,又能作为查看零碎文件的工具,Vim及其衍生产物是一个很好的选择。需要明确的是Vim及其衍生产物和VSCode一样都只是编辑器而已,并不是一个IDE,因此它也必须配备插件才能进行使用。由于Vim实在是有点上年纪了,我们使用的是Vim的Lua增强版——Neovim,它的社区相比Vim更为活跃,本身也更加好用。
在真正上手Neovim之前你可能已经听过Vim的大名,并且听闻熟练掌握Vim之后会非常的快。按我使用Vim的体验,我很难说我比其他熟练的编辑器要更快。Vim主要是带来了完全不同一般编辑器的输入体验,他的设计让你的手完全粘在键盘的主键区不拿下来,在你头脑完全清醒的情况下的确会更方便。在介绍Neovim前,你要知道Vim是一个模式编辑器,与常见的编辑器不同,默认进入的 normal 模式是不能直接输入的, normal 模式的功能包含了大量的热键以及能让你进入其他模式的动作。在 normal 模式下:
-
hjkl在normal模式下代表←↓↑→,使用这个方法的好处在于你移动光标的时候手不用移出主键区。 -
输入
i能进入insert模式,在这个模式下可以对文本进行编辑。 -
输入
a则会让光标后退一格,再进入insert模式。同理o是在光标的下一行插入一个空行并进入insert模式;O是在光标的上一行插入空行。 -
输入
v进入visual模式,在这个模式下,你移动光标相当于用鼠标左键选择内容。 -
输入
:进入command模式,这个模式用于输入真正意义上的命令,并使用回车以使用命令。最常用的两个命令:w用于保存当前工作;q用于退出Nvim窗口;!可接在任何命令后,代表忽略警告,强制执行命令;split用于分屏。
Nvim使用了Lua作为配置语言,相比TOML其具有更强的灵活性(在配置文件里写函数,有点过于灵活了),但也更加复杂,因此新手接触Nvim的第一件事就是去抄一份配置文件,然后照教程修改。虽然我不推荐使用预配置文件(热键习惯还是按照自己的来比较好),但其实LunarVim做的不错,就是配置写的有点复杂了,新手看着可能会手忙脚乱。如果非要用预配置的话,LazyVim是一个不错的选择,它使用了 lazy.nvim 的组织形式。对于一个Nvim配置文件,第一件事就是明确插件系统,并配置自己的 init.lua 。
我的Neovim配置如下,你可以参考:
init.lua 和 lazy.nvim 的配置
安装 lazy.nvim 并认识 nvim 的配置文件结构
安装 lazy.nvim 的方法在 🛠️ Installation | lazy.nvim ,我推荐使用结构化安装的形式,便于后续的插件管理。安装好 lazy.nvim 后,你的配置目录应该是这样的:
~/.config/nvim├── lua│ ├── config│ │ └── lazy.lua│ └── plugins│ ├── spec1.lua│ ├── **│ └── spec2.lua└── init.lua接下来就应该配置一下 init.lua 了,一般要配置的内容如下:
-- 使用行号vim.wo.number = true-- 使用相对行号-- 在同时使用number和relativenumber的情况下,会在光标所在行显示绝对行号,其他行显示相对行号vim.wo.relativenumber = true-- 设置缩进为4vim.o.tabstop = 4vim.bo.tabstop = 4vim.o.softtabstop = 4vim.o.shiftround = truevim.o.shiftwidth = 4---高亮所在行vim.wo.cursorline = true-- 查找的其他结果是否需要高亮vim.opt.hlsearch = true---使光标距离窗口一定行数vim.opt.scrolloff = 5---自动补全,但不自动选中vim.g.completeopt = "menu,menuone,noselect,noinsert"---补全显示10行vim.o.pumheight = 10---开启系统剪切板和真彩色vim.o.clipboard = 'unnamedplus'vim.o.termguicolors = true---导入lazy.nvim和热键绑定require("config.lazy")require("config.keybindings")你可以在之后将自己喜欢的配置填在 init.lua 中,接下来我们配置一些热键,你需要在上述的 config.keybindings 也就是 nvim/lua/config/keybindings.lua 中填入热键配置,之后我们用这个文件来对热键进行统一管理:
-- 定义几个函数,令配置看起来更简洁local map = vim.api.nvim_set_keymap-- vim.keymap.set可以接受lua函数作为其第三个参数,-- 这使得它可以映射vim.api.nvim_set_keymap无法映射的功能local maps = vim.keymap.set-- 将热键配置为不要覆盖,且关闭命令回显local opt = {noremap = true, silent = true }-- 设置leader键,自定义的热键前缀vim.g.mapleader = ' '-- 设置normal模式下的快捷键,这里设置了<space>+hjkl来切换窗口-- map所接受的参数为:(模式, 热键, 命令, 附加选项)map('n', '<leader>h', '<Cmd> wincmd h <CR>', opt)map('n', '<leader>j', '<Cmd> wincmd j <CR>', opt)map('n', '<leader>k', '<Cmd> wincmd k <CR>', opt)map('n', '<leader>l', '<Cmd> wincmd l <CR>', opt)配置插件
接下来就是最激动人心的时刻,是时候配置插件了。不可否认,Vim没有插件也很好用,但没有插件的Nvim完全不能拿来写脚本和程序。介绍一下我在使用的插件目录:
plugins├── blink-cmp.lua # 自动补全引擎,现在最好的补全引擎就是blink├── colorscheme.lua # 色彩方案,一个好的色彩方案能有效缓解疲劳├── hlchunk.lua # 缩进提示插件├── mason.lua # language-server-protocol管理插件├── nvim-autopairs.lua # 自动补全括号、引号等├── nvim-bufferline.lua # 显示缓冲区的插件├── nvim-dap.lua # 调试接口插件├── nvim-lualine.lua # 替换Vim原本的底栏├── nvim-numbertoggle.lua # 更好的切换行号显示├── nvim-scrollview.lua # 滚动条插件├── nvim-tree.lua # 文件树目录插件├── nvim-treesitter.lua # 代码高亮插件,使用了treesitter├── rainbow-delimiters.lua # 彩虹括号,方便分辨括号层级├── render-markdown.lua # markdown渲染插件├── snacks.lua # 一些实用小工具├── toggleterm.lua # 在Nvim中直接使用命令行└── yazi-nvim.lua # 在Nvim中使用yazi,一个命令行文件管理器以上述的 colorscheme.lua 为例,我来介绍一下 lazy.nvim 所定义的插件接口:
return{ "akinsho/bufferline.nvim", after = 'catppuccin', version = "*", dependencies = { "nvim-tree/nvim-web-devicons", }, config = function () vim.opt.termguicolors = true require("bufferline").setup{ options = { indicator = { icon = '▎', style = 'icon', }, offsets = { { filetype = "NvimTree", text = "File Explorer", text_align = "center", highlight = 'Directory', separator = true } }, } } end,}所有插件的配置均被包含在 return {} 中,其内部均是插件所定义的配置。 "akinsho/bufferline.nvim" 是插件的github仓库名; after 表明该插件只会在特定插件之后启动; version 锁定了插件的版本,只在你想使用特定版本的情况下才会使用; dependencies 表示该插件依赖某几个插件才能正常工作, lazy.nvim 会自动安装他们。config = function() 定义了一段加载插件的命令,其中 require("bufferline").setup({}) 是手动启动插件的命令, {} 内写入插件的自定义配置,不写的部分使用默认配置。不写 config = function() 也是可以的,这时插件会使用默认配置 lazy load 懒加载。注意,一些插件在懒加载的时候会出问题,将它们切换为手动加载能避免问题。
结语
这就已经是 lazy.nvim 配置Neovim的全部过程了,实际上还有相当多的内容没有讲,尤其是关于补全的部分。如何使用 blink 补全引擎和 mason 管理LSP我并不打算放在这里将清楚,因为他们的内容实在是太多了,一篇内容很难讲的完。Neovim作为一个关心性能的编辑器,其启动速度和性能优化一直都是值得说道的内容,而且Windows上的Neovim其实还挺慢的,在 wsl 里用就有肉眼可见的速度提升,不仅如此,Windows上还会遇见神秘的 ShaDa bug。