是否存在可在未修改缓冲区触发:x但不触发:q的autocmd事件
解决方案
没有单一原生autocmd事件可以直接覆盖你描述的场景,核心原因有两点:
:x/ZZ的内置逻辑为仅当缓冲区存在未修改的变更时才会执行写入动作,无变更时会直接退出,自然不会触发BufWritePre等和写入相关的事件。- 你之前尝试的
ExitPre事件触发时机过晚,此时缓冲区已经进入卸载流程,无法再修改内容触发写入,所以无法满足需求。
你可以通过以下两种常用稳定方案实现需求:
方案1:重写保存退出相关的命令与映射,提前触发格式化
该方案逻辑最可控,在执行原有保存退出动作前,先对目标缓冲区执行一次格式化,再判断是否需要保存,你已经写在BufWritePre上的格式化逻辑可以直接复用,不需要重复编写:
" 重写:x命令 command! X execute 'doautocmd BufWritePre' | x " 重写普通模式ZZ映射 nnoremap ZZ :doautocmd BufWritePre<CR>ZZ " 可按需扩展适配:wq/:wa等其他保存相关命令 command! Wq execute 'doautocmd BufWritePre' | wq command! Wa execute 'bufdo doautocmd BufWritePre' | wa
格式化产生的变更会被包含到后续的写入判断中,符合:x仅保存修改文件的原有逻辑。
方案2:组合QuitPre事件做全缓冲区检查
如果不想修改原有命令和映射,可以在QuitPre事件中遍历所有待退出的缓冲区,手动触发格式化:
autocmd QuitPre * for buf in filter(range(1, bufnr('$')), 'buflisted(v:val) && !&modified') \ | execute 'buf' buf | doautocmd BufWritePre <buffer> | endfor
该逻辑会在退出前对所有已加载、无未保存变更的缓冲区主动触发格式化,天然适配无变更时使用:x/ZZ退出的场景。
注意:如果你的格式化逻辑执行时间较长,建议在上述方案中增加文件类型过滤,仅对需要格式化的代码文件触发逻辑,避免退出时出现不必要的卡顿。
内容的提问来源于stack exchange,提问作者Kljunas2
相关产品推荐
相关产品推荐

