0Pricing
Lua Academy · 课时

缓冲区与窗口

操作编辑器。

缓冲区与窗口 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。

缓冲区、窗口与标签页

Neovim 将内容与显示分离。缓冲区在内存中保存文本;窗口是缓冲区的视口;标签页是窗口布局。

一个缓冲区可以显示在多个窗口中。插件通过 nvim_buf_* 和 nvim_win_* API 系列操作这些句柄,而句柄本质上是整数。

local buf = vim.api.nvim_get_current_buf()
local win = vim.api.nvim_get_current_win()
print(buf, win)

读取缓冲区行

nvim_buf_get_lines(buf, start, end_, strict) 以列表形式返回行。索引从零开始,并且不包含结束索引;将 -1 作为结束索引即可读取到最后一行。

将 strict_indexing 设置为 false 后,超出范围的索引会被容忍,而不会报错。

local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
print('line count: ' .. #lines)

写入缓冲区行

nvim_buf_set_lines 会用新文本替换指定范围。要在末尾追加内容,请将起始位置和结束位置都设为 -1。要覆盖全部内容,请使用 0, -1。

替换内容是一个由字符串组成的 Lua 列表,每行对应一个字符串,且末尾不包含换行符。

vim.api.nvim_buf_set_lines(0, -1, -1, false, {
  '-- appended line',
})

临时缓冲区

使用 nvim_create_buf(listed, scratch) 创建一个不列出且用完即弃的缓冲区。传入 false, true 会创建适合插件界面的临时缓冲区。

请设置 bufhidden = 'wipe',这样窗口关闭时缓冲区也会消失,避免留下多余的缓冲区。

local buf = vim.api.nvim_create_buf(false, true)
vim.bo[buf].bufhidden = 'wipe'
vim.api.nvim_buf_set_lines(buf, 0, -1, false, { 'Panel' })

缓冲区局部选项

通过索引 vim.bo[buf],可以为指定句柄设置缓冲区局部选项。常见的插件设置包括 modifiable = false 和 buftype = 'nofile'。

将显示缓冲区设为不可修改,可以防止用户意外编辑生成的内容。

vim.bo[buf].modifiable = false
vim.bo[buf].buftype = 'nofile'
vim.bo[buf].filetype = 'myplugin'

打开浮动窗口

nvim_open_win(buf, enter, config) 会将缓冲区放入浮动窗口。配置中可以设置 relative、row、col、width、height 和 border。

浮动窗口是现代界面的基础,例如悬停文档、选择器和通知。

local win = vim.api.nvim_open_win(buf, true, {
  relative = 'editor', row = 5, col = 10,
  width = 40, height = 10, border = 'rounded',
})

窗口配置

使用 nvim_win_set_config 调整已打开的浮动窗口,例如在 VimResized 时调整大小。使用 nvim_win_get_config 读取当前布局。

通过 vim.wo[win] 设置窗口局部选项,例如在界面面板中隐藏光标行或禁用行号列。

vim.wo[win].number = false
vim.wo[win].cursorline = true
vim.api.nvim_win_set_config(win, { width = 50 })

光标与位置

使用 nvim_win_set_cursor(win, {row, col}) 移动光标。请注意,行号从 1 开始,而列号从 0 开始,这是产生偏移一位错误的常见原因。

使用 nvim_win_get_cursor 读取光标位置,以便在某项操作前后记住并恢复用户的位置。

local pos = vim.api.nvim_win_get_cursor(0)
vim.api.nvim_win_set_cursor(0, { pos[1], 0 })

有效性与清理

句柄可能会失效。在操作已保存的句柄之前,请使用 nvim_buf_is_valid 和 nvim_win_is_valid 进行检查。

使用 nvim_win_close(win, force) 关闭窗口,并通过 nvim_buf_delete(buf, { force = true }) 删除缓冲区。请始终先进行有效性检查,以避免错误。

if vim.api.nvim_win_is_valid(win) then
  vim.api.nvim_win_close(win, true)
end

扩展标记与命名空间

扩展标记会将元数据锚定在文本上,并在编辑发生时随文本移动。请使用 nvim_create_namespace 创建命名空间,然后附加虚拟文本或高亮。

nvim_buf_set_extmark 支持 virt_text、标记列和行内高亮,也是内嵌提示和 Git 追责插件所依赖的引擎。

local ns = vim.api.nvim_create_namespace('myplugin')
vim.api.nvim_buf_set_extmark(0, ns, 0, 0, {
  virt_text = { { ' hint', 'Comment' } },
})

列出与迭代

nvim_list_bufs 和 nvim_list_wins 会返回当前所有句柄。您可以使用 nvim_buf_is_loaded 或检查选项来筛选它们。

迭代可以让插件作用于整个会话,例如关闭每个浮动窗口,或刷新指定文件类型的每个缓冲区。

for _, b in ipairs(vim.api.nvim_list_bufs()) do
  if vim.api.nvim_buf_is_loaded(b) then print(b) end
end

快速检查

请验证您对缓冲区和窗口所学内容的掌握情况。

回顾:缓冲区与窗口

缓冲区保存文本,窗口显示文本,而句柄是您在使用前需要验证的整数。您可以读取和写入行、创建临时缓冲区,以及设置缓冲区局部选项。

通过 nvim_open_win 创建浮动窗口,再结合光标控制、扩展标记和列表接口,您就拥有了构建丰富且有状态的插件用户界面所需的一切。

常见问题解答

「缓冲区与窗口」课时是免费的吗?

是的 — 「缓冲区与窗口」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。

「缓冲区与窗口」这节课中我会学到什么?

操作编辑器。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「缓冲区与窗口」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Lua Academy 课中编写并运行代码吗?

能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Neovim Lua API
  2. 命令与按键映射
  3. 缓冲区与窗口
  4. 打包插件
← 返回 Lua Academy