Eric's Blog 时光荏苒,岁月如梭

Neovim 缓冲区(buffer)相关事件

2024-07-07
Eric Wong

起因

最近在使用 SpaceVim 的标签栏(tabline)时发现,对于新增的空内容的缓冲区(buffer),标签栏上方并不会列出。 检查源码发现标签栏跟踪缓冲区新增的代码只监听了:BufNewFileBufReadPost 事件。

vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufReadPost' }, {
  callback = vim.schedule_wrap(function(event)
    if
      vim.api.nvim_buf_is_valid(event.buf)
      and index(right_hide_bufs, event.buf) == -1
      and index(visiable_bufs, event.buf) == -1
      and index(left_hide_bufs, event.buf) == -1
    then
      table.insert(right_hide_bufs, event.buf)
    end
  end),
  group = tabline_augroup,
})

测试发现 :enew 命令及 :new 命令并不会触发这两个事件。修改源码增加监听 BufNew 事件

虽然问题是修复了,但是我觉得有必要整理下缓冲区相关事件的触发时机。

获取可用事件列表

可以使用命令 :echo getcompletion('Buf', 'event') 快速查看当前 Neovim 版本支持的缓冲区事件列表。

事件的触发时机

BufAdd

  1. 新增一个缓冲区至缓冲区列表
  2. 将一个 unlisted 缓冲区添加进 listed 缓冲区列表
  3. 修改 listed 缓冲区列表中某个缓冲区的名称

BufNew

  1. 新增一个缓冲区
  2. 修改缓冲区的名称

BufNewFile

  1. 当开始编辑一个不存在的文件时

测试示例

通过一些实例来测试事件触发的时机,测试代码如下:

需要忽略掉 *Cmd 事件,避免文件读写失败。

local log = require("spacevim.logger").derive("logevent")
local group = vim.api.nvim_create_augroup("logevent", { clear = true })
vim.api.nvim_create_autocmd(
	vim.tbl_filter(function(e)
		return not vim.endswith(e, "Cmd")
	end, vim.fn.getcompletion("Buf", "event")),
	{
		callback = vim.schedule_wrap(function(event)
			log.debug(event.event .. event.buf)
		end),
		group = group,
	}
)
  1. 执行命令::new
[ logevent ] [13:20:39:562] [ Debug ] BufNew5
[ logevent ] [13:20:39:562] [ Debug ] BufAdd5
[ logevent ] [13:20:39:562] [ Debug ] BufAdd5
[ logevent ] [13:20:39:562] [ Debug ] BufLeave4
[ logevent ] [13:20:39:562] [ Debug ] BufEnter5
[ logevent ] [13:20:39:562] [ Debug ] BufWinEnter5
  1. 执行命令::enew
[ logevent ] [13:22:42:452] [ Debug ] BufNew6
[ logevent ] [13:22:42:452] [ Debug ] BufAdd6
[ logevent ] [13:22:42:452] [ Debug ] BufAdd6
[ logevent ] [13:22:42:452] [ Debug ] BufLeave4
[ logevent ] [13:22:42:452] [ Debug ] BufWinLeave4
[ logevent ] [13:22:42:452] [ Debug ] BufHidden4
[ logevent ] [13:22:42:452] [ Debug ] BufEnter6
[ logevent ] [13:22:42:452] [ Debug ] BufWinEnter6
  1. 执行命令: :echo bufadd('')
[ logevent ] [13:47:57:482] [ Debug ] BufNew6
  1. echo nvim_create_buf(v:false, v:true)
[ logevent ] [14:25:06:555] [ Debug ] BufNew5
  1. echo nvim_create_buf(v:true, v:true)
[ logevent ] [14:26:32:389] [ Debug ] BufNew11
[ logevent ] [14:26:32:389] [ Debug ] BufAdd11
[ logevent ] [14:26:32:389] [ Debug ] BufAdd11

当打开一个文件后,执行 :set nobuflisted, 在执行 :set buflisted

[ logevent ] [14:38:15:888] [ Debug ] BufDelete4
[ logevent ] [14:38:19:857] [ Debug ] BufAdd4
[ logevent ] [14:38:19:857] [ Debug ] BufAdd4

打开一个存在的文件::e README.md

[ logevent ] [14:44:15:717] [ Debug ] BufNew8
[ logevent ] [14:44:15:717] [ Debug ] BufAdd8
[ logevent ] [14:44:15:717] [ Debug ] BufAdd8
[ logevent ] [14:44:15:717] [ Debug ] BufLeave4
[ logevent ] [14:44:15:717] [ Debug ] BufWinLeave4
[ logevent ] [14:44:15:717] [ Debug ] BufHidden4
[ logevent ] [14:44:15:717] [ Debug ] BufReadPre8
[ logevent ] [14:44:15:717] [ Debug ] BufReadPost8
[ logevent ] [14:44:15:717] [ Debug ] BufReadPost8
[ logevent ] [14:44:15:717] [ Debug ] BufEnter8
[ logevent ] [14:44:15:717] [ Debug ] BufWinEnter8

打开一个不存在的新文件: :e newfile.txt

[ logevent ] [14:45:56:519] [ Debug ] BufNew10
[ logevent ] [14:45:56:519] [ Debug ] BufAdd10
[ logevent ] [14:45:56:519] [ Debug ] BufAdd10
[ logevent ] [14:45:56:519] [ Debug ] BufLeave4
[ logevent ] [14:45:56:519] [ Debug ] BufWinLeave4
[ logevent ] [14:45:56:519] [ Debug ] BufHidden4
[ logevent ] [14:45:56:519] [ Debug ] BufNewFile10
[ logevent ] [14:45:56:519] [ Debug ] BufEnter10
[ logevent ] [14:45:56:519] [ Debug ] BufWinEnter10

延生阅读

分享到:

评论

目前只支持使用邮件参与评论。