首页
归档
友情链接
关于
Search
1
在wsl2中安装archlinux
105 阅读
2
nvim番外之将配置的插件管理器更新为lazy
78 阅读
3
2018总结与2019规划
62 阅读
4
PDF标准详解(五)——图形状态
40 阅读
5
为 MariaDB 配置远程访问权限
33 阅读
软件与环境配置
博客搭建
从0开始配置vim
Vim 从嫌弃到依赖
archlinux
Emacs
MySQL
Git与Github
AndroidStudio
cmake
读书笔记
编程
PDF 标准
从0自制解释器
qt
C/C++语言
Windows 编程
Python
Java
算法与数据结构
PE结构
Thinking
FIRE
菜谱
登录
Search
标签搜索
c++
c
学习笔记
windows
文本操作术
编辑器
NeoVim
Vim
win32
VimScript
emacs
linux
文本编辑器
Java
elisp
反汇编
OLEDB
数据库编程
数据结构
内核编程
Masimaro
累计撰写
314
篇文章
累计收到
31
条评论
首页
栏目
软件与环境配置
博客搭建
从0开始配置vim
Vim 从嫌弃到依赖
archlinux
Emacs
MySQL
Git与Github
AndroidStudio
cmake
读书笔记
编程
PDF 标准
从0自制解释器
qt
C/C++语言
Windows 编程
Python
Java
算法与数据结构
PE结构
Thinking
FIRE
菜谱
页面
归档
友情链接
关于
搜索到
62
篇与
的结果
2022-08-19
从零开始配置 vim(17)——快捷键提示
之前我们定义了各种各样的快捷键,有为了增强功能自定义的,有针对插件的。数量一多有的时候就不那么容易记忆了。要是每次要去配置文件找我定义了哪些快捷键肯定会影响使用的。本篇将要介绍一个插件,它是快捷键的一个词典,可以快速找到我们想要的快捷键安装使用 packer 的小伙伴可以使用如下代码进行安装use {"folke/which-key.nvim"}然后我们新建一个文件作为它的配置文件,并写入如下代码require("which-key").setup({})这个时候我们使用一些快捷键并且在中间停顿一下就可以看到它已经给出了相关的提示了配置默认的配置已经足够好了,基本不需要我们对它的行为做某些配置。它真正强大的地方在于,我们可以自己注册快捷键到显示中去。有时候不知道什么原因某些插件或者我们自定义的快捷键无法显示时可以使用这个方法注册到显示中。假设我们现在有一个 <leader>ff 的键,它用来打开配置文件,但是它在 which-key 中没有显示出来,我们可以使用它的 register 方法来注册。该方法原型如下register(mappings, opts)它接收两个 table 参数,第一个表示需要注册的快捷键绑定,第二个是注册时的一些属性。mappings 中的字段主要用来定义快捷键以及它的显示文字,后面我们通过例子来体会它的具体参数opts 主要有下面几个参数mode: 表示模式,与nvim_set_keymap第一个参数中的模式相同prefix: 前置键,我们触发该条快捷键需要的前置键,一般使用leader作为前置键buffer: 命令对应的缓冲区id,用它来指定这个绑定作用于某个局部缓冲区silent: 同我们之间介绍的 nvim_set_keymap中的 silent含义noremap: 快捷键不进行递归传递接下来我们通过几个例子来体会它的用法local wk = require("which-key") wk.register({ f = { name = "myvimrc", -- 指定该快捷键组的名称 f = {":edit $MYVIMRC<CR>", "Open vimrc"}, -- 创建新的快捷键绑定 s = {":source $MYVIMRC<CR>", "reload vimrc", noremap = true}, -- 也可以只显示一个标签而不绑定到具体的快捷键 e = {"New File"} } }, {prefix = "<leader>"})通过上面的代码我们绑定了 <leader>ff、<leader>fs 和 <leader>fe 这三个快捷键。我们可以尝试一下执行 <leader>ff 发现它确实打开了我们的配置文件,而且我们稍微停顿一下它也给出了提示我们将这个改写一下wk.register({ ["<leader>"] = { f = { name = "myvimrc", -- 指定该快捷键组的名称 f = {":edit $MYVIMRC<CR>", "Open vimrc"}, -- 创建新的快捷键绑定 s = {":source $MYVIMRC<CR>", "reload vimrc", noremap = true}, -- 也可以只显示一个标签而不绑定到具体的快捷键 e = {"New File"} } } }, {silent = true, noremap = true})或者也可以改写为这样wk.register({ ["<leader>f"] = { name = "myvimrc", f = { ":edit $MYVIMRC<CR>", "Open vimrc" }, s = { ":source $MYVIMRC<CR>", "reload vimrc", noremap = true }, n = { "New File" }, }, })wk.register({ ["<leader>f"] = { name = "myvimrc" }, ["<leader>ff"] = { ":edit $MYVIMRC<CR>", "Open vimrc" }, ["<leader>fs"] = { ":source $MYVIMRC<CR>", "reload vimrc", noremap = true }, ["<leader>fn"] = { "New File" }, })到这里相信各位小伙伴应该已经明白了如何使用 mappings这个字段,它外层是每次按下的按键,最内层则用来绑定具体的命令和提示时显示的具体内容。一般来说我们用不到这个东西,但是如果希望动态的修改这个显示的内容,例如把快捷键归类,这个就很有用了。我们可以对照一下之前定义的快捷键,发现分屏相关的快捷键并没有显示出提示,这个时候我们就可以将它添加到对应的快捷键中wk.register({ ["s"] = { name = "split window", v = { ":vsp<CR>", "vertical split window" }, h = { ":sh<CR>", "horizontal split window"}, c = { ":close<CR>", "close this window"}, o = { ":only<CR>", "close all but this window"}, }, }, {noremap = true, silent = true})如果你不喜欢它用英文显示,还可以尝试 将所有英文提示改为中文,这是一个浩大的工程,有兴趣的小伙伴可以尝试一下查看所有快捷键绑定有时候我们不知道某个功能具体绑定到哪个键上面了,甚至不知道它有这个快捷键绑定,这个时候可以使用 :WhichKey 这个命令来检查一下。它默认有2个参数第一个参数是一个字符串,查看所有以此字符串为开头的快捷键,例如使用 :WhichKey <leader>s 来查看所有以 <leader>s开头的快捷键第二个参数一个是表示模式的字符,用来限定它只显示绑定在某个模式中的快捷键,例如 :WhichKey<leader>s n 只显示在 normal 模式下的快捷键好了,本篇的内容到此就结束了。
2022年08月19日
8 阅读
0 评论
0 点赞
2022-08-18
从零开始配置 vim(16)——启动界面配置
不知道各位小伙伴用过 spacevim或者 LunarVim又或者 doomvim或者其他的什么 vim配置框架,我们发现他们的启动界面都做的比较好看,而我们默认进入的启动界面则显得比较素了。这篇文章我们将来教大家使用插件打造属于自己的启动界面使用 dashboard-nvim 插件这部分我主要使用的是插件 dashboard-nvim 。与之前的插件类似,我们可以使用下面的语句来安装use {'glepnir/dashboard-nvim'}我们可以使用如下语句来加载该插件local db = require("dashboard")然后我们重新进入 neovim 之后,发现它已经给我们显示了一个默认的启动界面针对启动界面的配置分为三个部分,显示头信息、中间内容以及底部的内容。我们来分别对其进行配置配置显示头图中使用蓝色显示的 dashboard为显示头,我们可以使用 custom_header变量进行配置。官方贴心的给了很多使用ascii字符显示的图片可以供我们选择(ascii-text-header),例如我们使用如下的配置db.custom_header = { ' ⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣴⣶⣶⣶⣶⣶⠶⣶⣤⣤⣀⠀⠀⠀⠀⠀⠀ ', ' ⠀⠀⠀⠀⠀⠀⠀⢀⣤⣾⣿⣿⣿⠁⠀⢀⠈⢿⢀⣀⠀⠹⣿⣿⣿⣦⣄⠀⠀⠀ ', ' ⠀⠀⠀⠀⠀⠀⣴⣿⣿⣿⣿⣿⠿⠀⠀⣟⡇⢘⣾⣽⠀⠀⡏⠉⠙⢛⣿⣷⡖⠀ ', ' ⠀⠀⠀⠀⠀⣾⣿⣿⡿⠿⠷⠶⠤⠙⠒⠀⠒⢻⣿⣿⡷⠋⠀⠴⠞⠋⠁⢙⣿⣄ ', ' ⠀⠀⠀⠀⢸⣿⣿⣯⣤⣤⣤⣤⣤⡄⠀⠀⠀⠀⠉⢹⡄⠀⠀⠀⠛⠛⠋⠉⠹⡇ ', ' ⠀⠀⠀⠀⢸⣿⣿⠀⠀⠀⣀⣠⣤⣤⣤⣤⣤⣤⣤⣼⣇⣀⣀⣀⣛⣛⣒⣲⢾⡷ ', ' ⢀⠤⠒⠒⢼⣿⣿⠶⠞⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀⣼⠃ ', ' ⢮⠀⠀⠀⠀⣿⣿⣆⠀⠀⠻⣿⡿⠛⠉⠉⠁⠀⠉⠉⠛⠿⣿⣿⠟⠁⠀⣼⠃⠀ ', ' ⠈⠓⠶⣶⣾⣿⣿⣿⣧⡀⠀⠈⠒⢤⣀⣀⡀⠀⠀⣀⣀⡠⠚⠁⠀⢀⡼⠃⠀⠀ ', ' ⠀⠀⠀⠈⢿⣿⣿⣿⣿⣿⣷⣤⣤⣤⣤⣭⣭⣭⣭⣭⣥⣤⣤⣤⣴⣟⠁ ', }我们再次打开就发现头已经变成哆啦A梦了。如果你喜欢彩色样式的话,官方已经给出了解决办法了。可以通过 lolcat 或者 ueberzug 来生成彩色图片,然后嵌入到 custom_header 变量中。这里就不过多演示了定义中间部分中间部分表示的是它显示为 Please Config your own center section 这块的内容。我们可以使用 custom_center 来定义custom_center 是一个 table。它的每个部分对应着一条显示。每条显示和功能我们可以使用如下字段来进行定制icon : 当前显示图标desc:某个功能的描述信息,后面会原样显示出来shortcut:快捷键action:在某项位置回车时执行的命令我们按照官方给出的截图上的功能进行定义db.custom_center = { {icon = " ", desc = 'Recently lastest session ', shortcut = "Leader s l", action = ""}, {icon = " ", desc = "Recently opened files ", shortcut = "Leader f h", action = ""}, {icon = " ", desc = "Find File ", shortcut = "leader f f", action = ""}, {icon = " ", desc = "File Browser ", shortcut = "leader f b", action = ""}, {icon = " ", desc = "Find Word ", shortcut = "leader f w", action = ""}, {icon = " ", desc = "Open Personal dotfiles ", shortcut = "leader e e", action = "edit $MYVIMRC"} }其他地方的功能我们先不管,暂时在 action 这个字段上填上空,我们先实现最后打开个人配置文件那个位置的代码,我们在 action 中填入 edit $MYVIMRC。再次打开,我们发现它已经可以显示这些内容了并且我们在最后一项回车,发现它打开了当前配置文件各位可以尝试一下,它并不能帮助我们自动将 shortcut 字段与 action 结合绑定为快捷键。仅仅作为一行的几个元素进行显示而已。而 action 则是按下回车会执行的命令footer 定义footer这部分与之前定义 header类似,也是一个 table组成的字符串。 这里我们可以对他进行一些扩展,例如我这里可以使用下面的函数获取到底加载了哪些插件作为我们优化启动速度的依据db.custom_footer = function() local footer = {'', '🎉 Have fun with neovim'} if packer_plugins ~= nil then local count = #vim.tbl_keys(packer_plugins) footer[2] = '🎉 neovim loaded ' .. count .. ' plugins' for key, value in pairs(packer_plugins) do table.insert(footer, '✨ ' .. key) end end print(footer) return footer end我们再次重启 neovim 之后发现,它已经帮我们显示了它加载了哪些插件我们发现关于主题的插件它加载了两个,后面我们可以选择注释掉一个。本篇就到此结束了,剩下的插件我们在下一篇继续介绍
2022年08月18日
5 阅读
0 评论
1 点赞
2022-08-17
从零开始配置 vim(15)——状态栏配置
vim 下侧有一个状态栏,会显示当前打开的文件等一系列内容,只是我们很少去关注它。而且原生的vim也支持对状态栏进行自定义。这篇文章主要介绍如何自定义状态栏设置状态栏我们可以采用 set statusline 来设置状态栏。例如我们输入 :set statusline=%f\ -\ FileType=%y。之后我们可以发现它变成了如下这个样子statusline 的值是一个格式字符串。上述命令我们使用了 %f 表示当前文件名称 。从上面的命令中明显感觉到只输出两个内容就已经开始显的比较繁琐了,如果显示的内容多了是不是就更加难以阅读和书写了呢?好在我们还能使用 lua来做设置。上述内容可以翻译为如下的 lua代码vim.o.statusline = "%f - FileType=%y"我们保存之后发现下方的状态栏显示内容已经发生变化。控制边距和宽度如果你写过 c 或者其他编程语言中的输出语句,应该很容易理解如何控制输出的格式,一般使用类似 %4l` 这样的语句来控制该项占4个字符宽度。这里的设置也是类似的vim.o.statusline = "%20f - FileType=%y"它表示 文件名这项应该站20个字符宽度。最终效果如下所示默认它的边距是添加在左边的,这样会让左侧空出一大半,会显得比较难看,我们可以使用 -来使空白站位符显示在右侧vim.o.statusline = "%-20f - FileType=%y"当然我们也可以控制一下输出字符的最大长度,例如使用如下代码vim.o.statusline = "%0.10F - FileType=%y"使用 %F可以显示文件的全路径。这里我们发现全路径大于10个字符,但是它只是显示了10个字符。使用这个方法可以防止某些超长的字符串破坏了我之前的布局分割我们再来介绍一个符号 %=,它表示将 %= 后面的内容全局居右对齐,例如vim.o.statusline = "%f %= FileType=%y"将得到如下显示内容更多的关于各个标识符代表的含义可以使用 :help statusline 来查看。练习最后我们来做一个小练习,我们希望将状态栏显示为如下内容mode | filename[status] | currentline:totalline |encoding|filetype|其中 mode 代表当前所处模式、filename 代表文件名称、status 代表文件状态(是否可读写、是否保存)、currentline 代表光标当前所在行数、totalline 代表文件一共多少行、encoding 代表文件编码、filetype 代表文件类型我们通过查阅文档可以知道:文件名称可以使用 %f 来显示文件状态可以使用 %m 来显示当前行可以使用 %l当前buffer总行数可以使用 %L文件类型可以使用 %y 来显示至于当前模式和文件类型我们先不管它,根据这些内容我们可以写下如下代码vim.o.statusline = "mode|%f%m|%l:%L%=encoding|%y"[+] 表示对缓冲区所做的修改还没有写入到磁盘中。执行:w写入之后发现它直接消失了我们可以通过 vim.g.encoding 来获取当前文件的编码方式,因此我们改一下当前代码vim.o.statusline = "mode|%f%m|%l:%L%=" .. vim.g.encoding .. "|%y"我们发现此时的状态已经改过来了。最麻烦的是模式,vim 中提供了一个可以获取当前模式的函数 mode 。但是在 lua 接口中我没有找到对应的函数。因此我们仍然采用在 lua 中调用 vimscript 的方式。这次我们使用函数 vim.api.nvim_eval()。它可以执行 vim 命令并将返回执行的结果。我们可以定义一个函数返回当前所处模式function get_mode() local mode = vim.api.nvim_eval([[mode]]) if mode == "n" then return "Normal" elseif mode == "v" then return "Visual" elseif mode == "i" then return "Insert" else return "" end end这里我们为了演示只返回了 3中模式的字符串,更多模式可以查看vim的帮助文档我们希望模式改变时对应的就修改 mode 对应的字段,此时我们应该采用自动命令。查看vim的用户手册我们发现,针对模式变化这一事件有一个叫做 ModeChanged 的事件类型,因此我们可以写下一些代码local cmd_statusline = vim.api.nvim_create_autogroup("SET_STATUS_LINE", {clear = true}) vim.api.nvim_create_autocmd({"ModeChanged"}, { pattern = "*", group = cmd_statusline, callback = function() local win_id = vim.api.nvim_eval([[win_getid()]]) --获取当前window id vim.wo[win_id].statusline = get_mode() .. "|%f%m|%l:%L%=" .. vim.g.encoding .. "|%y" -- 使用 setlocal 针对窗口设置本地化配置 end )后面我们可以对字符串进行一些格式控制,这里就不展开了。我们将这些代码写到 init.lua中,保存后发现它大致效果如下我们发现就是简单的设置状态栏的工作也是比较麻烦的。而且有时候我们又想它好看,带点颜色什么的。这就更麻烦了。好在有大量的插件可以帮助我们来完成这一工作lualine 插件lualine 是一个用 lua 语言开发的 neovim 的状态栏美化插件,可以使用如下代码进行安装use { 'nvim-lualine/lualine.nvim', requires = { 'kyazdani42/nvim-web-devicons', opt = true } }我们创建 lualine 的配置文件,加入加载 lualine 的代码require("lualine").setup()然后在主配置文件中加载该文件require("plugin-config/lualine")lualine 官方提供了3种主题的配色,我们可以直接在代码中引用,例如我这里引用 evil_lualine 这个配置,然后将 theme改为之前我们安装的 tokyonight主题theme = "tokyonight"到这里我们已经完成了 状态栏的美化,其实主要靠插件,本篇一大部分写了如何使用原生的statusline 设置主要是自己手工设置比较有意思,而且也可以凑文章字数,其实你不知道statusline 这个也无所谓,很多插件都都对原生的方式进行了大量封装,而且能进行高度的自定义。完全可以满足你各种奇怪的口味。当然状态栏配置并不只有这一种插件,如果你知道有哪些状态栏的插件也欢迎在评论区留言给出
2022年08月17日
23 阅读
0 评论
1 点赞
2022-08-16
从零开始配置 vim(14)——目录管理插件
我们在介绍vim目录管理的时候提到 vim自带一个 叫做 netrw的工具来管理目录。但是它自身的功能有限,而且样式也丑。今天我们将使用其他强大的插件来替代 netrw,增强目录管理功能nvim-tree 插件安装使用增强目录管理功能我们采用 nvim-tree 插件。根据对应文档的描述,我们可以使用如下代码进行安装use { 'kyazdani42/nvim-tree.lua', requires = { 'kyazdani42/nvim-web-devicons', -- optional, for file icons }, tag = 'nightly' -- optional, updated every week. (see issue #1193) }安装完成之后我们新建一个文件 plugin-config/nvimtree.lua 用来保存它的配置信息。该文件中先写入以下内容用于加载启动 nvim-tree 插件require("nvim-tree").setup()之后我们可以使用命令 :NvimTreeToggle 打开文件树,再次使用该命令可以关闭文件树。打开之后我们发现一个问题,打开文件树之后,标签页仍然是居左对齐的。影响观看,我们应该让 tab 标签跟着往右移动一些距离。如何配置,我们可以在 bufferline 插件官方找到offsets = { { filetype = "NvimTree", text = "File Explorer", highlight = "Directory", text_align = "left" } }将这段代码添加到 bufferline.lua 的设置中,此时我们的 bufferline.lua 设置的代码应该变为如下这样require("bufferline").setup{ options = { mode = "buffers", numbers = "ordinal", offsets = { { filetype = "NvimTree", text = "File Explorer", highlight = "Directory", text_align = "left" } } } }我们先映射一个快捷键,用于打开或者关闭文件树vim.api.nvim_set_keymap("n", "<F2>", ":NvimTreeToggle<CR>", {noremap = true, silent = true})配置我们可以对其进行一些配置,例如这里我不想它显示 .git 目录中的内容,但是想保留 .gitignore 的显示。我们可以使用如下配置require("nvim-tree").setup({ -- 关闭文件时,自动关闭 auto_close = true, filters = { -- 不显示 .git 目录中的内容 custom = { ".git/" }, -- 显示 .gitignore exclude = { ".gitignore" }, -- 不显示隐藏文件 dotfiles = true }, -- 以图标显示git 状态 git = { enable = true } })使用我们使用该插件最大的目的不是为了显示目录的树形结构,而是为了快速管理文件,例如我们可以通过树快速打开、查找文件,甚至通过树快速创建、删除、移动、拷贝文件和目录r:重命名文件或者目录a:创建一个文件d: 删除一个文件(需要最后确认)x: 剪切一个文件到剪切板或者从剪切板移除一个剪切c:拷贝一个文件到剪切板或者从剪切板移除一个拷贝p: 粘贴文件或者目录当然它还有其他许多快捷键,只是其他的我很少使用,所以这里就不列举了。如果你对这些快捷键不太满意,可以重新定义。例如我们介绍 ntrw 的时候知道它也可以进行目录管理,为了减少记忆负担,你也可以采用 ntrw 的快捷键。我们在 setup 函数中添加如下代码view = { mappings = { list = { -- 定义快捷键 {key = "%", action = "create"}, {key = "d", action = "create"}, {key = "R", action = "rename"}, {key = "D", action = "remove"} } } }这里仅仅给大家做一个演示,我自己并不推荐采用这种方式。我更喜欢它原版的快捷键。另外从我的使用习惯来说,我在需要进行跳转的时候多数用的是标签、跳转到定义、gf甚至采用 :find 这种形式。使用它只是为了查看目录结构以及进行目录结构的管理。
2022年08月16日
7 阅读
0 评论
1 点赞
2022-08-12
从零开始配置 vim(13)——标签页插件
原始的vim中标签页已经足够好用了。你完全可以使用原始 vim 提供的功能,但是使用插件可以让它更好看。这里我比较喜欢使用 bufferline 这个插件安装首先我们来安装它, 在使用 packer 的前提下,你可以使用如下代码-- using packer.nvim use {'akinsho/bufferline.nvim', tag = "v2.*", requires = 'kyazdani42/nvim-web-devicons'}它的效果如下配置注意这里的 v2 只支持 neovim0.7 以上的 版本,如果你使用的 0.6 版本,应该将这里的 tag 改为 tag = 'v1.*'vim.opt.termguicolors = true require("bufferline").setup{}启用之后我们发现它将所有缓冲区都以标签页的形式显示出来了。这会对我们的理解造成困扰,我们可以对它进行一些配置,更改默认行为vim.opt.termguicolors = true require("bufferline").setup{ options = { -- 模式改为 tabs ,只显示真实的tabs不显示buffer mode = "tabs", } }但是使用默认的 buffers 模式有一个好处那就是将切换 buffer 的操作和切换 tab 的操作统一了。统一使用 BufferLineCycleNext 和 BufferLineCyclePrev。我们可以映射快捷键快速在 buffer 和 tab 之间进行切换。因此我还是比较推荐使用 buffers 模式的。这里我采用我比较熟悉的配置vim.opt.termguicolors = true require("bufferline").setup{ options = { mode = "buffer", -- 显示id number = "ordinal" } } -- 快速在buffer间跳转 vim.api.nvim_set_keymap("n", "<leader>1", ":BufferLineGoToBuffer 1<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<leader>2", ":BufferLineGoToBuffer 2<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<leader>3", ":BufferLineGoToBuffer 3<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<leader>4", ":BufferLineGoToBuffer 4<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<leader>5", ":BufferLineGoToBuffer 5<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<leader>6", ":BufferLineGoToBuffer 6<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<leader>7", ":BufferLineGoToBuffer 7<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<leader>8", ":BufferLineGoToBuffer 8<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<leader>9", ":BufferLineGoToBuffer 9<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<leader>bg", ":BufferLinePick", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "gt", ":BufferLineCycleNext<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "gT", ":BufferLineCyclePrev<CR>", {noremap = true, silent = true})number 属性默认有3个值,buffer_id、ordinal、both。buffer_id 代表真实的缓冲区 id,ordinal 应该是由该插件指定的一个 id,它与 buffer_id 并不相同,这里我们还是采用它默认的 ordinal 选项。注意这里的数字并不代表标签页所对应的数字,而是在可见区域中第几个标签页。例如有下面一些标签页<- (30) | buf31 | buf32 | buf33 | buf34 | buf35 | buf36 | buf37 (24) ->当前显示的是第31个 buffer 的内容。如果我么我们想要显示第34号buffer的内容,可以使用 <leader>4。我们已经有了针对 tab 和 buffer 的快速跳转的快捷键,因此之前定义的基础快捷键中针对 tab 操作的就都可以删掉了。主要是这么几行--- 配置tabline快捷键,主要以 t开头代表 t --- 关闭当前标签页 --vim.api.nvim_set_keymap("n", "tc", ":tabclose<CR>", {noremap = true, silent = true}) --- 关闭所有标签页,仅保留当前标签页 --vim.api.nvim_set_keymap("n", "to", ":tabonly<CR>", {noremap = true, silent = true}) --- gt 切换到下一个,gT切换到上一个接下来为了方便 buffer的管理。我们来配置两个有用的功能。关闭当前buffer还记得我们介绍 buffer 的时候介绍过,我们可以使用 :bdelete {fname} 来删除一个 buffer。{fname}可以是buffer的id也可以是buffer的名称。不管使用哪种办法,首先要获取当前所在 buffer的名称或者id。我们以获取 name 为例。 在介绍命令模式的时候说过 % 可以代表当前文件的名称。而 buffer 的名称与当前所关联的文件名称相同。所以这里我们完全可以使用 %来作为 当前要删除的 buffer 的名称vim.api.nvim_set_keymap("n", "<leader>bc", ":bdelete %<CR>", {noremap = true, silent = true})或者我们可以使用 BufferLinePickClose 命令来快速关闭某一个 buffer 。我们可以再定义一个快捷键vim.api.nvim_set_keymap("n", "<leader>bp", ":BufferLinePickClose<CR>", {noremap = true, silent = true})什么是 pick 呢?简单来说它会将所有标签页都标记一个字母,然后等待用户按下标签所对应的字母,以便对对应标签页进行操作。他的效果如下图第二种形式统一了 tab 和 buffer 的行为。我自己基本不使用 tab。因为使用第二种方式多了一次选buffer 的操作,所以我采取第一种办法删除当前 bufer。后面的用来删除其他不想要的 buffer 或者 tab。关闭除当前buffer外的所有buffer这部分的功能我们可以使用借助 BufferLine 提供的两个删除函数 BufferLineCloseLeft 和 BufferLineCloseRight 来完成。它们分别用于删除当前 buffer 左侧所有的 buffer 以及删除右侧所有的 buffer。因此这里我们可以使用如下代码来定义这一行为vim.api.nvim_set_keymap("n", "<leader>bo", ":BufferLineCloseLeft<CR>:BufferLineCloseRight<CR>", {noremap = true, silent = true})本篇的内容到此就结束了,下一篇将介绍插件用来做目录管理。
2022年08月12日
11 阅读
0 评论
1 点赞
2022-08-11
从零开始配置 vim(12)——主题配置
在我们进一步增强vim的功能之前,我们先为vim准备一个漂亮的主题,毕竟对着一个丑陋原始的界面多少有点提不起劲来进行编程。长时间对着丑陋的界面多多少少会产生抑郁情绪的。下面推荐几款我觉得还不错的主题插件tokyonight官方仓库在使用 packer 作为插件管理器的前提下可以使用use 'folke/tokyonight.nvim'来安装该插件我们在 init.lua中添加启用该主题的代码vim.cmd[[colorscheme tokyonight]]我们发现 此时已经变得好看了点为了配置该主题,我们在 lua目录中中新建一个 plugin-config 目录,专门用来放置各种插件的配置文件。例如针对这个主题的配置应该放在 lua/plugin-config/tokyonight.lua 中。我们在 init.lua 中引用它require("plugin-config/tokyonight")我们在 tokyonight 中放入下面的配置-- 配置主题颜色模式为 storm vim.g.tokyonight_style = "storm" -- 允许neovim中的终端使用该主题配色 vim.g.tokyonight_terminal_colors = true -- 注释使用斜体 vim.g.tokyonight_italic_comments = true最后的效果大致如图所示vscode再来推荐一个我比较喜欢的主题——vscode.nvim这是一个使用lua实现的vscode的配色主题,支持暗色和亮色两种模式。在 packer 的配置中,我们可以加入如下代码use 'Mofiqul/vscode.nvim'同样的可以使用 vim.cmd[[colorscheme vscode]] 来启用该主题我们可以在 plugin-config 中创建一个 vscode.lua 的文件来配置该主题-- 使用 dark 主题 1 vim.o.background = 'dark' local c = require('vscode.colors') require('vscode').setup({ -- 允许透明背景 transparent = true, -- 注释使用斜体 italic_comments = true, -- 禁止使用 nvim-tree 背景色 disable_nvimtree_bg = true, -- 重写部分元素配色 color_overrides = { vscLineNumber = '#FFFFFF', }, })最后我们也需要在 init.lua 中加载它require('plugin-config/vscode')最后的效果如下所示对比起来我更喜欢 tokyonight 主题,如果你有喜欢的主题或者配色也可以在评论区给出
2022年08月11日
16 阅读
0 评论
0 点赞
2022-08-10
从零开始配置 vim(11)——插件管理
之前我们介绍了基础配置部分和快捷键配置部分。如果你配置了这两个部分,vim已经算是比较好用了。但是作为代码编辑器来讲还是显的比较简陋,用这些配置来完成日常的编码任务会显得力不从心。vim比较强大的一点是它拥有丰富的插件系统。大量高手在上面为它开发各种形式的插件。今天我们将从插件管理开始,利用前人的成果丰富我们的vim功能使用lua添加自动命令组在正式开始介绍插件之前我们先优化一下加载配置文件的时机。之前我们介绍自动命令的时候已经给出了如何自动加载配置augroup NVIMRC autocmd! autocmd BufWritePost init.lua source % augroup END在使用vimscript的场合它可以正常工作。但是如何在 neovim中配置它呢?目前有两种解决办法使用新版 neovim api在 neovim0.7 版本以后,我们可以使用下列 api 来创建并使用自动命令组nvim_create_augroup({name}, {*opts}) : 创建自动命令组,如果创建成功,返回自动命令组的idnvim_create_autocmd({event}, {*opts}):创建自动命令。nvim_create_augroup 传递一个自动命令组的名称,另外它可以接受一个 table 作为属性值,目前属性值可以传入一个 clear 的布尔值,相当于是否执行 autocmd! 。nvim_create_autocmd,第一个参数是一个或者多个事件字符串组成的 table,它的含义与 autocmd 中的事件相同,用的字符串也相同。第二个参数是一个表示属性的 table。常用的有:group: 所属自动命令组pattern: autocmd中的 pattern部分callback: 一个lua的回调函数,当事件发生时,调用该回调函数command: 该字段可以填入一个 vim命令的字符串,相当于 autocmd中的 command部分我们要将上述代码改为 lua 版本,首先使用创建一个自动命令组local nvimrc = vim.api.nvim_create_augroup("NVIMRC", {clear = true})接着为了方便我们使用 command 字段来完成这个自动命令vim.api.nvim_create_autocmd({"BufWritePost"}, { pattern = "init.lua", group = nvimrc, command = "source %" })在上一篇文章中,我们已经初步有了划分模块的概念。随着配置的越来越多,以后在 init.lua 中一定伴随着大量的 require。我们可以通过 gf 快速跳转到对应的模块,但是前提条件是我们已经设置了 path 变量。每次退出 nvim 再进来,需要重新设置,有没有觉得很麻烦呢?如果我们使用自动命令组,在进入 init.lua 之后自动设置 path 就好了。我们学会了使用自动命令组之后,来自己实现这个需求vim.api.nvim_create_autocmd({"BufWritePost"}, { pattern = "init.lua", group = nvimrc, callback = function() vim.o.path = vim.o.path .. ",**/*" end })path 中可以添加多个路径作为文件搜索的路径,多个路径之间以 , 分割。我们之前说过可以使用 **/* 表示当前目录下所有文件。这样退出重新进入 nvim 之后不需要再次手动输入 path 了。在lua中执行vim命令在 0.7以前的版本中无法通过上述api来创建自动命令。但是它提供了执行vim命令的接口。我们可以使用 vim.cmd 来执行 vim 命令。它接收一个字符串参数,该字符串表示将要执行的 vim 命令。可以使用引号括起来,但是需要对其中的特殊字符进行转义。也可以使用 [[]] 来括起来,此时就不需要进行转义了。使用上述函数我们可以很轻松的实现上面的功能vim.cmd[[ augroup NVIMRC autocmd! autocmd BufWritePost init.lua source % autocmd BufReadPost init.lua set path+=**/* augroup END ]]两种方式各有千秋,但是既然使用 lua做配置,那么我想的是能使用 lua的地方尽量用 lua。为了照顾还在使用 0.6 版本的小伙伴,我们先进行一下版本判断。最后的代码如下所示if vim.fn.has "nvim-0.7" then local nvimrc = vim.api.nvim_create_augroup("NVIMRC", {clear = true}) vim.api.nvim_create_autocmd({"BufWritePost"}, { pattern = "init.lua", group = nvimrc, command = "source %" }) vim.api.nvim_create_autocmd({"BufWritePost"}, { pattern = "init.lua", group = nvimrc, callback = function() vim.o.path = vim.o.path .. ",**/*" end }) else vim.cmd[[ augroup NVIMRC autocmd! autocmd BufWritePost init.lua source % autocmd BufReadPost init.lua set path+=**/* augroup END ]] end我将这段代码放到了 lua/autocmd.lua 中。所以我需要在 init.lua 中加载这个文件require("autocmd")插件管理在新版 neovim (版本大于 0.5 ) 中,一般推荐使用 packer 这个插件管理工具。根据官方的描述,我们使用如下方式来进行安装git clone --depth 1 https://github.com/wbthomason/packer.nvim\ ~/.local/share/nvim/site/pack/packer/start/packer.nvim根据官方的描述,我们可以在 lua/plugins.lua 中添加插件管理相关的代码。return require('packer').startup(function(use) -- Packer can manage itself use 'wbthomason/packer.nvim' -- 添加另外插件 end)接着我们需要在 init.lua 中加载这个文件require("plugins")后面我们可以使用下面的一些命令来对插件进行管理PackerInstall:先清理不需要的插件然后安装插件PackerClean: 清理不需要的插件PackerUpdate:先清理插件,然后更新已有的插件,再安装暂时没有的插件PackerSync: 包括 PackerClean和 PackerUpdate 的功能根据官方的描述,不管是要增删改哪些插件,都可以用 PackerSync 这一条命令搞定。完成之后我们可以使用 q来退出,如果出错可以使用 r来重新下载本篇就到这里了。后面几篇文章主要通过该插件管理工具来下载并配置一些插件,敬请期待!
2022年08月10日
10 阅读
0 评论
0 点赞
2022-08-09
从零开始配置 vim(10)——快捷键配置
之前我们对neovim 进行了基础的配置,这篇主要介绍我比较常用的快捷键配置。到这篇开始我们的配置已经可以为两个大的模块——基础配置和快捷键配置。我们的目录也应该按照模块来进行组织。在正式配置之前让我们先规划一下目录结构。当前我打算采用如下的目录格式📂 ~/.config/nvim ├── 📂 lua│ ├── 🌑 basic.lua # 用来存储基础配置│ ├── 🌑 keybindings.lua # 用来存储快捷键配置 └── 🌑 init.lua # 配置文件入口,主要用来加载其他配置文件lua模块加载还记得我们之前介绍过的 runtime 吗?在介绍文件类型的时候说过,runtime有两个路径,一个是系统路径位于 $VIMRUNTIME 中,第二个就是用户配置文件路径,可以使用$MYVIMRC来查看。在 Unix/Linux 平台,它位于 ~/.config/nvim 中,而模块路径就位于 runtime/lua 中。在 lua 语言中,加载模块可以使用 require() 。它传入一个不带 .lua 后缀的模块的相对路径。所以这里想要在 init.lua 中加载基础配置和 快捷键配置可以使用如下语句require('basic') require('keybindings')如果目录有多层,例如要加载 lua/basic/settings.lua 模块的话,可以使用 . 或者 / 来组织路径。require('basic/settings')这里我推荐使用 /。主要是为了使用 gf 快速跳转到对应路径。使用 . 的话 gf 并不会将它解析为目录结构,而是直接去找名为 basic.settings.lua 的文件。我们先创建好所有目录和文件,然后将之前的 init.lua 拷贝一份到 lua/basic.lua 中,并且创建文件 lua/keybindings.lua。然后修改 init.lua。require("basic") require("keybinds")快捷键配置这里我们事先设置 path路径,然后使用 gf快速跳转到不同文件。我们首先来设置 leader 键和 localleader键vim.g.mapleader = " " vim.g.maplocalleader = " "下面我们按照 《vim从嫌弃到依赖》这系列文章中介绍的顺序来配置快捷键标签页快捷键由于我自身很少用 标签页的功能,而且vim中自带的命令已经够高效的了,所以这里我基本没怎么定义快捷键-- 配置tabline快捷键,主要以 t开头代表 t -- 关闭当前标签页 vim.api.nvim_set_keymap("n", "tc", ":tabclose<cr>", {noremap = true, silent = true}) -- 关闭所有标签页,仅保留当前标签页 vim.api.nvim_set_keymap("n", "to", ":tabonly<cr>", {noremap = true, silent = true}) -- gt 切换到下一个,gT切换到上一个翻页代码翻页我主要采用 Ctrl + f和 Ctrl + b,代表 Foward 和 Backup。这里为了方便我将它们分别向上或者向下移动 10行。同时将光标至于中间位置,有时候光标在下面不好看它的上下文。vim.api.nvim_set_keymap("n", "<C-f>", "10jzz", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<C-b>", "10kzz", {noremap = true, silent = true})多窗口相关的操作多窗口快捷键我将它分为两个部分,一个是窗口本身的操作,主要是打开和关闭。第二个是窗口间跳转。第一类操作我采用 s(split)最为开头,第二类以 <leader> 键开头。-- 多窗口的打开与关闭 vim.api.nvim_set_keymap("n", "sv", ":vsp<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "sh", ":sp<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "sc", ":close<CR>", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "so", ":only<CR>", {noremap = true, silent = true}) -- 多窗口跳转 vim.api.nvim_set_keymap("n", "<leader>h", "<C-w>h", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<leader>l", "<C-w>l", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<leader>j", "<C-w>j", {noremap = true, silent = true}) vim.api.nvim_set_keymap("n", "<leader>k", "<C-w>k", {noremap = true, silent = true})其他有用的绑定这里我们将之前文章中用来当做例子的一部分比较有用的映射放上去-- 其他有用的绑定 -- 使用 <C-u> 将光标所在单词转化为全大写 vim.api.nvim_set_keymap("i", "<C-u>", "<esc>viwUwa", {noremap = true, silent = true}) -- 使用 <C-l> 将光标所在单词转化为全小写 vim.api.nvim_set_keymap("i", "<C-l>", "<esc>viwuwa", {noremap = true, silent = true}) -- dw删除当前光标所在单词 vim.api.nvim_set_keymap("n", "dw", "diw", {noremap = true, silent = true}) -- 快速打开vimrc文件 vim.api.nvim_set_keymap("n", "<leader>ee", ":vs $MYVIMRC<CR>", {noremap = true, silent = true}) -- 快速启用 vimrc vim.api.nvim_set_keymap("n", "<leader>ss", "source $MYVIMRC<CR>", {noremap = true, silent = true})本篇到这里就结束了,下一篇我们将要来介绍插件管理的相关内容,敬请期待
2022年08月09日
7 阅读
0 评论
1 点赞
2022-08-08
从零开始配置 vim(9)——初始配置
虽然本系列文章叫做从0开始配置vim,似乎我们从一开始就要写vimrc配置文件,但是我们并没有这么做。我们先经过几篇文章了解了下面的几个内容如何设置vim属性,从而改变vim的特征配置快捷键,以提高我们的使用效率使用自动命令,以便使用vim来自动化我们的相关操作这些既有vimscript的东西,也有vim自身一些特性的描述。拥有这些基础知识之后,在阅读其他人写的配置或者自己配置将会变得更加容易。当然关于vim我们还有很多内容没有讲,例如该如何自定义命令,如何弹出一个窗口,以及到最后如何编写自己的插件。如果后续在配置过程中涉及到新的内容,我将会给大家进行讲解,尽量让大家明白我们配置的每行代码都有哪些作用,让大家不仅仅是照着抄一遍,而是能举一反三,根据自己的习惯打造完全属于自己的 vim。话不多说,下面就让我们从0开始来一步一步的将原始落后的vim打造成现代化的好用的编辑器。相应的准备工作开始配置前,让我们进行一些准备工作。我们采用 neovim 进行配置,也打算使用 纯 lua 进行配置。如果你用的是 vim,请安装下载最新的 neovim。我本地的环境采用的是 neovim0.7.2 版本,你可以使用稍微低一点的版本,但至少保证版本在 0.6 及以上版本。(不要怪我一直变换版本,因为7以上的版本添加了自动命令的 lua 接口。)我随教程创建了一个 github仓库用于保存记录每次的配置,各位小伙伴可以克隆下来,也可以自己按照上面的目录结构和文章所描述的自己一步步手动组织。仓库地址: nvimrc-tutorial 。我们先使用 git clone https://github.com/aMonst/nvimrc-tutorial.git ~/.config/nvim 将仓库克隆到本地,然后在里面创建一个 init.lua 文件作为配置文件的入口基础配置我们在 init.lua 中写入如下内容作为基础配置-- 设置文件编码格式为 utf-8 vim.g.encoding = "utf-8" -- 设置终端编码格式为 utf-8 vim.o.termencoding = "utf-8" -- 开启语法高亮 vim.o.syntax = "enable" -- 显示相对行号 vim.o.relativenumber = true -- 显示行号 vim.o.number = true -- 高亮所在行 vim.o.cursorline = true -- 自动换行 vim.o.wrap = true -- 显示光标位置 vim.o.ruler = true -- 边输入边搜索 vim.o.incsearch = true -- 开启搜索匹配高亮 vim.o.hlsearch = true -- 搜索时自行判断是否需要忽略大小写 vim.o.smartcase = true -- tab键转换为 4 个空格 vim.o.tabstop = 4 vim.o.softtabstop = 4 vim.o.shiftwidth = 4 -- 新行对齐当前行,tab转换为空格 vim.o.expandtab = true vim.bo.expandtab = true vim.o.autoindent = true vim.bo.autoindent = true vim.o.smartindent = true -- << >> 缩进时移动的长度 vim.o.shiftwidth = 4 vim.bo.shiftwidth = 4 -- 使用jk移动光标时,上下方保留8行 vim.o.scrolloff = 8 vim.o.sidescrolloff = 8 -- 设置自动折叠 vim.o.smartindent = true -- 历史命令最多保存1000条 vim.o.history = 1000 -- 显示空白字符 vim.o.list = true -- 样式 vim.o.background = "dark" vim.o.termguicolors = true vim.opt.termguicolors = true完成之后,再次打开vim发现它已经变成了这样本篇就到这里了,下一篇我们将对默认的快捷键进行配置
2022年08月08日
9 阅读
0 评论
1 点赞
2022-08-05
从零开始配置 vim(8)——文件类型检测
在上一章介绍自动命令的时候,我们提到可以使用 FileType来根据文件类型来触发事件,但是关于文件类型并没有深入的介绍,本篇我们来补充关于文件类型相关的内容,让大家更好的理解,看不懂也没关系,你只需要知道vim能识别各种编程语言的文件并启用事先定义好的配置即可。事先做几点声明:跳过这篇文章对后面介绍的内容的理解不会有任何障碍,如果你不想看,直接拉到最后看结论即可1. 跳过这篇文章对后面介绍的内容的理解不会有任何障碍,如果你不想看,直接拉到最后看结论即可1. 跳过这篇文章对后面介绍的内容的理解不会有任何障碍,如果你不想看,直接拉到最后看结论即可1. 跳过这篇文章对后面介绍的内容的理解不会有任何障碍,如果你不想看,直接拉到最后看结论即可本篇文章会针对 neovim 的部分代码进行简单的剖析以便深入讲解文件类型。涉及到的 neovim 版本为 0.7.2,如果你使用的是更早版本,代码可能会不太一样,但是重点代码应该是一样的2. 本篇文章会针对 neovim 的部分代码进行简单的剖析以便深入讲解文件类型。涉及到的 neovim 版本为 0.7.2,如果你使用的是更早版本,代码可能会不太一样,但是重点代码应该是一样的2. 本篇文章会针对 neovim 的部分代码进行简单的剖析以便深入讲解文件类型。涉及到的 neovim 版本为 0.7.2,如果你使用的是更早版本,代码可能会不太一样,但是重点代码应该是一样的2. 本篇文章会针对 neovim 的部分代码进行简单的剖析以便深入讲解文件类型。涉及到的 neovim 版本为 0.7.2,如果你使用的是更早版本,代码可能会不太一样,但是重点代码应该是一样的里面的代码可能有些小伙伴并不能理解,但是我们只是通过代码来描述它的一些流程,不理解代码能理解这个流程也是OK的,再退一步即使不理解流程,也没关系,毕竟我们只需要知道它有这个功能,不需要知道它的细节,不理解细节完全不会阻碍我们使用并对它进行配置3. 里面的代码可能有些小伙伴并不能理解,但是我们只是通过代码来描述它的一些流程,不理解代码能理解这个流程也是OK的,再退一步即使不理解流程,也没关系,毕竟我们只需要知道它有这个功能,不需要知道它的细节,不理解细节完全不会阻碍我们使用并对它进行配置3. 里面的代码可能有些小伙伴并不能理解,但是我们只是通过代码来描述它的一些流程,不理解代码能理解这个流程也是OK的,再退一步即使不理解流程,也没关系,毕竟我们只需要知道它有这个功能,不需要知道它的细节,不理解细节完全不会阻碍我们使用并对它进行配置3. 里面的代码可能有些小伙伴并不能理解,但是我们只是通过代码来描述它的一些流程,不理解代码能理解这个流程也是OK的,再退一步即使不理解流程,也没关系,毕竟我们只需要知道它有这个功能,不需要知道它的细节,不理解细节完全不会阻碍我们使用并对它进行配置让我们进入相应的主题吧文件类型简介在 vim 中可以使用 filetype plugin indent on 来打开文件类型检测,而在 neovim 中已经默认打开了这些属性,因此我们可以不设置这些。我们可以使用 :filetype 来查看打开的状态。它会返回如下的内容 filetype detection:ON plugin:ON indent:ON 我们发现它包含了三个部分。上述的设置语句我们可以将它拆分成3个部分:filetype on filetype plugin on filetype indent on它打开了三个东西,文件类型检测,针对文件类型相关的插件,针对文件类型相关的缩进和隐藏代码块的格式。下面我们依次来介绍这些东西文件类型检测filetype on 将打开文件类型检测。如果该项被打开,vim 在初始化的时候会读取脚本 $VIMRUNTIME/filetype.vim 和 $VIMRUNTIME/filetype.lua 的内容。这两个脚本用来识别文件类型。$VIMRUNTIME 是 vim 里面的环境变量与 $MYVIMRC 类似,我们可以通过使用 :echo $VIMRUNTIME 来查看具体的路径,也可以直接在命令模式中将它当做一个路径来使用我们先来阅读以下 filetype.vim 的内容,在这段脚本中,我们可以发现大量这样的语句au BufNewFile,BufRead *.cxx,*.c++,*.hh,*.hxx,*.hpp,*.ipp,*.moc,*.tcc,*.inl setf cpp au BufNewFile,BufRead $VIMRUNTIME/doc/*.txt setf help au BufNewFile,BufRead .htaccess,*/etc/httpd/*.conf setf apache au BufNewFile,BufRead */etc/apache2/sites-*/*.com setf apache结合我们之前学习的自动命令相关的内容可以知道,这些代码会根据文件路径和后缀来自动设置文件类型。从这写代码中可以看到,vim 也是靠命令来设置文件类型的。使用 :setf 或者 使用 :set filetype=c 或者使用它的简写形式 set ft=c来设置文件类型除了根据文件后缀,vim 也可以根据文件内容来判别文件类型。我们进入到 filetype.lua 中可以看到,真正根据文件内容来决定类型是通过文件 script.vim 。该文件中主要使用正则表达式来匹配对应的特征值从而确定该文件类型,例如脚本中有这么一些代码elseif s:line1 =~# '<?\s*xml.*?>' set ft=xml " XHTML (e.g.: PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN") elseif s:line1 =~# '\<DTD\s\+XHTML\s' set ft=xhtml " HTML (e.g.: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN") " Avoid "doctype html", used by slim. elseif s:line1 =~? '<!DOCTYPE\s\+html\>' set ft=html elseif s:line1 =~? '-\*-.*C++.*-\*-' set ft=cpp如果我们的文件无法满足 vim 识别文件类型的要求,也可以在文件中添加注释来帮助 vim 进行识别例如使用如下注释来使vim 确定它是一个 c 的代码/* vim: ft=c */可以在注释中使用 vim: ft= 来设置文件类型。除了设置文件类型,这类注释还是设置像文件是否显示行号、列宽等等信息。更多信息可以查看 :help modeline 。文件类型插件在得到文件类型之后,vim 会根据文件类型加载不同的文件插件。它也是一个脚本,该脚本为 $VIMRUMTIME/ftplugin.vim 。打开这个文件,我们需要重点关注这么几句代码for name in split(s, '\.') exe 'runtime! ftplugin/' . name . '.vim ftplugin/' . name . '_*.vim ftplugin/' . name . '/*.vim' " Load lua ftplugins exe printf('runtime! ftplugin/%s.lua ftplugin/%s_*.lua ftplugin/%s/*.lua', name, name, name) endfor其中 s 是一个字符串,它是一个包含了扩展名的文件名,在这里以 . 作为分割,读取它以.分割的所有内容。例如 aaa.bbb 会被分割为 aaa 和 bbb。然后根据 aaa 和 bbb 来分别执行下面的循环exe 是用来执行对应文件内代码的语句。后面是一个字符串的拼接,假设当前打开的是一个.py 结尾的文件,对应的这句话就可以拼接为 exe 'runtim! ftplugin/py.vim ftplugin/py__*.vim' ftplugin/py/*.vim 。后面两句拼接的内容相似,只是一个是给vim 脚本用的,一个是给 lua 脚本用的。这里我们以 lua脚本为例。runtime! 你可以理解成 python 的 import 或者 c/c++ 中的 #include,加载文件的路径一个是 $VIMRUNTIME 所在路径,我们可以在 $VIMRUNTIME/ftplugin 目录中找到很多语言预定义的设置,还有一个是配置文件所在的根目录。对于 neovim 来说,这个路径就是 ~/.config/nvim 。这样我们就明白了,我们可以将对应文件类型的个性化配置放到 ~/.config/nvim/ftplugin 目录中。以 python 为例来说的话。它会加载 ftplugin/py.lua ,ftplugin/py_*.lua (以py 开头,以 .lua 结尾的文件), ftplugin/py/*.lua(py 目录下所有的lua文件)。这样以后针对不同语言的设置完全可以在 ftplugin 中以对应名字命名。从而更好的组织我们的目录结构。文件类型缩进文件类型缩进运行我们为不同类型的文件设置不同格式的缩进,例如有的习惯使用4空格缩进,有的习惯使用 2空格或者8空格缩进。定义缩进格式的脚本是 $VIMRUNTIME/indent.vim 。在这个文件中我们又见到了类似的写法for name in split(s, '\.') exe 'runtime! indent/' . name . '.vim' exe 'runtime! indent/' . name . '.lua' endfor有了上面讲解的基础,理解这段代码就容易多了,它这里加载的主要是 indent 目录中以后缀命名的缩进文件。但是它默认加载的文件比较少。从代码上看.py 文件如果使用 python.vim 应该是不会被加载的,但是它默认的目录中针对 python 的缩进仍然是以 python.vim 命名,就证明它是可以被加载的。这里我还不理解为什么会被加载。有知道的小伙伴可以在评论区留言,大家一起交流学习。 好了,本章内容就到这里了。前面分析了那么多内容,总结起来就很简单的几点# 最后的结论vim 可以根据文件后缀和文件内容来决定文件类型。如果无法决定也可以使用 set ft 来设置,或者在文件头部添加注释 vim: ft= 来知名类型我们可以针对不同文件类型进行个性化配置,包括插件和缩进,插件的用户配置文件的路径在 ~/.config/nvim/ftplugin 中,以类型名命名。缩进的配置在 ~/.config/nvim/indent 目录中,以类型名命名。
2022年08月05日
11 阅读
0 评论
0 点赞
1
2
3
4
...
7