autocmd FileType vs ftplugin - vim

What is the difference between placing:
autocmd FileType ruby setlocal ts=2
in my ~/.vimrc and placing:
setlocal ts=2
in ~/.vim/ftplugin/ruby.vim?
If there is no difference, where should I place commands that are specific to one filetype?

As far as I know, there isn't really a difference between the two.
I prefer to put commands like that in ftplugin and keep my main .vimrc language-agnostic… But there are no hard-and-fast rules. An advantage to keeping it in your vimrc would be that your vim settings would be easier to move around (ex, you could get all your vim settings on a new machine by simply copying your .vimrc, instead of .vimrc + .vim). Obviously putting them in your .vimrc will also have a minor performance penalty (ie, they will be loaded + executed for every file, not just ruby files)… But I wouldn't really worry about that.

Related

How to make tab spaces in vim varies according to file? [duplicate]

At my work, I am required to follow the house style for indentation, which goes as follows:
2 spaces when coding html and ruby
tabs when coding javascript, with tabwidth=4 recommended
What is the best way to specify different whitespace preferences per filetype?
there are many ways, but here's a simple, easy to understand way. add these lines to your ~/.vimrc:
autocmd FileType html setlocal ts=2 sts=2 sw=2
autocmd FileType ruby setlocal ts=2 sts=2 sw=2
autocmd FileType javascript setlocal ts=4 sts=4 sw=4
Peter's answer is straightforward enough, but unfortunately the options aren't right. You need to use the following options instead:
autocmd Filetype html setlocal ts=2 sw=2 expandtab
autocmd Filetype ruby setlocal ts=2 sw=2 expandtab
autocmd Filetype javascript setlocal ts=4 sw=4 sts=0 noexpandtab
Also note:
You can make vim show tab characters by using :set list.
Once you have the tab/space options set correctly, you can make vim repair the file (replace spaces with tabs or vice versa) using the :retab! command.
+1 to Peter's answer, but Vim provides another solution as well. If you want to do something more complicated than a single setlocal, like setting up a whole bunch of options, commands, and mappings at once, then vim's filetype plugin feature comes to the rescue.
You need to have filetype plugin on or filetype plugin indent on in your .vimrc, and then to create a plugin for e.g. ruby you can create ~/.vim/ftplugin/ruby.vim. Technically you can use any commands you like in here, to be run when a Ruby file is loaded, but the recommended ones include setlocal, map <buffer>, command -buffer, and defining functions. Lots more information is in the User Guide; if you're pretty familiar with scripting vim then jump to :help 41.11, otherwise read :help usr_40 and :help usr_41.
There's also a nice vim script: DetectIndent which tries to detect the indentation of a file that you open.
It's very handy if you work with many files with different coding style.
I use an autocommand in my .vimrc:
:autocmd BufReadPost * :DetectIndent
To insert space characters whenever the tab key is pressed, set the 'expandtab' option:
:set expandtab
Next step is to control the number of space characters that will be inserted when the tab key is pressed, set the 'tabstop' option. For example, to insert 2 space for a tab, use:
:set tabstop=2
ref: http://vim.wikia.com/wiki/Converting_tabs_to_spaces

Vim plugin "auto-pairs" change automatic indent size?

I'm not sure if this is the right place to ask about this, but I figured it couldn't hurt to ask here. I am using a plugin called auto-close so that I don't have to close my own parentheses. It has a very nice feature that does the following:
This is a great feature, but I don't like how far it indents for me.
I have the following line in my .vimrc:
" for filetype "js", tab = insert 4 spaces, backspace will delete all 4
autocmd Filetype javascript setlocal expandtab softtabstop=4
In editing a javascript file, it automatically did an 8-space indentation instead of a 4-space indenation, as I've specified in my .vimrc. Can anybody help me figure out how I can make it automatically indent 4-space tabs instead of 8-space tabs? I can't find it in the documentation either. Thanks!
If you get shiftwidth=8, softtabstop=0, tabstop=8, that means that your autocmd FileType didn't take effect. You'd have to troubleshoot that.
I would recommend putting any settings, mappings, and filetype-specific autocmds into ~/.vim/ftplugin/{filetype}_whatever.vim (or {filetype}/whatever.vim; cp. :help ftplugin-name) instead of defining lots of :autocmd FileType {filetype}; it's cleaner and scales better; requires that you have :filetype plugin on, though. Settings that override stuff in default filetype plugins should go into ~/.vim/after/ftplugin/{filetype}.vim instead. The change of indent settings would fit the latter, after directory location.

Run/Toggle command for certain filetypes only

