views:

567

answers:

4

My day job involves coding with Perl. At home I play around with Python and Erlang. For Perl I want to indent my code with two spaces. Where as for Python the standard is 4. Also I have some key bindings to open function declarations which I would like to use with all programming languages. How can this be achieved in GVIM? As in, is there a way to maintain a config file for each programming language or something of that sort?

+19  A: 

You should be able to do with by leveraging filetypes ... e.g., add this to your vimrc (and modify appropriately for different languages):

autocmd FileType python set tabstop=4|set shiftwidth=4|set expandtab
Chris J
Don't override default settings. Use 'setlocal' (or 'setl') instead of 'set'. You don't want settings of the last autocmd break into other buffers.
Maxim Kim
@Maxim -- Good catch... :-)
Chris J
The `set` command accepts multiple options. So, it's easier to write: `set tabstop=4 shiftwidth=4 expandtab`
Denilson Sá
`setlocal` also accepts multiple options.
too much php
+18  A: 

In your $HOME, make .vim/ directory (or vimfiles/ on Windows), in it make ftplugin/ directory, and in it keep files named "perl.vim" or "python.vim" or "html.vim" or ...

These should be loaded automatically when you open/create new file of given filetype as long as you don't forget to add :filetype plugin on in your .vimrc (or _vimrc under windows)

Then, vim options should be defined with :setlocal (and not :set, otherwise their definition will override the default global setting).

Mappings are defined with :n/i/v(nore)map <buffer>, as well as the abbreviations. Commands are defined with the -b option. Menus can't be made local without the help of a plugin.

local, <buffer>, and -b are important to prevent side effects.

depesz
If you're on windows, see ":help dos-locations".
glenn jackman
+1 I didn't know commands could be defined for a single buffer!
too much php
+3  A: 

Here's how I do it. The below is an excerpt from my .vimrc, and I maintain further configs per language, and load those when a new buffer is loaded.

" HTML
autocmd BufNewFile,BufRead *.html,*.htm,*.xhtml source ~/.vimhtml
" XML
autocmd BufNewFile,BufRead *.xml,*.xmi source ~/.vimxml
" Perl
autocmd BufNewFile,BufRead *.pl,*.pm source ~/.vimperl

Note that although I source a file, I can execute any VIM command, or call a function. e.g. for loading a new Java file I do this:

autocmd BufNewFile *.java call GeneratePackage()

where GeneratePackage() is a VIM function.

Brian Agnew
autocmd FileType ... is better because you separate the file type detection (with BufNewFile) from the actions performed for that type of file.
joeforker
+6  A: 

In addition to rangerchris's answer, you might consider using modelines. Modelines tell the editor how to configure itself:

#!/usr/bin/perl
# vi: ts=4 sw=4 ht=4 et textwidth=76 :

use strict;
use warnings;

print "hello world\n";

That modeline tells vi to use 4 character tabs and autoindents, to use spaces instead of tabs, and that it should insert a newline when the cursor gets to 76 characters.

You can control how Vim reads modelines with two variables (most likely set in your .vimrc):

set modeline
set modelines=5

The modeline variable tells Vim to look for modelines if it is set. The modelines variable tells Vim how many lines from the top and bottom to scan looking for the modeline (in this case it will find the modeline if it is in the first or last five lines of the file).

Like any system that takes instructions from untrusted sources, modelines can be a security threat, so the root user should never use modelines and you should keep your copy of Vim up-to-date.

The real benefit to modelines is that they are per file. Most Perl people are four spaces as indent people, but I am an eight character tab person. When working with other people's code, I use a modeline that reflects their usage. The rest of the time I use my own.

Chas. Owens