Blue_vision
Blue_vision

Reputation: 154

Vim not following config when opening a *second* file

Essentially, my configurations appear to work for the first file I open, but then do not work as expected when I open subsequent files. I'm specifically having an issue with Python files, but I would guess given the nature of the problem, it probably exists for other files.

I have my python configs in my .vimrc as follows

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

When I edit a new python file for the first time, expandtabs is set no problem. However, when I open up a second python file from within vim, it opens the file and identifies it as a python file (filetype=python), but expandtab is turned off! The same happens if I open a third, fourth, or fifth file.

Now, if I instead start Vim editing that second python file, expandtab is correctly set on! However, when I open up the first python file for editing, expandtab is off. Even if I start up Vim editing two files (e.g. running vim margins.py marginsio.py from bash), the first buffer has expandtab set as intended, but the second buffer does not have expandtab set. Now, if I start up Vim with a non-python file and then open a python file for editing, the python file has expandtab. However, any subsequent python files I open do not have expandtab set.

Finally, if I run vim, say vim margins.py, then open a new python file marginsio.py (which does not have expandtab set when I open it), then close margins.py, then re-open margins.py from within vim, margins.py has expandtab set!

Running Vim 7.4 on Ubuntu 14.04.5 on Windows Subsystem for Linux (on Windows 10). I'd assume that WSL isn't having an effect here, but I've used Vim for many years and have never (knowingly) encountered this before. There's no set noexpandtab at all in either my .vimrc or any of my ~/.vim/ configs, and the problem persists if I run vim without plugins.

Upvotes: 0

Views: 220

Answers (2)

Blue_vision
Blue_vision

Reputation: 154

In trying to pare my problem down to the essential parts, I omitted the apparently very important comment on line 5 of my python config in my original post. It seems that when Vim encounters a comment, it ends an autocommand. For a yet unknown reason, when Vim opened a .py file for the first time, some default behaviour caused it to run expandtab. However, that did not happen the second time a .py file was opened, so the autocommand was run, but ended prematurely at set textwidth=89, and expandtab was never set.

I tried bringing it down to the essentials as per Jim Stewart's excellent answer, and didn't have any luck fixing it until I broke it into a bunch of setlocals outside of my autocommand. When I brought those setlocals into a single autocommand, my problem was fixed! I narrowed it down to the only difference being the lack of comment. Messing around with comments in my config does seem to indicate that comments simply cut off an autocommand at the line where the comment is located.

Upvotes: 0

Jim Stewart
Jim Stewart

Reputation: 17323

I'm unable to reproduce the issue you're having where the settings are applied to the first file but not subsequent files, but I think I can help you debug it.

First, try testing with no other configuration. Create a file called testvimrc containing only this:

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

Then start vim as

vim -u testvimrc somefile.py

And see if you still have the behavior you described. If I do this, all Python files use the specified settings, whether loaded via the command line, or loaded manually from inside Vim. That leads me to believe that the problem lies elsewhere in your config.

To figure out what might be happening, you can use the verbose command. Go back to your normal Vim config (don't use -u testvimrc this time). To see what last set expandtab:

:verbose set expandtab?

That should respond with something like

  expandtab
        Last set from ~/.vimrc

If you see anything else, you'll know where it's being overridden. You might see something like

Last set from /usr/share/vim80/ftplugin/python.vim

This will help you determine the offending plugin or other source of conflict. Changing the order of settings in your .vimrc may help if that's the case.

There's a better solution to this, however.

If you want to override type-specific settings, there's built-in support for it. There's a hint above, in the python.vim line: Vim already knows when you're editing a Python file, and it looks for a matching ftplugin. First it applies the one it was distributed with (for me, /usr/share/vim80/ftplugin/python.vim). Then it looks for overrides in your runtimepath. By default, the last directory in runtimepath is ~/.vim/after, which means that anything in there will override all preceding settings.

Create a file ~/.vim/after/ftplugin/python.vim and override the settings there. You should use setlocal instead of set so that it only affects Python buffers. Put this inside:

setlocal tabstop=4
setlocal softtabstop=4
setlocal shiftwidth=4
setlocal textwidth=89
setlocal expandtab
setlocal autoindent
setlocal foldmethod=syntax
setlocal fileformat=unix

Now, whenever you load or create a buffer with filetype=python, those settings will be applied, overwriting the settings from any other plugins or conflicting sources. You can verify that your settings are being used by running :verbose set again.

Upvotes: 2

Related Questions