PAYATHON 2026

如何在项目中仅覆盖 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 文件。

备注:内容仅供参考。