I use Vim 7.3, and have this in my .vimrc (and nothing else):
filetype plugin indent on
autocmd FileType java :setlocal sw=4 ts=4 sts=2 noet
autocmd BufNewFile,BufReadPost ~/testdir/* setlocal sw=2 ts=2 sts=2 et
I have a directory ~/testdir which only contains a subdirectory p and the file ~/testdir/p/A.java which contains this:
class A {
}
If I open A.java by saying :e ~/testdir/p/A.java then :set et? reports that expandtab is currently ON.
On the other hand, if I start a new instance of Vim and go :vim A ~/testdir/** then this search will open A.java, but now :set et? tells me expandtab is OFF.
How do I make my intended indentation settings always apply for files under ~/testdir/?
The event BufReadPost should be being fired. Check that writing a message. This is:
autocmd BufNewFile,BufReadPost $HOME/git/repo/* echom "Reading buffer " . expand("<afile>")
Look for the messages with:
:messages
If the messages are there, then you know you are setting those options for the buffer. So, if the options have changed when the buffer is displayed, perhaps a plugin is setting them to some other thing. Check who is the culprit by showing who last changed the option with
:verbose set sw?
If that doesn't lead you to a solution, try using BufWinEnter instead of BufReadPost. That would probably work.
Vim explicitly recommends using ~ for the user home.
The help at :h autocmd-patterns says that you can use environment variables in the event patterns ...
... [a]nd ~ can be used for the home directory (if $HOME is defined):
:autocmd BufWritePost ~/.vimrc so ~/.vimrc
:autocmd BufRead ~archive/* set readonly
The environment variable is expanded when the autocommand is defined, not when
the autocommand is executed. This is different from the command!
So, change $HOME to ~ in your autocommand.
Even if your problem turns out to be unrelated it's good to follow the practice recommended in the docs.
The autocmd does work but probably not the way you expect since you did not set softtabstop.
autocmd BufNewFile,BufReadPost ~/git/repo/* setlocal sw=2 ts=2 sts=2 et
If you do not set softtabstop it will keep its old value. If this value is not 0 (which seems to be the case) when you press tab you will get the number of softtabstop spaces inserted into the file. And it will look like its not working.
It is generally a good idea to set shiftwidth, tabstop, and softtabstop to the same value if you ever change it.
Its also probably a good idea to make the set command local to the buffer by using setlocal.
Take a look at :h softtabstop
You can see that the autocmd "works" when softtabstop is set to its default value (of 0) if you run the command like this. And then run your :vim command
vim -u NONE -N -c'autocmd BufNewFile,BufReadPost $HOME/git/repo/* set sw=2 ts=2 et'
Related
I am recovering from a surgery, thusly, I am transitioning to VIM. As I starting point, I've opted to use the vim-sensible plugin as the foundation of my configuration. Additionally, I've installed the 'vim-rails' and 'vim-ruby' plugins. These are all loaded via Pathogen.
For whatever reason, the plugins are not adjusting indentation settings in accord with filetype. Tabs seem locked to 9 columns. I am able to set them manually, but obviously this is not ideal.
Here is my .vimrc. As you can see, it is very basic.
execute pathogen#infect()
syntax on
filetype plugin indent on
Vim provides the following buffer local options for managing indention: 'softtabstop', 'shiftwidth', 'tabstop', and 'expandtab'. The idea is to set these options for a specific filetype, e.g. ruby either by using an autocommand or using the after ftplugin directory (my preference).
After directory approach
Add the following to your ~/.vim/after/ftplugin/ruby.vim file:
setlocal softtabstop=2
setlocal shiftwidth=2
setlocal tabstop=2
Autocommand approach
Add the following to your ~/.vimrc file:
augroup MyIndentSettings
autocmd!
autocmd FileType ruby setlocal softtabstop=2 shiftwidth=2 tabstop=2
augroup END
Learn more
As you are just starting to vim it is best to learn how to query these options so you can track down future bugs. Querying an option is as simple as :verbose set {option}?, e.g. :verbose set expandtab?.
You may also be interested in Tim Pope's vim-sleuth which heuristically sets indent settings.
For more help see:
:h :set
:h 'softtabstop'
:h 'shiftwidth'
:h 'tabstop'
:h 'expandtab'
:h after-directory
In my vimrc I have the following:
set autoindent
set expandtabs
set shiftwidth=4
set tabstop=4
Actually I just have
set ai et sw=4 ts=4
You can change the specific settings using FileType or BufEnter:
autocmd BufEnter *.py ai et sw=4 ts=4
Context
I have my .vimrc automatically being sourced with:
autocmd! BufWritePost ~/.vimrc source ~/.vimrc
I also set defaults for spacing:
set tabstop=2 softtabstop=2 shiftwidth=2 expandtab
Later on, I use the FileType event to override the spacing default above with filetype-specific spacing:
" Syntax of these languages is fussy over tabs & spaces¬
autocmd FileType make setlocal ts=8 sts=8 sw=8 noexpandtab¬
autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab¬
" Customisations based on house-style (arbitrary)
autocmd FileType sh setlocal ts=4 sts=4 sw=4 expandtab
autocmd FileType vim setlocal ts=4 sts=4 sw=4 expandtab
Problem
The problem I am having is that sourcing my .vimrc will set the default values, but will not trigger the FileType event. This means that when I do a :write to my .vimrc while editting a file with filetype-specific spacing, the filetype-specific spacings get overridden by the defaults!
UPDATE: As pointed out by Ingo, the issue only arises in .vimrc and does not occur in any other files.
Example
As an example, when I am working on my .vimrc, initially the file-specific spacing (ts=4 sts=4 sw=4 expandtab) is enabled, but after I make some arbitrary change in my .vimrc, the default spacing (tabstop=2 softtabstop=2 shiftwidth=2 expandtab) is loaded but my file-specific spacing is NOT loaded (since the FileType event was not triggered by a write to my .vimrc) leaving me with the default spacing!
My question(s)
How can I override the default spacing with filetype specific spacings and preserve these even when auto-sourcing .vimrc?
If possible, I would like to accomplish this without getting rid of the autocmd's. Is that possible?
My hunch is that I should somehow manually trigger the FileType event when sourcing .vimrc Can this be done and is this the recommended approach?
Though you've very clearly described the problem, I doubt that this is happening.
As you're correctly using :setlocal for the filetype-specific settings, and :set in your ~/.vimrc, the sourcing of the latter will only affect the global defaults (and the current buffer, which is your .vimrc during the BufWritePost event). To affect other buffers, there would need to be a :bufdo command in your .vimrc.
You can check this with
:verbose set ts? sts? sw? et?
To avoid that your .vimrc settings are overridden with the global settings, you can append this:
if expand('%:t') ==# '.vimrc'
setlocal filetype=vim
endif
I ended up solving this issue by grouping the sourcing autocmd with another autocmd with the same event
" Reload changes to .vimrc automatically
autocmd BufWritePost ~/.vimrc source ~/.vimrc | setlocal filetype=vim
I had tried this earlier, but I was also using the AirlineRefresh command for vim-airline as such:
autocmd BufWritePost ~/.vimrc source ~/.vimrc | AirlineRefresh | setlocal filetype=vim
which was giving me this error:
E488: Trailing characters: AirlineRefresh | setlocal filetype=vim
Switching the order of AirlineRefresh and set local filetype=vim fixed the error and results in the desired behavior:
autocmd BufWritePost ~/.vimrc source ~/.vimrc | setlocal filetype=vim | AirlineRefresh
:bufdo e will do it but I couldn't just add it to my .vimrc. It will also remove syntax highlighting which is not so good.
:h bufdo execute the command in each buffer in the buffer list
:h :e re-edit the current file
I have the following lines in my .vimrc:
" UNIX fileformat
au BufRead,BufNewFile * set fileformats=unix,dos
au BufRead,BufNewFile * set fileformat=unix
These are to make any opened file using the unix file format.
It works well in almost all cases except for the help messages. If I type, let's say:
:h help
Vim first complains that:
"helphelp.txt" [readonly] 350L, 13662C Error detected while processing
BufRead Auto commands for "*": E21: Cannot make changes, 'modifiable'
is off: fileformat=unix
Obviously, I am trying to set the fileformat option on a non-modifiable buffer so this error is to be expected. However, what is the cleanest way to get rid of it without removing the feature for other files ?
Is there a way to conditionally apply/not apply autocommands for the help buffers ?
Thank you.
The 'fileformats' is a global setting, it should suffice to set it only once in your .vimrc:
set fileformats=unix,dos
The error will occur for any other unmodifiable file, not just help files. Therefore, it's best to make the setting conditional on the 'modifiable' buffer setting:
au BufRead,BufNewFile * if &l:modifiable | setlocal fileformat=unix | endif
(Alternatively, you could also just :silent! the error, but I regard the conditional as cleaner.)
I have installed Markdown syntax plugin.
When I'm on a new buffer not associated with any file, and paste the source portion of the site http://rosylilly.github.com/markdown.html into it, the colors appear nicely as it should for the markdown syntax.
However, after saving the file, the colors change. Any idea how I can fix this?
Can you, before and after saving do
:verbose set filetype
:verbose set
Tip: use :redir > file.txt to capture the output so you won't have to copy/paste which can be difficult with gvim - for command output
You could also look at the autocommands when saving:
:verbose au BufWrite
:verbose au BufWritePre
:verbose au BufWritePost
This would serve to discover what plugin/script is causing the highlighting to go haywire.
I turned on filetype plugin for some rails vim plugins I added, but a side effect of this seems to be that now autocommenting has been enabled in all filetypes (for instance, if I start a line with #, the next line, either by Enter in insert mode or O, etc. to enter insert mode, will also get a #).
I found a guide to disabling the auto-commenting formatoptions, and added the following to my .vimrc:
au FileType * setlocal formatoptions-=cro
However, I am still running into problems -- unless I explicitly :source .vimrc, (or enter the setlocal ... directly), it is not taking effect. I determined that this is the case because vim's ftplugins are overriding my options with their own.
I then found a second guide which talks about using an after ftplugin script to make changes after the ftplugin scripts have run, however their solution is to create symlinks for every single filetype in ~/.vim/after/ftplugin to a central file, and this seems to be kludgy to me.
Is there any way to create a generic after-ftplugin script or am I approaching this problem incorrectly? Any help would be appreciated.
How about an "after" plugin? Create a file in ~/.vim/after/plugin/ called noAutoComments.vim (or whatever) and place your autocmd in that?
Edit:
The reason this works? I'm only guessing here, but I have a feeling that the autocmd in the ~/.vimrc file is getting removed by some other file (but before the "after" files are getting sourced).
I ended up removing my ~/.vim directory and replaced my ~/.vimrc with the following 3 lines:
filetype plugin on
syntax on
au FileType * setlocal formatoptions-=cro
With only these lines in my ~/.vimrc and no ~/.vim/ directory, the autocmd seems to work as expected (Vim 7.1).
For any file that I edit:
:verbose set formatoptions?
formatoptions=ql
Last set from ~/.vimrc
I have yet to determine what file (plugin) is causing this issue however.
I've done some more investigation and it seems that the location of my autocmd within my .vimrc file determines if formatoptions will be overridden by vim's ftplugins or not. Using vim --noplugin to disable all external plugins, I found the following results:
If my vimrc looks like:
au FileType * setl fo-=cro
filetype plugin indent on
The result of :verbose set fo? is:
formatoptions=croql
Last set from /usr/share/vim/vim72/ftplugin/ruby.vim
However, if the lines in my vimrc are reversed:
filetype plugin indent on
au FileType * setl fo-=cro
The result of :verbose set fo? is:
formatoptions=ql
Last set from ~/.vimrc
... which is the desired result. So it seems that the autocmd needs to be specified after filetype plugins are enabled.
Another reason this might not be taking effect...
From :he :set-=:
When the option is a list of flags, {value} must be
exactly as they appear in the option. Remove flags
one by one to avoid problems.
I have
" Turn off auto-commenting
au FileType * setlocal formatoptions-=c
au FileType * setlocal formatoptions-=r
au FileType * setlocal formatoptions-=o
because I've run into this.
Using one of the various autocmd events to set the configuration option should work if you find the right one, but I'd start by running:
:verbose set formatoptions?
This will tell you where the option was set, which may make it easier to determine which autocmd to use. Alternatively, if you don't mind a bit of minor hacking, the way I'd probably do it is just to find out where it's set in the plugin and comment out that line (and make a note of it in case you ever upgrade the plugin). You could also contact the plugin's author and ask them to make it a configurable option.
For the available autocmd events, read this:
:help {event}
I have tried solutions proposed by many, but none of them worked for me, but I found one very simple workaround, namely, in your ~/.bash_aliases:
# vim without auto comment
alias vi="vi +'set fo-=cro'"
I was struggling with this issue and I finally works with the following lines:
syntax on
filetype on
filetype plugin on
au FileType * setlocal formatoptions-=cro
I think the key here is that the autocmd is place after the filetype plugin on.