(Neo)Vim编辑Python代码时的异常缩进问题排查与修复
Vim/Neovim Python列表缩进异常问题解析与修复
问题复现
在默认配置(仅启用标准Python文件插件)的Vim/Neovim中,输入Python代码时会出现列表缩进异常:
def test(): a = [
按下回车后,预期光标缩进至8个空格位置(相对于行首):
def test(): a = [ <光标位置>
但实际光标会缩进至12个空格位置:
def test(): a = [ <光标位置>
嵌套场景下问题一致:
def test(): for i in range(10): a = [ <光标位置>
成因分析
问题根源在于Vim默认的Python缩进函数*GetPythonIndent(v:lnum)*的逻辑设计:
- 当检测到上一行以
[结尾时,函数会将下一行的缩进计算为当前行缩进值 + 2 × shiftwidth - 你的配置中
*shiftwidth=4*,因此会额外增加8个空格(2×4),导致最终缩进超出预期
从你提供的Python文件插件配置也能看到,默认*indentexpr*绑定的是*GetPythonIndent(v:lnum)*,这是触发异常的核心。
修复方法
通过自定义缩进函数覆盖默认逻辑,让列表下一行仅增加1倍*shiftwidth*的缩进:
在vimrc(Vim)或init.vim/init.lua(Neovim)中添加以下配置:
Vimscript版本
function! MyPythonIndent(lnum) " 先调用默认缩进函数获取基础值 let base_indent = GetPythonIndent(a:lnum) " 获取上一行内容 let prev_line = getline(a:lnum - 1) " 判断上一行是否是赋值后接列表开头的格式 if prev_line =~# '\s*=\s*\[$' " 重新计算缩进:上一行缩进 + 1倍shiftwidth let base_indent = indent(a:lnum - 1) + &shiftwidth endif return base_indent endfunction " 对Python文件启用自定义缩进 autocmd FileType python setlocal indentexpr=MyPythonIndent(v:lnum)
Neovim Lua版本(可选)
vim.api.nvim_create_autocmd("FileType", { pattern = "python", callback = function() vim.bo.indentexpr = [[MyPythonIndent(v:lnum)]] vim.fn.setreg("MyPythonIndent", [[ function! MyPythonIndent(lnum) let base_indent = GetPythonIndent(a:lnum) let prev_line = getline(a:lnum - 1) if prev_line =~# '\s*=\s*\[$' let base_indent = indent(a:lnum - 1) + &shiftwidth endif return base_indent endfunction ]], "v") vim.cmd([[call MyPythonIndent(1)]]) end })
添加后重启Vim/Neovim,再输入类似代码就能得到符合预期的缩进效果。
内容的提问来源于stack exchange,提问作者Bastian Venthur
相关产品推荐
相关产品推荐