I found this nice plugin for distraction free writing named Goyo, which is really well done.
I setup autocmds to enable Goyo based on the filetype, so if I work on a markdown or textfile Goyo gets initialized automatically. If I leave the buffer or change the filetype then Goyo gets closed. Below is how I implemented the behaviour:
autocmd FileType * :Goyo!
autocmd FileType markdown :Goyo
autocmd FileType text :Goyo
That seems to work fine. The question is, whether or not this is the way to go or if there is a better approach to solve the problem?
That's just fine and how I would implemented it, too. As you only hook into the FileType event, the toggling is only triggered when you :edit a new file, not when you recall an existing buffer with another filetype. You could do that with BufWinEnter, but it may cause too many inadvertent togglings. I guess the plugin comes with a quick toggle mapping to manually do this, anyway.
Alternative
An alternative to the autocmd FileType commands is filetype plugins (i.e. ~/.vim/ftplugin/markdown.vim etc.), which have the benefit of separating things neatly. But as you need a catch-all autocmd to turn off Goyo, and the list of filetypes is small, I would also prefer keeping things together, just like you did.
Improvements
Note that your set of commands would add a duplicate set of autocmds if you re-:source your ~/.vimrc (or whichever script you've put them in). To avoid that, you could wrap them in
augroup AutomaticGoyo
autocmd!
...
augroup END

Why does vim not obey my expandtab in python files?

After I installed Vundle, my vim no longer obeys the expandtab settings I had. My tabs were set to 2 spaces, but now in python files it no longer does that. The problem is being called by this line:
filetype plugin on
What does this line do (It is required by vundle)? Also, what can I do to make sure my settings are obeyed?
Thanks!
VIMRC: pastebin.com/tGmfCi78
The problem is that your settings are being overridden by a filetype plugin that's part of Vim. The issue is in ftplugin/python.vim:
" As suggested by PEP8.
setlocal expandtab shiftwidth=4 softtabstop=4 tabstop=8
The python plugin attempts to setup your source code to be PEP8 compliant by default, so it's adjusting the tabstop. You'll want some of what these plugins have to offer, but you may need to setup your own autocommands to fixup anything you don't like.
There are two ways to go about doing this. If you have a ~/.vim folder, the easiest way is to add the file ~/.vim/after/ftplugin/python.vim:
" Here, you can set the setting directly, or call a command or function
" to help you. We'll call a command, and then implement that command in
" your top-level vimrc to help keep things in one place.
SetupPython
In your .vimrc, add:
function! SetupPython()
" Here, you can have the final say on what is set. So
" fixup any settings you don't like.
setlocal softtabstop=2
setlocal tabstop=2
setlocal shiftwidth=2
endfunction
command! -bar SetupPython call SetupPython()
The latter bit just allows you to call the function as SetupPython rather than call SetupPython() in the after file.
The other way, is to keep everything in your .vimrc, but you use the VimEnter autocommand to setup a FileType autocommand for python to set your preferences. By waiting until VimEnter is triggered, all the other plugins will have had time to setup their autocommands, so your's will be added to the end of the list. This allows you to run after the python plugin's FileType autocommand and set your own settings. This is a bit of a mess though, and the after/ mechanism above is the preferred way of doing this.
FWIW, many common settings I keep in a SetupSource() function to be called from a number of different FileTypes. Then I'd have SetupPython() call SetupSource(). This helps to keep the specific functions a little cleaner and reduce some duplication. If it helps, take a look at the functions in my vimfiles here: https://github.com/jszakmeister/vimfiles/blob/master/vimrc#L5328
Overridden settings
It could be that the settings are being overridden by language-specific settings. See http://vim.wikia.com/wiki/Keep_your_vimrc_file_clean for more information:
The quick way to get started is to move all the language-specific stuff from your .vimrc file into a file named .vim/ftplugin/language.vim (or $HOME/vimfiles/ftplugin/language.vim on Windows).
Check in those locations for a python specific .vim file.
Filetype on
Vundle appears to require filetype off, and I'm not sure if you should turn it back on. There's a thread on the github issues page for Vundle explaining why filetype on is required. Perhaps this will provide some insight.
I also think having filetype plugin indent on followed by filetype on is redundent. According to the vim help docs, the former turns detection, plugin and indent on, and the latter turn detection on and leaves the plugin and indent unchanged:
Overview: *:filetype-overview*
command detection plugin indent
:filetype on on unchanged unchanged
:filetype off off unchanged unchanged
:filetype plugin on on on unchanged
:filetype plugin off unchanged off unchanged
:filetype indent on on unchanged on
:filetype indent off unchanged unchanged off
:filetype plugin indent on on on on
:filetype plugin indent off unchanged off off

colorcolum only in certain files (e.g. *.cpp, *.h) in VIM

I would like to have a marker at column 80 in VIM, but only in file like *.cpp, *.h. but not in *.txt
For now I have this in my .vimrc
set cc=120
Cheers
Solution:
autocmd FileType cpp,c,cxx,h,hpp,python,sh setlocal cc=120
Vim doesn't directly use the file extension, it has an indirection called filetype, which is then used for syntax highlighting and specific settings.
Put your :set command (as :setlocal, so that it only affects the current buffer [1]) in a new file ~/.vim/after/ftplugin/cpp.vim. (You could also use :autocmd FileType cpp setlocal cc=120 directly in your .vimrc, but the separation is cleaner once you do a lot of that customization.)
[1] Note that 'colorcolumn' is window-local, not buffer-local, so the approach isn't perfect, but usually good enough. It can be perfected with additional BufWinEnter/Leave autocmds.

Resources