nvim/lua/autocmds.lua
xfy e013cb9e88 fix(fold): 排除 help/man/qf 等特殊 filetype 的 treesitter 折叠
FileType autocmd 对所有文件类型触发,help/qf 原生的 manual 折叠
被 expr 覆盖。增加 filetype 排除表,保留特殊窗口的原生折叠行为,
使实现与注释承诺一致。
2026-06-16 09:59:28 +08:00

99 lines
4.3 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- =============================================================================
-- 自动命令配置 (lua/autocmds.lua)
-- =============================================================================
-- 自动命令autocmd是事件驱动的回调机制
-- 在特定编辑器事件(如打开文件、切换 buffer、进入插入模式等发生时自动执行。
--
-- 所有 autocmd 归属于 "UserAutocmds" 组,
-- 使用 { clear = true } 确保每次重载配置时先清除旧的 autocmd
-- 避免重复注册导致命令被多次触发。
-- =============================================================================
-- 创建用户 autocmd 组clear = true 表示创建前清空组内所有现有命令
local group = vim.api.nvim_create_augroup("UserAutocmds", { clear = true })
-- ---------------------------------------------------------------------------
-- 1. Yank 高亮
-- ---------------------------------------------------------------------------
-- 复制文本时短暂高亮被复制的区域,提供视觉反馈。
vim.api.nvim_create_autocmd("TextYankPost", {
group = group,
desc = "复制文本时高亮被复制的区域",
callback = function()
vim.hl.on_yank()
end,
})
-- ---------------------------------------------------------------------------
-- 2. 恢复上次编辑位置
-- ---------------------------------------------------------------------------
-- 打开文件后,将光标恢复到上次关闭时的位置。
-- 原理Vim 在关闭文件时会保存光标位置到 `"` 标记(双引号标记),
-- 下次打开时可通过此标记恢复。
--
-- 跳过的情况:
-- - commit / gitcommitGit 提交消息文件,总是从头开始编辑
-- - xxd十六进制编辑模式
-- - gitrebaseGit rebase 交互式编辑
vim.api.nvim_create_autocmd("BufReadPost", {
group = group,
callback = function()
-- 获取 `"` 标记的位置(行, 列)
local mark = vim.api.nvim_buf_get_mark(0, '"')
local row = mark[1] -- 行号1-based
local ft = vim.bo.filetype
-- 仅当标记有效(行号 > 1 且在文件范围内)时恢复光标
if row > 1 and row <= vim.fn.line("$") then
-- 排除特定文件类型
if ft ~= "commit" and ft ~= "gitcommit" and not ft:match("xxd") and not ft:match("gitrebase") then
vim.api.nvim_win_set_cursor(0, mark)
end
end
end,
})
-- ---------------------------------------------------------------------------
-- 3. 注释延续行为
-- ---------------------------------------------------------------------------
-- 控制按回车或 o/O 时是否自动延续注释符号(如 //、#、--)。
--
-- formatoptions 说明:
-- o - 使用 o/O 换行时延续注释(被移除,避免在 normal 模式下意外延续)
-- r - 按回车时延续注释保留insert 模式下回车延续注释符)
--
-- 注意此设置对自动格式化conform.nvim的行为也有影响。
vim.api.nvim_create_autocmd("FileType", {
group = group,
callback = function()
-- 移除 'o':按 o/O 时不自动插入注释符号
vim.opt_local.formatoptions:remove("o")
-- 追加 'r':按回车时自动插入注释符号
vim.opt_local.formatoptions:append("r")
end,
})
-- ---------------------------------------------------------------------------
-- 4. 按文件类型设置 Treesitter 折叠
-- ---------------------------------------------------------------------------
-- 使用 treesitter 的 foldexpr 进行语法感知的代码折叠。
-- 在 FileType 事件中按 buffer 设置 window-local 选项:
-- - window-localvim.wo而非全局vim.o每个 buffer 独立
-- - 排除非代码 filetypehelp/man/qf保留它们的原生折叠行为
--
-- foldmethod = "expr" 表示使用表达式foldexpr计算折叠范围。
-- foldexpr = "v:lua.vim.treesitter.foldexpr()" 是 Neovim 0.10+ 的内置函数,
-- 基于 treesitter 语法树计算折叠边界。无 parser 时返回 0不折叠不会报错。
vim.api.nvim_create_autocmd("FileType", {
group = group,
callback = function(args)
-- 跳过非代码 filetype保留它们的原生折叠行为
local excluded = { help = true, man = true, qf = true, terminal = true }
if excluded[vim.bo[args.buf].filetype] then
return
end
vim.wo.foldmethod = "expr"
vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()"
end,
})