vim: check where a setting value was modified - vim

I should probably written this down somewhere because it's not easy to remember and not often used. But anyways,
I have a setting like 'expandtab'. I'd like to change to 'noexpandtab'. But I can't figure out in which rc file it was set that takes the last effect. There is a trick to know where a setting was last set. What's the trick?

Use :verbose along with :set {option}?:
:verbose set expandtab?
You should see something akin to:
expandtab
Last set from ~/.vimrc

Related

Which configuration does Vim finally apply after setting values in .vimrc, ftplugin, after/ftplugin etc.?

I am editing a python file. My current settings for tabstop are as follows(just experimenting things):
~/.vimrc: set tabstop=4
~/.vim/ftplugin/python.vim: set tabstop=2
There is no ~/.vim/after/plugin/python.vim file
set tabstop? shows tabstop=8
verbose set tabstop? shows tabstop=8. Last set from /usr/share/vim/vim80/ftplugin/python.vim
My questions:
Why is tabstop settings at 8 even though i have explicitly set it to 4 in .vimrc file or 2 in ~/.vim/ftplugin/python.vim file
When is each of the files i.e. ~/.vimrc, ~/.vim/ftplugin/python.vim, ~/.vim/after/plugin/python.vim, /usr/share/vim/vim80/ftplugin/python.vim loaded?
Which file takes priority and where should I define my settings to override the others?
How is set different from set local?
It would be great if someone answers all these questions. It will surely benefit people especially Vim beginner and intermediate users as all of these concepts are inter-related
tabstop is the width of space represented by a tab character in the file, but the width of space inserted when you press Tab on your keyboard is controlled by softtabstop (if it's set to a non-zero value). Nothing weird is going on with order of evaluation, or setlocal, or any of the other things you're asking about.
See also What is softtabstop used for? on the Vim StackExchange.
tabstop is a buffer-local setting. That means that every buffer has its own value. So by setting it from your vimrc you only set the global default which will probably be overwritten by ftplugin and such.
The plugin's code resides in $VIMRUNTIME/ftplugin.vim. Roughly speaking, what it does is runtime! ftplugin/python.vim. runtime! differs from source in two aspects: (a) it searches along :h 'runtimepath', and not in the current directory; (b) it sources all files found (that's what the "bang" stands for), not only the first one.
So, because of (b), ftplugin first sources your ~/.vim/ftplugin/python.vim, and then $VIMRUNTIME/ftplugin/python.vim. For this reason your setting gets finally overwritten.
This is why usually we want ~/.vim/after/ftplugin/python.vim instead. Also note that standard "ftplugin"-scripts have the guard against multiple sourcing:
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
....
So if you really want it, you can put this on top of your ~/.vim/ftplugin/python.vim and exclude all the stuff from $VIMRUNTIME/ftplugin/python.vim. Rarely wanted though.
The difference between set, setglobal and setlocal is actually the difference between option types: global, local-to-buffer, local-to-window, global-local. To keep the things simple, setglobal sets a global value for an option, setlocal sets a local one, and set does something "reasonable" (tm). In particular, set tabstop=x sets both global and local (current buffer's one) values.

How to find out, in which plugin a Vim setting gets changed?

Today I had some obscure behavior. I have
set autoindent
in my vimrc, but for some reason, this gets turned off, whenever i open a PHP file.
I've fixed it now by adding a line like
autocmd FileType php set autoindent
But I'm still trying to figure out, where this setting is disabled. So is there some way to find out, where in the vim config a setting gets changed?
For reference here's my full vimrc.local that I'm using on Ubuntu:
https://gist.github.com/mikehaertl/1612035/5fa149468006577d193858bbc8cefcd3a413e017
EDIT:
The problem was caused by a filetype indent on that I added some time ago to my config. No idea, why that affects autoindent, though.
The :verbose command will tell you where an option was last changed:
:verbose set autoindent?
If that alone doesn't help, you can inspect all executed commands, preferably with the output redirected into a logfile:
:set verbosefile=vim.log
:20verbose edit foo.php
Also note that there are several options controlling indentation, e.g. 'cindent', 'smartindent', 'indentexpr', etc.
PS: To avoid that the changed option value spills into other buffers, it's recommended to use :setlocal instead.
Isnt that line the problem?
autocmd FileType php set cindent|set cinkeys-=0#

How can I find out why vim keeps changing my expandtab setting

I use vim. Specifically I am using Janus. I have expandtab set. However, during the course of using vim, for some reason, my expandtab setting gets set to noexpandtab, and my files start to gain hard tabs. I have tried typing :verbose set expandtab? but this does not show me anything (specifically, it shows me that noexpandtab is set, but it doesn't show a file that is responsible for setting it).
So I would like to find out:
Why my expandtab setting might be changing
How I can track down the culprit and prevent it from happening
Thanks
Try this
:verb set expandtab?
:verb set et?
:verb set invexpandtab?
expandtab can really be set in a number of ways :/
I should add that in addition to the above if you tried the following:
:verb set expandtab?
:verb set et?
:verb set invexpandtab?
And you get back with no line number or file:
noexpandtab
It's more than likely that you have the following and need to change the order:
set expandtab
set binary
set noeol
Change to (note the order)
set binary
set noeol
set expandtab
The reason for this is due to set binary command has a few defaults it executes after it runs. Including the following:
'textwidth' will be set to 0
'wrapmargin' will be set to 0
'modeline' will be off
'expandtab' will be off
I noted DavidWinterbottom called this out in his comment, but that seemed to be the only comment that was hidden by default and this caused me to do a lot more reading that was necessary, so hopefully this post helps another poor soul from wasting countless hours tracking this down.
VIM settings can either be set in a configuration file, or in a modeline inside the file you're editing. Note that expandtab can be shortened in VIM to et, so be sure to look for that as well.
Possible configuration files I'd look for:
/etc/vim/vimrc and other files in that directory (sometime vimrc.local and such)
$HOME/.vimrc
As for modelines, they are simply configuration options for VIM, located as comments in the file itself. If this only happens with some files but not others, look for comments that look something like:
/* vim: set noet ai tw=75: */
And try to remove them and see if it helps.

How to impose hard wrap against my soft wrap wishes?

Well, I'm a newb at Vim, so I'm guessing there's a 99% chance it's a user error!
Vim was soft wrapping long lines very nicely thank you, then a couple of days ago it started to insert hard wraps but only when I had saved the file.
I have been through wrap, nolinebreak, textwidth, nolist, and all combinations thereof to try to get softwrap back but to no avail. Heck, I even read the help pages. All of 'em.
Here's the relevant bits from my .vimrc (as you can tell, I'm getting desperate):
" Editing
set aw ai
set et ts=8 sts=2 sw=2 nu
set fo+=tcrqw fo-=o
set showmatch matchtime=5
set whichwrap=<,>,h,l,[,]
set cursorline
set nofoldenable
set wrap
set linebreak
let mapleader = ","
I picked up this .vimrc from using Vundle.
I found the culprit, Tim Pope's Vim Markdown plugin. Lovely plugin but personally prefer soft wraps, will have to find how to change it!
but only when I had saved the file.
This should hint to you that some plugin is touching the buffer Pre-Write.
Find out which it is by doing
:au BufWrite,BufWritePre,BufWriteCmd
:au FileWriteCmd,FileWritePre
To see where the trigger was installed from:
:verbose au BufWrite,BufWritePre,BufWriteCmd
:verbose au FileWriteCmd,FileWritePre
I have a suspicion this is probably caused by your fo line. Having "t" in the formatoptions option means that if a textwidth is set for the current buffer then vim will break lines at this width. You may notice that this only happens for certain filetypes because different ftplugins may be setting textwidth without you knowing.
The next time you see this happening, I'd suggest running :verbose set textwidth? (with the question mark) and seeing if the value is set. This command will also point you to where it was last set.
Another test would be to just remove "t" from your fo line and see if the problem goes away.
Janus is another Vim plugin that fiddles with linewrap/linebreak and textwidth.
:verbose set tw?
told me:
textwidth=72
Last set from ~/.vim/janus/vim/core/before/plugin/filetypes.vim
Now I just need to figure out the right incantation to disable that... for now, I just added set textwidth=99 to my ~/.vimrc.after file, but there may be a better way...

Can you query what a variable/setting in vim is set to?

For example, in vim, if I want to know if autoread is set or not, is there a command I can run to tell me? Or to know what my tabstop is set to?
In your case, :set autoread? will give you the current value of autoread. Generally, set foo? will give you the value of option foo.
:set will display all options that are different from default.
:verbose set autoread? will tell you what set autoread and its value.
You can also do, for example,
echo &ft
The & refers to the contents of the variable. I find this useful in scripts.
You can view settings in vim with this command
:set all

Resources