How can I get MacVim to properly indent my .vimrc - vim

I'm going through the VimCasts.org archive of videos and number 5 covers using Vim's auto-indentation to format source code. I see it working properly in my Objective-C file but not my .vimrc.
My tab settings are as follows:
set tabstop=2
set shiftwidth=2
set softtabstop=2
set expandtab
My .vimrc file has the following if block:
if has("autocmd")
filetype on
autocmd BufNewFile,BufRead *.rss,*.atom setfiletype xml
autocmd BufWritePre *.py,*.js :call <SID>StripTrailingWhitespaces()
endif
I would think that if I placed the cursor on the first line above and pressed Vjjjj= I would get the second, third and fourth line indented by two spaces, but what I get instead is:
if has("autocmd")
filetype on
autocmd BufNewFile,BufRead *.rss,*.atom setfiletype xml
autocmd BufWritePre *.py,*.js :call <SID>StripTrailingWhitespaces()
endif
Are my expectations incorrect or is this correct for some reason given the Vimscript language?

You need to add filetype plugin indent on to your vimrc to get vim to do indentation properly. (The plugin part isn't really necessary but is nice to have)
I would recommend replacing the filetype on line with filetype plugin indent on

Related

Vim autocmd for FileType not working indirectly

I have a custom ~/.vimrc I made with this augroup:
augroup filetype_vim
autocmd!
autocmd! BufWritePost .vimrc* source %
autocmd FileType vim |
setlocal foldlevel=0 foldmethod=marker foldmarker={{{,}}}
augroup END
When I open vim directly to edit the ~/.vimrc like this: vim ~/.vimrc, the folding works as expected, I can fold {{{ marker:
:set foldmethod?
> foldmethod=marker
When I open vim without specifying a file: vim, and then trying to edit: :e ~/.vimrc, the foldmethod is different!
:set foldmethod?
> foldmethod=syntax
Which obviously comes from a different part of my vimrc.
Why doesn't it recognizes the file type when I open the file indirectly?
You've failed with VimScript syntax. Must be
autocmd FileType vim
\ setlocal foldlevel=0 foldmethod=marker foldmarker={{{,}}}
What you did instead is
autocmd FileType vim <nothing> | <nothing>
setlocal foo bar
Therefore setlocal applies to the current buffer only (i.e. command-line argument), not to anything else.

How to prevent global defaults from overriding 'filetype=vim' specific settings in .vimrc when automatically sourcing .vimrc?

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

In vim, why my autocmd setfiletype command not working?

In my .vimrc I add this,
autocmd BufNewFile,BufRead *.markdown setfiletype octopress
But it seems not working because after I open a xxx.markdown file and input the command setfiletype octopress everything works fine.
Here is my intact .vimrc
set nocompatible
syntax on
filetype off
colorscheme desert
set nu
set mouse=a
set rtp+=~/.vim/bundle/vundle/
call vundle#rc()
Bundle 'gmarik/vundle'
filetype plugin indent on
Bundle 'vim-octopress'
autocmd FileType markdown setfiletype octopress
Hope someone can help me and tell me how to debug this thing...
I don't see this:
autocmd BufNewFile,BufRead *.markdown setfiletype octopress
I only see this at the end:
autocmd FileType markdown setfiletype octopress
I think fixing that will fix you issue.
Update:
A couple more things to consider. First, the Markdown-syntax plugin sets the filetype to be mkd, not markdown. This doesn't seem to work correctly either:
autocmd FileType mkd setfiletype octopress
But this does:
au FileType mkd set filetype=octopress
...And that makes sense now. setfiletype won't set the file type if it's already been set. Since it was already flagged as being of type mkd, it wasn't being updated to the new file type.
It's because setfiletype ... but only if not done yet in a sequence of (nested) autocommands.
Doc about setfiletype function
filetype plugin on
filetype indent on
au FileType htm,html,php,css setl ts=2 sw=2 sts=2 et

How do I tidy up my vimrc file?

My Vim configuration file is getting bigger (15KB+). And I try not to make my vim launch slower by sourcing more (larger) files at startup. For the same purpose I use only essential plugins and I try to keep the number of plugin as less as possible.
So, somewhere in my .vimrc file, I have these lines:
autocmd FileType python setlocal expandtab shiftwidth=4 tabstop=4 softtabstop=4
autocmd FileType python setlocal textwidth=78
autocmd FileType python match ErrorMsg '\%>80v.\+'
autocmd FileType python inoremap <F5> <esc>:upd\|!python %<cr>
autocmd FileType python nnoremap <F5> :upd\|!python %<cr>
autocmd FileType python nnoremap <leader>8 :w\|call Flake8()<cr>
autocmd FileType python setlocal formatoptions-=t
autocmd BufWritePost *.py call Flake8()
Now I see in first 7 lines, all lines have autocmd FileType python in common. So my thinking is, if we manage to replace all those word with something less then Vim will fire up faster. But I don't know how to do that.
Can we group them? How? Anything else?
Just put
setlocal expandtab shiftwidth=4 tabstop=4 softtabstop=4 textwidth=78 formatoptions-=t
match ErrorMsg '\%>80v.\+'
inoremap <F5> <esc>:upd\|!python %<cr>
nnoremap <F5> :upd\|!python %<cr>
nnoremap <leader>8 :w\|call Flake8()<cr>
in ~/.vim/after/ftplugin/python.vim.
Vim will read this file only when you open a Python file.
I've been meaning to do this for some time, actually. And for the same reasons.
Filetype-specific stuff should be moved to ~/.vim/after/ftplugin/{filetype}.vim, as romainl has already pointed out.
I moved all my custom mappings and commands into ~/.vim/plugin/my{mappings,commands}.vim, and mostly only put real settings (the :set commands) and plugin customizations into .vimrc. Any mappings / commands that aren't simple one-liners and delegate to functions then use the autoload mechanism. This keeps the amount of stuff read at startup small.
TL,DR: Autoload is great; all plugins should use it.
I am using a scheme where a group of options is set in a function that is called by an auto command.
function! s:C_options()
setlocal cinoptions={0,:1s,g1s,t0,(0,=.5s
setlocal noautoindent
setlocal nosmartindent
setlocal cindent
call s:PROG_options()
endfunction
autocmd BufRead,BufNewFile *.c call s:C_options()
It is quite similar to using a filetype but you can use nested call, like having general programming options in s:PROG_options(), so you should be able to reduce further the size of your .vimrc.
The after\filetypesolution might be more efficient regarding initial load time, but I would rather have most of my customization in a single .vimrc than scattered in the .vimdirectory.
At least you can merge the first two lines with the 7th
autocmd FileType python setlocal expandtab shiftwidth=4 tabstop=4 softtabstop=4 textwidth=78 formatoptions-=t
autocmd FileType python match ErrorMsg '\%>80v.\+'
autocmd FileType python inoremap <F5> <esc>:upd\|!python %<cr>
autocmd FileType python nnoremap <F5> :upd\|!python %<cr>
autocmd FileType python nnoremap <leader>8 :w\|call Flake8()<cr>
autocmd BufWritePost *.py call Flake8()
But I can't imagine how you can get rid of the others. On the other hand I don't think that these autocmd commands are taking so long to execute.

Enable syntax highlighting for various filetypes in vim

I can enable syntax highlighting for a file that has an extension that is unknown to vim by doing the following
set syntax=c
Every time I switch tabs however, I have to renter the command. Is there any way to let vim know that a file with an extension .xyz should be coloured with C syntax?
Put this at the end of your .vimrc (I'm assuming you have autocommands enabled).
autocmd BufRead,BufNewFile *.xmlx set filetype=xml
In your home directory, create the .vim/ftdetect/xyz.vim:
au BufRead,BufNewFile *.xyz set filetype=c " to overrule an existing filetype
au BufRead,BufNewFile *.xyz setfiletype c " to set it only if no filetype has been detected for this extension
With autocommand. E.g.
au BufNewFile,BufRead *.xyz setf c
You can set it in the vim config file:
http://beerpla.net/2008/04/02/how-to-add-a-vim-file-extension-to-syntax-highlighting/

Resources