I've been using vi-based editors since the late 80s. While an .exrc – or, as I eventually settled on vim as my vi-like editor, a .vimrc – is a generically decent way to pre-configure one's edit sessions, they have their shortcomings. As my work causes me to need to edit files of ever-broadening file-types, I find, with greater frequency, that I want to tailor my editor's behavior along swaths of file-types. In the land of monolithic .exrcs/.vimrcs, setting up customized-behaviors for multiple file-types results in the monolithic .exrcs/.vimrcs becoming stoopid-long. This makes them harder to read, harder to understand a general pain in the ass to maintain.
In general, I'm a fan of smaller config-files and using some kind of inheritance structure or other conditional-read method. Wasn't until today that I decided to see, "do current iterations of vim let me do that?" Boy was I glad I did: it turns out that the answer is, "yes it does". The key is judicious use of not only one's ~/.vimrc but of files in ~/.vim/.
After some digging around in the documentation and experimentation, I was able to solve my most pressing needs with a collection of files:
- ~/.vimrc: the grand-daddy
- ~/.vim/filetype.vim: To handle mapping file-extensions to vim-recognized file-type handlers
- ~/.vim/ftplugin/bash.vim: A file-type handler for files with the .bash extension
- ~/.vim/ftplugin/sh.vim: A file-type handler for files with the .sh extension
…I'll be adding more
~/.vim/filetype.vim:
This file provides file-extension to file-type mappings. These mappings are used when using file-type files in the ~/.vim/ftplugin/ directory.
The contents of the ~/.vim/filetype.vim file is (currently) fairly simple and straight-foward:
"An easier-to read filetype mapper routine
if exists("did_load_filetypes")
finish
endif
augroup filetypedetect
au! BufRead,BufNewFile *.bash setfiletype bash
au! BufRead,BufNewFile *.sh setfiletype sh
augroup END
As the comment-line indicates, this file makes it easy to legibly extend mapping of file-suffixes to file types. This is done by using a grouping-block to apply autocmd-type directives. Such a grouping-block allow line-by-line mapping-extensions. The above replaces content like:
autocmd BufRead,BufNewFile *.sh,*.bash,*.sls,*.json,*.yml <ACTION>
Thus, if one wants to, say, add further file-type mappings (say for YAML files), one could add a line like:
au! BufRead,BufNewFile *.yml setfiletype yaml
Or even:
au! BufRead,BufNewFile *.yml setfiletype yaml au! BufRead,BufNewFile *.yaml setfiletype yaml
The latter line-pair captures YAML files that might be suffixed .yml or .yaml. As someone who does work for multiple organizations – either concurrently or serially – I've found, much to my consternation, that selected file-suffixes may differ from organization to organization.
~/.vim/ftplugin/*.vim:
The …/ftplugin directory contains the files that contain the actual, per file-type configuration-directives. The previous …/filetype.vim file's `setfiletype` command provides the value of the `*` in the header's wildcarded .vim file-names. Thus a .bash file that was mapped to the bash file-type will cause the ~/.vim/ftplugin/bash.vim file's configuration-options to be read.
Note: while my earlier file-list appears to show two, discrete config-files:
- ~/.vim/ftplugin/bash.vim
- ~/.vim/ftplugin/sh.vim
They are actually just one file that's hard-linked:
$ ls -il *.vim
330115 -rw-r--r-- 2 ferric ferric 453 Feb 5 16:27 bash.vim
330115 -rw-r--r-- 2 ferric ferric 453 Feb 5 16:27 sh.vim
These files (currently) contain:
"Ensure that lines break at 80 characters set wrap set textwidth=80 set wrapmargin=0 "Ensure linewraps happen when textwidth is reached set formatoptions+=t "Enable auto-indent set autoindent "Set 4-char tabstops set tabstop=4 "Convert tabs to spaces set expandtab "Set autoindent to 4-chars set shiftwidth=4 "Eliminate trailing whitespace augroup prewrites autocmd! autocmd BufWritePre,FileWritePre * :%s/\s\+$//e | %s/\r$//e augroup END
One could create equivalent *.vim files for other filetypes. One would do this if, say, you leveraged different maximum line-widths, indent-paddings or the like on a per-language file-basis.
~/.vimrc:
With the other files in place, this allows for a svelter ~/.vimrc file. Mine now looks like:
"Disable syntax-highlighting syntax off "Turn off search-highlighting set nohlsearch "Turn off angry fruit-salad set t_Co=0
I, uh, hate the "angry fruit-salad" appearance that many distro's default vim-configs use.