如何在项目中仅覆盖 conform.nvim 的 Python 格式化配置?
可以直接修改 require('conform').formatters_by_ft.python,不必再次调用 setup()。如果要关闭项目内 Python 文件的保存时格式化,还要处理现有的 lsp_format = 'fallback':即使清空 formatter 列表,LSP 仍可能执行格式化。
只修改 Python formatter 列表
在项目的 .nvim.lua 中写入:
-- @file /path/to/project/.nvim.lua
local conform = require('conform')
conform.formatters_by_ft.python = {}
这会替换 Python 的 formatter 列表,保留 Lua 等其他文件类型的列表,也不会重新配置保存时格式化。官方文档支持直接修改 formatters_by_ft 和 formatters。参考 conform.nvim 配置文档
对于题目中的 lazy.nvim 配置,require('conform') 可以触发插件加载。应在基础配置完成后再赋值,避免后续初始化覆盖它。参考 lazy.nvim 懒加载说明
为什么再次调用 setup 会影响其他行为?
在查阅到的 conform.nvim 实现中,setup() 会合并 formatters_by_ft,同时清空并重建 Conform 自动命令组。如果第二次调用时没有传入 format_on_save,原来的保存时格式化自动命令就不会重新创建。
因此,下面的代码可能清空 Python formatter 列表,也可能影响其他语言的自动格式化:
require('conform').setup({
formatters_by_ft = { python = {} },
})
不宜把第二次 setup() 当作只更新一个字段的操作。具体实现应以安装版本为准。参考 conform.nvim 的 setup 实现
只关闭项目内 Python 的保存时格式化
如果还想保留 <leader>f 手动格式化,建议保留 python = { 'autopep8' },并在现有 format_on_save 回调中增加项目路径判断。
先将项目 .nvim.lua 改成下面这样,并将路径替换为项目的实际绝对路径:
-- @file /path/to/project/.nvim.lua
vim.g.no_python_autoformat_root = '/path/to/project'
然后只替换 init.lua 中原有的 format_on_save 函数,其他 opts 字段保持原样:
format_on_save = function(bufnr)
local ft = vim.bo[bufnr].filetype
local root = vim.g.no_python_autoformat_root
if ft == 'python' and type(root) == 'string' and root ~= '' then
root = vim.fs.normalize(root):gsub('/+$', '')
local filename = vim.fs.normalize(vim.api.nvim_buf_get_name(bufnr))
local prefix = root .. '/'
if filename:sub(1, #prefix) == prefix then
return nil
end
end
local disable_filetypes = { c = false, cpp = false, cmake = true }
if disable_filetypes[ft] then
return nil
end
return {
timeout_ms = 500,
lsp_format = 'fallback',
}
end,
这样,指定项目目录及其子目录中的 Python 缓冲区会跳过保存时格式化,其他文件仍按原来的规则处理。手动 <leader>f 不经过这个回调,因此仍可使用原先配置的 formatter。
这里利用了原有回调返回 nil 的机制:跳过保存时调用后,也不会触发该调用中的 LSP fallback。fallback 表示没有其他可用的 formatter 时使用 LSP,并不表示关闭格式化。参考 format_on_save 与 lsp_format 文档
检查配置是否符合预期
- 用
:messages确认项目.nvim.lua已加载。 - 用
:set filetype?确认目标缓冲区的 filetype 是python。 - 用
:ConformInfo检查 formatter 状态,再实际保存 Python 和 Lua 文件,确认各自的行为符合预期。
直接修改 conform.formatters_by_ft.python 会作用于整个 Neovim 实例,不会因为代码写在项目 .nvim.lua 中就自动获得项目作用域。路径判断方案则按缓冲区的文件路径限制范围;通过符号链接打开项目时,需要保证配置路径与缓冲区路径一致。
采用路径判断方案后,:ConformInfo 仍可能列出 autopep8。这是正常的:配置保留了手动格式化能力,只在保存时跳过该项目的 Python 文件。
备注:内容仅供参考。
