Vim 打开*第二个* 文件时未遵循配置
Vim not following config when opening a *second* file
基本上,我的配置似乎适用于我打开的第一个文件,但当我打开后续文件时却无法按预期工作。我特别遇到 Python 文件的问题,但我猜想鉴于问题的性质,它可能存在于其他文件中。
我的 python 配置在我的 .vimrc 中,如下所示
au BufNewFile,BufRead *.py
\ set tabstop=4 |
\ set softtabstop=4 |
\ set shiftwidth=4 |
\ set textwidth=89 | " PEP-8 prefers 80
\ set expandtab |
\ set autoindent |
\ set foldmethod=syntax
au BufNewFile *.py set fileformat=unix
当我第一次编辑一个新的 python 文件时,expandtabs 设置没问题。但是,当我从 vim 中打开第二个 python 文件时,它会打开该文件并将其标识为 python 文件 (filetype=python
),但是 expandtab
已关闭!如果我打开第三个、第四个或第五个文件,也会发生同样的情况。
现在,如果我改为开始 Vim 编辑第二个 python 文件,则 expandtab
已正确设置!但是,当我打开第一个 python 文件进行编辑时,expandtab
处于关闭状态。即使我开始 Vim 编辑两个文件(例如 运行ning vim margins.py marginsio.py
来自 bash),第一个缓冲区已按预期设置 expandtab
,但第二个缓冲区没有设置 expandtab
。现在,如果我用一个非 python 文件启动 Vim,然后打开一个 python 文件进行编辑,python 文件有 expandtab
。但是,我打开的任何后续 python 文件都没有设置 expandtab
。
最后,如果我 运行 vim,说 vim margins.py
,然后打开一个新的 python 文件 marginsio.py(其中没有 expandtab
打开时设置),然后关闭margins.py,然后从vim中重新打开margins.py,margins.py有expandtab
设置!
运行 Vim Ubuntu 7.4 Windows 14.04.5 Linux 子系统(Windows 10)。我假设 WSL 在这里没有效果,但我已经使用 Vim 多年并且以前从未(有意地)遇到过这种情况。我的 .vimrc 或我的任何 ~/.vim/ 配置中根本没有 set noexpandtab
,如果我 运行 vim 问题仍然存在没有插件。
我无法重现您遇到的设置应用于第一个文件而不是后续文件的问题,但我想我可以帮助您调试它。
首先,尝试在没有其他配置的情况下进行测试。创建一个名为 testvimrc
的文件,仅包含以下内容:
set nocompatible
au BufNewFile,BufRead *.py
\ set tabstop=4 |
\ set softtabstop=4 |
\ set shiftwidth=4 |
\ set textwidth=89 |
\ set expandtab |
\ set autoindent |
\ set foldmethod=syntax
au BufNewFile *.py set fileformat=unix
然后开始vim为
vim -u testvimrc somefile.py
然后看看您是否还有所描述的行为。如果我这样做,所有 Python 文件都使用指定的设置,无论是通过命令行加载,还是从 Vim 内部手动加载。这使我相信问题出在您的配置中的其他地方。
要找出可能发生的情况,您可以使用 verbose
命令。返回正常的 Vim 配置(这次不要使用 -u testvimrc
)。看看上次设置的是什么expandtab
:
:verbose set expandtab?
那应该以类似
的方式回应
expandtab
Last set from ~/.vimrc
如果您看到其他内容,您就会知道它在哪里被覆盖了。您可能会看到类似
的内容
Last set from /usr/share/vim80/ftplugin/python.vim
这将帮助您确定有问题的插件或其他冲突源。如果是这种情况,更改 .vimrc
中的设置顺序可能会有所帮助。
然而,有更好的解决方案。
如果您想覆盖特定于类型的设置,它有内置支持。上面有一个提示,在 python.vim
行中:Vim 已经知道您何时编辑 Python 文件,并且它会寻找匹配的 ftplugin。首先,它应用它分发的那个(对我来说,/usr/share/vim80/ftplugin/python.vim
)。然后它会在您的 runtimepath
中查找覆盖。默认情况下,runtimepath
中的 last 目录是 ~/.vim/after
,这意味着其中的任何内容都会覆盖之前的所有设置。
创建文件 ~/.vim/after/ftplugin/python.vim
并覆盖其中的设置。您应该使用 setlocal
而不是 set
,这样它只会影响 Python 缓冲区。把这个放在里面:
setlocal tabstop=4
setlocal softtabstop=4
setlocal shiftwidth=4
setlocal textwidth=89
setlocal expandtab
setlocal autoindent
setlocal foldmethod=syntax
setlocal fileformat=unix
现在,每当您使用 filetype=python
加载或创建缓冲区时,这些设置将被应用,覆盖来自任何其他插件或冲突源的设置。您可以验证 运行 :verbose set
再次使用您的设置。
在尝试将我的问题简化为基本部分时,我在原始 post 的 python 配置的第 5 行省略了明显非常重要的评论。 好像Vim遇到注释就结束一个自动命令。由于未知原因,当 Vim 第一次打开 .py 文件时,一些默认行为导致它 运行 expandtab
。但是,第二次打开 .py 文件时并没有发生这种情况,因此自动命令是 运行,但在 set textwidth=89
处过早结束,并且从未设置 expandtab
。
我试着按照 Jim Stewart 的出色回答将其归结为基本要素,但直到我将其分解为自动命令之外的一堆 setlocal
之前,我都没有运气修复它。当我将那些 setlocal
放入单个自动命令时,我的问题就解决了!我将其缩小到唯一的区别是缺乏评论。在我的配置中乱用评论似乎表明评论只是在评论所在的行切断自动命令。
基本上,我的配置似乎适用于我打开的第一个文件,但当我打开后续文件时却无法按预期工作。我特别遇到 Python 文件的问题,但我猜想鉴于问题的性质,它可能存在于其他文件中。
我的 python 配置在我的 .vimrc 中,如下所示
au BufNewFile,BufRead *.py
\ set tabstop=4 |
\ set softtabstop=4 |
\ set shiftwidth=4 |
\ set textwidth=89 | " PEP-8 prefers 80
\ set expandtab |
\ set autoindent |
\ set foldmethod=syntax
au BufNewFile *.py set fileformat=unix
当我第一次编辑一个新的 python 文件时,expandtabs 设置没问题。但是,当我从 vim 中打开第二个 python 文件时,它会打开该文件并将其标识为 python 文件 (filetype=python
),但是 expandtab
已关闭!如果我打开第三个、第四个或第五个文件,也会发生同样的情况。
现在,如果我改为开始 Vim 编辑第二个 python 文件,则 expandtab
已正确设置!但是,当我打开第一个 python 文件进行编辑时,expandtab
处于关闭状态。即使我开始 Vim 编辑两个文件(例如 运行ning vim margins.py marginsio.py
来自 bash),第一个缓冲区已按预期设置 expandtab
,但第二个缓冲区没有设置 expandtab
。现在,如果我用一个非 python 文件启动 Vim,然后打开一个 python 文件进行编辑,python 文件有 expandtab
。但是,我打开的任何后续 python 文件都没有设置 expandtab
。
最后,如果我 运行 vim,说 vim margins.py
,然后打开一个新的 python 文件 marginsio.py(其中没有 expandtab
打开时设置),然后关闭margins.py,然后从vim中重新打开margins.py,margins.py有expandtab
设置!
运行 Vim Ubuntu 7.4 Windows 14.04.5 Linux 子系统(Windows 10)。我假设 WSL 在这里没有效果,但我已经使用 Vim 多年并且以前从未(有意地)遇到过这种情况。我的 .vimrc 或我的任何 ~/.vim/ 配置中根本没有 set noexpandtab
,如果我 运行 vim 问题仍然存在没有插件。
我无法重现您遇到的设置应用于第一个文件而不是后续文件的问题,但我想我可以帮助您调试它。
首先,尝试在没有其他配置的情况下进行测试。创建一个名为 testvimrc
的文件,仅包含以下内容:
set nocompatible
au BufNewFile,BufRead *.py
\ set tabstop=4 |
\ set softtabstop=4 |
\ set shiftwidth=4 |
\ set textwidth=89 |
\ set expandtab |
\ set autoindent |
\ set foldmethod=syntax
au BufNewFile *.py set fileformat=unix
然后开始vim为
vim -u testvimrc somefile.py
然后看看您是否还有所描述的行为。如果我这样做,所有 Python 文件都使用指定的设置,无论是通过命令行加载,还是从 Vim 内部手动加载。这使我相信问题出在您的配置中的其他地方。
要找出可能发生的情况,您可以使用 verbose
命令。返回正常的 Vim 配置(这次不要使用 -u testvimrc
)。看看上次设置的是什么expandtab
:
:verbose set expandtab?
那应该以类似
的方式回应 expandtab
Last set from ~/.vimrc
如果您看到其他内容,您就会知道它在哪里被覆盖了。您可能会看到类似
的内容Last set from /usr/share/vim80/ftplugin/python.vim
这将帮助您确定有问题的插件或其他冲突源。如果是这种情况,更改 .vimrc
中的设置顺序可能会有所帮助。
然而,有更好的解决方案。
如果您想覆盖特定于类型的设置,它有内置支持。上面有一个提示,在 python.vim
行中:Vim 已经知道您何时编辑 Python 文件,并且它会寻找匹配的 ftplugin。首先,它应用它分发的那个(对我来说,/usr/share/vim80/ftplugin/python.vim
)。然后它会在您的 runtimepath
中查找覆盖。默认情况下,runtimepath
中的 last 目录是 ~/.vim/after
,这意味着其中的任何内容都会覆盖之前的所有设置。
创建文件 ~/.vim/after/ftplugin/python.vim
并覆盖其中的设置。您应该使用 setlocal
而不是 set
,这样它只会影响 Python 缓冲区。把这个放在里面:
setlocal tabstop=4
setlocal softtabstop=4
setlocal shiftwidth=4
setlocal textwidth=89
setlocal expandtab
setlocal autoindent
setlocal foldmethod=syntax
setlocal fileformat=unix
现在,每当您使用 filetype=python
加载或创建缓冲区时,这些设置将被应用,覆盖来自任何其他插件或冲突源的设置。您可以验证 运行 :verbose set
再次使用您的设置。
在尝试将我的问题简化为基本部分时,我在原始 post 的 python 配置的第 5 行省略了明显非常重要的评论。 好像Vim遇到注释就结束一个自动命令。由于未知原因,当 Vim 第一次打开 .py 文件时,一些默认行为导致它 运行 expandtab
。但是,第二次打开 .py 文件时并没有发生这种情况,因此自动命令是 运行,但在 set textwidth=89
处过早结束,并且从未设置 expandtab
。
我试着按照 Jim Stewart 的出色回答将其归结为基本要素,但直到我将其分解为自动命令之外的一堆 setlocal
之前,我都没有运气修复它。当我将那些 setlocal
放入单个自动命令时,我的问题就解决了!我将其缩小到唯一的区别是缺乏评论。在我的配置中乱用评论似乎表明评论只是在评论所在的行切断自动命令。